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:
- 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.
- 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.