So I'm trying to make a fun and simple little game of Blackjack using C#. I've got a lot of it working how I want it to, except my shuffle routine doesn't seem to be doing anything. What do I need to change in my shuffle routine so that it'll actually shuffle my cards instead of giving me the same cards everytime? Here's what it looks like: Let me know if you need more or the rest of the code in order to find the error(s). THanks in advance!

public void shuffle()
        {
            List<Card> shufCards = new List<Card>(52);
            Random rand = new Random();
            for (int i = 52; i > 1; i--)
            {
                int c = rand.Next(cards.Count);
                shufCards.Add(cards[c]);
                cards.RemoveAt(c);
            }
            shufCards.Add(cards[0]);
            cards = shufCards;
        }

-Matt

Okay, good news...I figured out how to get my shuffle routine to work!! I can't make it past 2 hands of play now though. It shuffles correctly for two hands then when I try to play ("Deal") again it gives me an error popp-up box with the whole:


"Unhandled exception has occurred....blah blah blah.....

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index."

Typical error message...

Now, I know it has to do with my shuffle routine. After I complete one hand and click the "Deal" button again, my "cards" don't show as 52 cards anymore because of the one's that were played last hand. (i.e. if the computer stands after 2 cards and I stand after 3 then 5 cards will be missing and "cards" will only have 47 values in it next hand.) This of course creates big problems, because some cards are missing, and more so because the for loop doesn't work correctly then. What should I do to remedy this situation? I think I just need to reset the "cards" List somehow, but I don't know how to do that without it ruining my shuffle routine. Any ideas/help?

Here's ALL my classes and everything...

DECK:

using System;
using System.Collections.Generic;
using System.Text;

namespace Blackjack_Final_Lab
{
    class Deck
    {
        public List<Card> cards = new List<Card>();

        public Deck()
        {
            string rank = "", suit = "";
            int count = 0;
            for (int i = 0; i < 4; i++)
            {
                switch (i)
                {
                    case 0: suit = "Spades"; break;
                    case 1: suit = "Hearts"; break;
                    case 2: suit = "Diamonds"; break;
                    case 3: suit = "Clubs"; break;
                }
                for (int j = 0; j < 13; j++)
                {
                    switch (j)
                    {
                        case 0: rank = "Ace"; count = 11; break;
                        case 1: rank = "2"; count = 2; break;
                        case 2: rank = "3"; count = 3; break;
                        case 3: rank = "4"; count = 4; break;
                        case 4: rank = "5"; count = 5; break;
                        case 5: rank = "6"; count = 6; break;
                        case 6: rank = "7"; count = 7; break;
                        case 7: rank = "8"; count = 8; break;
                        case 8: rank = "9"; count = 9; break;
                        case 9: rank = "10"; count = 10; break;
                        case 10: rank = "Jack"; count = 10; break;
                        case 11: rank = "Queen"; count = 10; break;
                        case 12: rank = "King"; count = 10; break;
                    }
                    cards.Add(new Card(rank, suit, count));
                }
            }
        }

        public void shuffle()
        {
            List<Card> shufCards = new List<Card>(52);
            Random rand = new Random();
            for (int i = 0; i < cards.Count; i++)
            {
                int c = rand.Next(cards.Count);
                shufCards.Add(cards[c]);
                cards.RemoveAt(c);
            }
            cards = shufCards;
        }

        public Card deal()
        {
            Card ret = cards[0];
            cards.RemoveAt(0);
            return ret;
        }
    }
}

CARD:

using System;
using System.Collections.Generic;
using System.Text;

namespace Blackjack_Final_Lab
{
    class Card
    {
        private string rank;
        private string suit;
        private int count;

        public int Count { get { return count; } set { count = value; } }

        public Card(string r, string s, int c)
        {
            rank = r;
            suit = s;
            count = c;
        }

        public string showShort()
        {
            return (rank == "10") ? ("10" + suit[0].ToString())
                    : rank[0].ToString() + suit[0].ToString();
        }
    }
}

HAND:

using System;
using System.Collections.Generic;
using System.Text;

namespace Blackjack_Final_Lab
{
    class Hand
    {
        private List<Card> cards = new List<Card>();

        public Hand() {}

        public void addCard(Card c)
        {
            cards.Add(c);
        }

        public int getCount()
        {
            int total = 0;
            foreach (Card c in cards)
                total += c.Count;
            if (total > 21)
                foreach (Card c in cards)
                    if (c.Count == 11)
                    {
                        c.Count = 1;
                        total -= 10;
                    }
            return total;
        }

        public string showCards()
        {
            string ret = "";
            foreach (Card c in cards)
                ret += c.showShort() + "  ";
            return ret;
        }

        public void empty()
        {
            cards.Clear();
        }
    }
}

and the FORM:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Blackjack_Final_Lab
{
    public partial class Form1 : Form
    {
        Deck d = new Deck();
        Hand CompHand = new Hand();
        Hand PlyrHand = new Hand();

        public Form1()
        {
            InitializeComponent();
        }

        private void PlayBtn_Click(object sender, EventArgs e)
        {    
            ResultsLbl.Text = " ";
            PlyrHand.empty();
            CompHand.empty();
            d.shuffle();
            HitBtn.Enabled = true;
            StandBtn.Enabled = true;
            PlyrHand.addCard(d.deal());
            CompHand.addCard(d.deal());
            PlyrHand.addCard(d.deal());
            CompHand.addCard(d.deal());
            PlyrCrdsBox.Text = PlyrHand.showCards();
            PlyrScoreBox.Text = PlyrHand.getCount().ToString();
            CompCrdsBox.Text = CompHand.showCards();
            CompScoreBox.Text = CompHand.getCount().ToString();
            PlayBtn.Enabled = false;
        }

        private void HitBtn_Click(object sender, EventArgs e)
        {
            PlyrHand.addCard(d.deal());
            PlyrCrdsBox.Text = PlyrHand.showCards();
            PlyrScoreBox.Text = PlyrHand.getCount().ToString();
        }

        private void StandBtn_Click(object sender, EventArgs e)
        {
            while (CompHand.getCount() < 17)
                CompHand.addCard(d.deal());
            CompCrdsBox.Text = CompHand.showCards();// +"=  " + CompHand.getCount().ToString();
            CompScoreBox.Text = CompHand.getCount().ToString();
            int compTot = CompHand.getCount();
            int playrTot = PlyrHand.getCount();
            if ((playrTot <= 21) && (((playrTot > compTot)) || (compTot > 21)))
                ResultsLbl.Text = "You win!";
            else if ((compTot == playrTot) || ((compTot > 21) && (playrTot > 21)))
                ResultsLbl.Text = "Tie game";
            else
                ResultsLbl.Text = "You lose";
            
            PlayBtn.Enabled = true;
            HitBtn.Enabled = false;
            StandBtn.Enabled = false;
        }
    }
}

Thanks,
Matt

Why not just remember to remove the cards from the table and players hands, and put them back in the deck?

Why not just remember to remove the cards from the table and players hands, and put them back in the deck?

That's what I was thinking, but I guess I don't know how to code that. What do you suggest?

well whatever lists you used for player hands and on the table...
append them back in to the original deck

I understand the process...I'm here because I don't know how to implement it. Now that I've included my code, can you tell me how to do it using the code? I've tried a couple different things with no success. I'm to the point now where I'm thinking I need to create a whole new List and store the cards there then set "cards" List equal to that one, but I think that's a long, unnecessary approach to solving this.

Thanks!

Well you dont include all your code, but in "Hand" as long as you still have access to the list of cards, just remember to "add" them back to the deck.

For the shuffle method, would it be more practical to simply switch the positions of the cards in the same manner as swapping characters in a string? That would probably be the best way to handle the shuffle. You're already generating a random seed, so the cards would be placed randomly before it its time to deal again.

This article has been dead for over six months. Start a new discussion instead.