Page 1 of 1

C# Blackjack - Freezing?

Posted: Sun Sep 19, 2010 2:46 pm
by TheFinalFanatic
So, I've been working on a basic console application game of blackjack using C#. All is going well, until I come across a strange problem. I haven't done any programming in a long time, and C# is a relatively new language to me, so the problem may be obvious. However, I fail to see it. Basically, the following code (in the main function) appears to freeze after running the first Draw method of case 1. It runs perfectly fine if I enter break mode and step through the code line by line, but when left to run freely appears to freeze.

Code: Select all

            Console.WriteLine("1 - Play Game");
            Console.WriteLine("2 - See Rules");

            int pChoice = Convert.ToInt32(Console.ReadLine());
            switch (pChoice)
            {
                case 1:
                    deck.Draw(ref player);
                    deck.Draw(ref player);
                    Debug.WriteLine("Player hand initialized.");
                    deck.Draw(ref opponent);
                    deck.Draw(ref opponent);
                    int turn = generator.Next(2);
                    switch (turn)
                    {
                        case 1:
                            if (turn == 1)
                                player.Turn(ref deck, ref player);
                            else
                                opponent.Turn(ref deck, ref player);
                            Console.ReadKey();
                            break;
                        case 2:
                            opponent.Turn(ref deck, ref player);
                            break;
                    }
                    break;
                case 2:
                    ShowRules();
                    break;
            }
This is the Draw() method in the Deck class. It generates a random value and a random suit for the card from two arrays, and checks against another array to see if the card has been used before or not, if it has, it redoes the loop, if not, it adds the card to the used array and changes the player's hand and score accordingly:

Code: Select all

        public void Draw(ref Player player)
        {
            Random generator = new Random();
            bool used = false;

            while (true)
            {
                int value = generator.Next(Names.Length);
                string name = Names[value] + Suits[generator.Next(Suits.Length)];

                for (int i = 0; i < Used.Length; i++)
                    {
                        if (name == Used[i])
                        {
                            used = true;
                            break;
                        }

                        if (Used[i + 1] == null)
                        {
                            break;
                        }
                    }

                if (used == false)
                {
                    cards--;
                    player.cards++;
                    Used[iter] = name;
                    iter++;
                    player.hand += name;
                    player.score += value;
                    Console.WriteLine("You drew a {0}!", name);
                    break;
                }
            }
        }
The opponent version of this function is simply overloaded with a small amount of modifications. Any ideas as to why this would be freezing?

Re: C# Blackjack - Freezing?

Posted: Mon Sep 20, 2010 2:42 pm
by trufun202
TheFinalFanatic wrote:

Code: Select all

bool used = false;

            while (true)
            {
                int value = generator.Next(Names.Length);
                string name = Names[value] + Suits[generator.Next(Suits.Length)];
////////////--> used = false;
                for (int i = 0; i < Used.Length; i++)
                    {
                        if (name == Used[i])
                        {
                            used = true;
                            break;
                        }

                        if (Used[i + 1] == null)
                        {
                            break;
                        }
                    }

                if (used == false)
                {
                    cards--;
                    player.cards++;
                    Used[iter] = name;
                    iter++;
                    player.hand += name;
                    player.score += value;
                    Console.WriteLine("You drew a {0}!", name);
                    break;
                }
            }
        }
Any ideas as to why this would be freezing?
That while(true) looks mighty guilty... You need to reset the variable "used = false;" after setting a new name. (as marked above) For instance, say the first card randomly chosen IS used. (Used == true) Now, that while loop iteration is done, so we grab the next card. If that card is NOT used and falls through the for loop; however, "used" is NOT false. Welcome to the infinite loop.

By the way, rather than using a for loop to check for used cards, you could do something like this:

Code: Select all

List<string> UsedCards = new List<string>();

...

int value = generator.Next(Names.Length);
string name = Names[value] + Suits[generator.Next(Suits.Length)];

if (!UsedCards.Contains(name))
{
    UsedCards.Add(name);
   //do stuff
}
Also, I don't recommend reinstantiating a new Random with every Draw() invoke. A global can be used and it should be seeded. For instance:

Code: Select all

Random rand = new Random(DateTime.Now.Millisecond);

Re: C# Blackjack - Freezing?

Posted: Mon Sep 20, 2010 3:44 pm
by TheFinalFanatic
Appears to be working now, many thanks for the reply! :worship:
Using a list also seems like the better option, prevents the need to loop through the whole array on each invoke.

Still kinda confused as to why it would function correctly in it's previous state whilst in break mode though?

Re: C# Blackjack - Freezing?

Posted: Mon Sep 20, 2010 5:46 pm
by dandymcgee
trufun202 wrote:
Also, I don't recommend reinstantiating a new Random with every Draw() invoke. A global can be used and it should be seeded. For instance:

Code: Select all

Random rand = new Random(DateTime.Now.Millisecond);
While it's a good idea to make it global as to avoid repeated instantiation, the DateTime seed is redundant as C# uses the current time as a seed by default. The seed parameter is only there to help with debugging (by providing a constant seed).

Code: Select all

Random rand = new Random();

Re: C# Blackjack - Freezing?

Posted: Tue Sep 21, 2010 8:19 am
by trufun202
dandymcgee wrote:
trufun202 wrote:
Also, I don't recommend reinstantiating a new Random with every Draw() invoke. A global can be used and it should be seeded. For instance:

Code: Select all

Random rand = new Random(DateTime.Now.Millisecond);
While it's a good idea to make it global as to avoid repeated instantiation, the DateTime seed is redundant as C# uses the current time as a seed by default. The seed parameter is only there to help with debugging (by providing a constant seed).

Code: Select all

Random rand = new Random();
touche. I've always just seeded out of habit I guess. ;)