Minmax algorithm in a simple console tic tac toe game;

27 Views Asked by At

I'm making a console tic tac toe game. To explain the structure it's almost like any other console tic tac tie game out there.. We have a base array that store the values and render the board according to it, but after making this i thought that i needed to implement AI to it using minmax algorithm. I saw this youtuber who explains this perfectly and i followed his pseudocode shown in his video to make the algorithm

namespace Tic_Tac_Toe
{
    class Ai
    {
        static int turn = Game.choice;
        static char[] baseArray = Board.indexes; //this is the base array 
        private static char[] GenerateActionArr()
        {
            char[] resultArr = new char[9];
            for (int i = 0; i<9; i++)
            {
                resultArr[i]='.';
            }
            return resultArr;
        }
        //----------------------------------------------
        private static char[][] FindActions(char[] gameState, int turn)
        {
            int index = 0;
            char[][] Actions = new char[index][];
            for (int i = 0; i<gameState.Length; i++)
            {
                if (gameState[i]!='X'&&gameState[i]!='O')
                {
                    char[] arrResult = GenerateActionArr();
                    index++;
                    Array.Resize(ref Actions,index);
                    arrResult[i] = (turn%2==0)?'O':'X';
                    Actions[i] = arrResult;
                }
            }
            return Actions;
        }
        private static char[] Result(char[]gameState, char[] action)
        {
            char[] resultGameState = gameState;
            for (int i = 0; i<gameState.Length; i++)
            {
                if (action[i]=='X'||action[i]=='O')
                {
                    resultGameState[i] = action[i];
                }
            }
            return resultGameState;
        }
        private static int Minimax(char[] gameState)
        {
            int value = 0;
            bool terminal = false;
            if (CheckWin()||CheckDraw())
            {
                terminal = true;
            }
            else{terminal = false;}
            if (terminal)
            {
                if (CheckWin())
                {
                    value = (turn%2==0)?-1:1;
                }
                else if (CheckDraw())
                {
                    value = 0;
                }
                return value;
            }
            else
            {
                if (turn%2==0)
                {
                    foreach (var a in FindActions(gameState,turn))
                    {
                        value = int.MaxValue;
                        value = Math.Min(value,Minimax(Result(gameState,a)));
                    }
                    return value;
                }
                else
                {
                    foreach (var a in FindActions(gameState,turn))
                    {
                        value = int.MaxValue*-1;
                        value = Math.Max(value,Minimax(Result(gameState,a)));
                    }
                    return value;
                }
            }
        }
        private static bool CheckWin()
        {
            if (Board.indexes[1]==Board.indexes[2]&&Board.indexes[2]==Board.indexes[3]&&Board.indexes[1]!='.') 
            {
                return true;
            }
            else if (Board.indexes[4]==Board.indexes[5]&&Board.indexes[5]==Board.indexes[6]&&Board.indexes[4]!='.')
            {
                return true;
            }
            else if (Board.indexes[7]==Board.indexes[8]&&Board.indexes[8]==Board.indexes[9]&&Board.indexes[7]!='.')
            {
                return true;
            }
//------------------------------------------------------------------------------------------> Horizontal Checking            
            else if (Board.indexes[1]==Board.indexes[4]&&Board.indexes[4]==Board.indexes[7]&&Board.indexes[1]!='.')
            {
                return true;
            }
            else if (Board.indexes[2]==Board.indexes[5]&&Board.indexes[5]==Board.indexes[8]&&Board.indexes[2]!='.')
            {
                return true;
            }
            else if (Board.indexes[3]==Board.indexes[6]&&Board.indexes[6]==Board.indexes[9]&&Board.indexes[3]!='.')
            {
                return true;
            }
//------------------------------------------------------------------------------------------> Vertical Checking
            else if (Board.indexes[1]==Board.indexes[5]&&Board.indexes[5]==Board.indexes[9]&&Board.indexes[1]!='.')
            {
                return true;
            }
            else if (Board.indexes[3]==Board.indexes[5]&&Board.indexes[5]==Board.indexes[7]&&Board.indexes[3]!='.')
            {
                return true;
            }
//-------------------------------------------------------------------------------------------> Diagonal Checking
            else
            {
                return false;
            }
        }
        public static bool CheckDraw()
        {
            for (int i = 1; i <= 9; i++)
            {
                if ((Board.indexes[i]!='X'&&Board.indexes[i]!='O'))
                {
                    return false; // There is at least one available slot, not a draw yet
                }
            }
            return true;
        }
    }
}

Apologies if some variable names doesn't make sense to you. So I have two problems:

  1. I'm not sure if this code is correct or it works..The reason i asked this is that im fairly new to c# and programming.. And it seems like i can only test it if problem 2 is sorted out.
  2. If the code is correct and it returns the value correctly, how can I use that value to determine the next move for the computer..

I thought that i could use dictionary or something to store each action value with their corresponding values. But after thinking for sometime i realized that its not possible..

Also: This is my first stack overflow post so apologies if i'm posting this question at a wrong group or something.

0

There are 0 best solutions below