4A4B Game: A Problem Solving Algorithm

Posted on Posted in Artificial Intelligence, C Sharp, C#, Math, programming

One of my earlier projects was a number guessing algorithm, which I’ve christened the 4A4B Game and I will showcase here. The rules for the game are:

  1. There is a randomly generated four digit number with no repeating digits or zeroes, unknown to the player.
  2. Each turn, the player gets to guess one four digit number, following the same rules as above.
  3. For each guess, each digit of the guess is given a score, A, B or none. If the guessed digit has the same position and value as its corresponding digit in the randomly generated number, it is assigned an A. If the guessed digit doesn’t match the corresponding digit, but the value is equivalent to one of the three other digits, it is assigned a B. Else, it isn’t given a score.
    • For example, if the generated number is 1234, and the player guesses 1369, the digits will be assigned scores AB__.
  4. The game ends when all four digits are assigned A, i.e. the player has guessed all four digits correctly. The fewer turns it takes on average, the better the player.

Now replace all instances of the word “player” with “algorithm”. How would this be accomplished in code?

  1. Have the computer generate a series of four random non-zero integers (the number unknown to the “player”.
    public void generate()
    {
        taken = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        int[] generator = new int[4];
        Random randdigit = new Random(Guid.NewGuid().GetHashCode());
    
        for (int x = 0; x <= 3; x++)
        {
            do
            {
                generator[x] = randdigit.Next(1, 10);
            } while (taken[generator[x] - 1] == 1);
            taken[generator[x] - 1] = 1;
         }
         textBox4.Text = generator[0].ToString() + generator[1].ToString() + generator[2].ToString() + generator[3].ToString();
    }
    
  2. Generate another series of four random non-zero integers (first “guess”) – similar to the previous code.
  3. Assign the A/B/None score to the guess.
            public void evaluate()
            {
                for (int x = 0; x <= 3; x++)
                {
                    if (guess[x + 1] == integerarr[x])
                    {
                        guessaccuracy[x] = 2;
                        possible[guess[x + 1]] = 1;
                    }
                    else if (integerarr.Contains(guess[x + 1]))
                    {
                        guessaccuracy[x] = 1;
                    }
                    else if (integerarr.Contains(guess[x + 1]) == false)
                    {
                        guessaccuracy[x] = 0;
                        possible[guess[x + 1]] = 1;
                    }
                }
            }
    
  4. Reroll the digits with the None score.
                    if (guessaccuracy.Contains(0))
                    {
                        if (guessaccuracy[0] == 0)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[1] = digit;
                            } while (previousvalue[0] == digit);
                            taken[guess[1] - 1] = 1;
                        }
                        if (guessaccuracy[1] == 0)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[2] = digit;
                            } while (previousvalue[1] == digit);
                            taken[guess[2] - 1] = 1;
                        }
                        if (guessaccuracy[2] == 0)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[3] = digit;
                            } while (previousvalue[2] == digit);
                            taken[guess[3] - 1] = 1;
                        }
                        if (guessaccuracy[3] == 0)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[4] = digit;
                            } while (previousvalue[3] == digit);
                            taken[guess[4] - 1] = 1;
                        }
                    }
    
  5. Reassign the position of the digits with the B score. These cannot be in the pool of rerolled integers of step 4.
                    if (guessaccuracy.Contains(1))
                    {
                        if (guessaccuracy[0] == 1)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[1] = digit;
                            } while (previousvalue[0] == digit);
                            taken[guess[1] - 1] = 1;
                            flagarray[0] = 1;
                        }
                        if (guessaccuracy[1] == 1)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[2] = digit;
                            } while (previousvalue[1] == digit);
                            taken[guess[2] - 1] = 1;
                            flagarray[1] = 1;
                        }
                        if (guessaccuracy[2] == 1)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[3] = digit;
                            } while (previousvalue[2] == digit);
                            taken[guess[3] - 1] = 1;
                            flagarray[2] = 1;
                        }
                        if (guessaccuracy[3] == 1)
                        {
                            do
                            {
                                bdigit(possible);
                                guess[4] = digit;
                            } while (previousvalue[3] == digit);
                            taken[guess[4] - 1] = 1;
                            flagarray[3] = 1;
                        }
                    }
                if (flagarray.Sum() >= 1)
                {
                    shift(flagarray);
                }
            public void shift(int[] flagarray)
            {
                int firstb = 0;
                int secondb = 0;
                int thirdb = 0;
                int fourthb = 0;
                if (flagarray.Sum() >= 2)
                {
                    firstb = guess[Array.IndexOf(flagarray, 1) + 1];
                    flagarray[Array.IndexOf(flagarray, 1)] = 0;
                    secondb = guess[Array.IndexOf(flagarray, 1) + 1];
                    flagarray[Array.IndexOf(flagarray, 1)] = 0;
                    if (flagarray.Sum() >= 3)
                    {
                        thirdb = guess[Array.IndexOf(flagarray, 1) + 1];
                        flagarray[Array.IndexOf(flagarray, 1)] = 0;
                        if (flagarray.Sum() == 4)
                        {
                            fourthb = guess[Array.IndexOf(flagarray, 1) + 1];
                        }
                    }
                    if (flagarray.Sum() == 2)
                    {
                        int temp = guess[Array.IndexOf(guess, firstb)];
                        guess[Array.IndexOf(guess, firstb)] = guess[Array.IndexOf(guess, secondb)];
                        guess[Array.IndexOf(guess, secondb)] = temp;
                    }
                    else if (flagarray.Sum() == 3)
                    {
                        int temp = guess[Array.IndexOf(guess, firstb)];
                        guess[Array.IndexOf(guess, firstb)] = guess[Array.IndexOf(guess, secondb)];
                        guess[Array.IndexOf(guess, secondb)] = guess[Array.IndexOf(guess, thirdb)];
                        guess[Array.IndexOf(guess, thirdb)] = temp;
                    }
                    else if (flagarray.Sum() == 4)
                    {
                        int temp = guess[Array.IndexOf(guess, firstb)];
                        guess[Array.IndexOf(guess, firstb)] = guess[Array.IndexOf(guess, secondb)];
                        guess[Array.IndexOf(guess, secondb)] = guess[Array.IndexOf(guess, thirdb)];
                        guess[Array.IndexOf(guess, thirdb)] = guess[Array.IndexOf(guess, fourthb)];
                        guess[Array.IndexOf(guess, fourthb)] = temp;
                    }
                }
    
            }
    
  6. Keep the Position of the digits with an A score. Like B, these can’t be in the pool of rerolled integers.
    if (guessaccuracy.Contains(2))
                    {
                        if (guessaccuracy[0] == 2)
                        {
                            taken[guess[1] - 1] = 1;
                        }
                        if (guessaccuracy[1] == 1)
                        {
                            taken[guess[2] - 1] = 1;
                        }
                        if (guessaccuracy[2] == 2)
                        {
                            taken[guess[3] - 1] = 1;
                        }
                        if (guessaccuracy[3] == 2)
                        {
                            taken[guess[4] - 1] = 1;
                        }
                    }
    
  7. Loop through step 3 through 6 until guess reaches 4A. Count number of guesses it took.
                A = 0;
                B = 0;
                for (int x = 0; x <= 3; x++)
                {
                    if (guessaccuracy[x] == 2)
                    {
                        A++;
                    }
                    else if (guessaccuracy[x] == 1)
                    {
                        B++;
                    }
                }
                countguess++;
                label34.Text = "Guess: " + guess[1].ToString() + guess[2].ToString() + guess[3].ToString() + guess[4].ToString();
                label35.Text = A.ToString() + "A " + B.ToString() + "B";
                label36.Text = "Total Guesses: " + countguess.ToString();
                previousvalue = new int[4] { guess[1], guess[2], guess[3], guess[4] };
                if (guessaccuracy.Average() == 2)
                {
                    label37.Text = "4A, Correct Guess.";
                    button5.Enabled = false;
                    if (countguess <= 3)
                    {
                        counter[0]++;
                        label38.Text = "3-: " + counter[0].ToString();
                    }
                    else if (countguess == 4)
                    {
                        counter[1]++;
                        label39.Text = "4: " + counter[1].ToString();
                    }
                    else if (countguess == 5)
                    {
                        counter[2]++;
                        label40.Text = "5: " + counter[2].ToString();
                    }
                    else if (countguess == 6)
                    {
                        counter[3]++;
                        label41.Text = "6: " + counter[3].ToString();
                    }
                    else
                    {
                        counter[4]++;
                        label43.Text = "7+: " + counter[4].ToString();
                    }
    

Results after 2000 Runs:

4a4b2k

Guess in progress:

4a4b1b

The Next Guess will reach 4A

4a4b2a2b

Please follow and like us:

Leave a Reply

Your email address will not be published.