I have been trying to create a tic tac toe game in C# with minimax functionality. Unfortunately I'm running into problems with getting the minimax function to correctly work.
static double MiniMax(char[] gameState, int depth)
{
int bestMove = 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestMove = i;
bestScore = score;
}
}
}
}
return bestMove;
}
static double MinPlay(char[] gameState, int depth)
{
if (Win(gameState)) return -1;
if (Draw(gameState)) return 0;
double bestScore = double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'O';
double score = 0;
score += MaxPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
static double MaxPlay(char[] gameState, int depth)
{
if (Win(gameState)) return 1;
if (Draw(gameState)) return 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
I made these functions by using the guide here: http://giocc.com/concise-implementation-of-minimax-through-higher-order-functions.html
When running the program everything works fine until the computer has to take its turn. I get the error "Process is terminated due to StackOverflowException". I think this is caused by infinite recursion but after looking through the program for a while I can't tell what is causing it.
I have edited the code so that there is now a depth and the minplay and maxplay loops have a validmove check in them. The the computer now makes a move but for some reason it only ever chooses the first position. If the player chooses the first position as their first move the computer then chooses the position next to it and on the next turn it will over write the player on the first position. Then the computer stops making moves. I have no clue as to why this is happening.
Any help would be much appreciated!
Change your for loops in MinPlay and MaxPlay to only consider empty squares. It also looks like your not using the gameState that is being passed in. I don't know where board is defined.
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState) {
char[] clone = new char[gameState.Length];
gameState.CopyTo(clone, 0);
clone[i] = 'X';
double score = MinPlay(clone);
if (score > bestScore)
{
bestScore = score;
}
}
}
return bestScore;
EDIT:
You changed it to score += which is incorrect. Also, You have the incorrect score comparison in MinPlay.
if (score < bestScore)
{
bestScore = score;
}