我试图为一个tic tac toe游戏创造一个无与伦比的AI,就像http://perfecttictactoe.herokuapp.com/那样。但是,因为我还在学习C,所以它更简单,因为用户总是先行,而且没有GUI,而ASCII艺术则用于图形。我已经查看了MiniMax算法的各种实现,因为它似乎是解决问题的最佳方法,根据该网站以及许多其他网站。我有一点问题,因为算法似乎不起作用。相反,它从方形(1,1)(数组中的[0,0])开始从左向右稳定移动,并在到达行尾时向下移动到下一行。我已经尝试了很多东西,从精心梳理我的代码到重写它,但似乎没有任何工作。我希望这里的精彩社区可以帮助我!
提前致谢!
代码:
#include <stdio.h>
#include "simpio.h"
#include "stdlib.h"
void print(char board[3][3]);
char didwin(char board[3][3]);
void AImove(char board[3][3], int *rows, int *columns);
int MinMax(char board[3][3], int player);
int main(void)
{
int i, i2, player, rows=0,columns=0;
char board[3][3], tempboard[3][3], winner;
string name;
printf("The computer will now play tic-tac-tow with you.\n");
printf("The computer will use \"O\" and you will use \"X\".\n");
printf("You will go first. To begin, please enter your name: ");
name=GetLine();
while(true)
{
for(i=0;i<3;i++)
{
for(i2=0;i2<3;i2++)
{
board[i][i2]='\0';
}
}
print(board);
for(i=0;i<9&&winner==0;i++)
{
printf("\n");
player=i%2+1;
if(player==1)
{
printf("\n%s, what row is your square in?\t", name);
rows=GetInteger()-1;
printf("\n%s, what column is your square in?\t", name);
columns=GetInteger()-1;
}
else if(player==2)
{
printf("\nThe computer will move now.\n");
for(i=0;i<3;i++)
{
for(i2=0;i2<3;i2++)
{
tempboard[i][i2]=board[i][i2];
}
}
AImove(tempboard, &rows, &columns);
}
if(rows<0||rows>3||columns<0||columns>3||board[rows][columns]=='X'||board[rows][columns]=='O')
{
if(player==1)
{
printf("The space is already taken or out of bounds, please try again");
}
i--;
}
else
{
if(player==1) board[rows][columns]='X';
else board[rows][columns]='O';
print(board);
}
winner = didwin(board);
}
if(winner!='\0')
{
if(winner=='X') printf("\n\nYou won!");
else printf("\n\nThe computer won! Try harder next time.");
break;
}
else
{
printf("No winner this round. Try again.");
break;
}
}
}
void print(char board[3][3])
{
int i,i2;
printf("\n");
for(i=0;i<3;i++)
{
for(i2=0;i2<3;i2++)
{
if(board[i][i2]=='\0')
{
printf(" ");
}
else
{
printf(" %c ", board[i][i2]);
}
if(i2<2) printf("|");
}
if(i<2)
{
printf("\n-----------\n");
}
}
}
char didwin(char board[3][3])
{
int i,i2;
char temp;
char winner = '\0';
for(i=0;i<3;i++)
{
temp=board[i][0];
for(i2=0;i2<3;i2++)
{
if(board[i][i2]!=temp)
{
temp='\0';
}
}
if(temp!='\0')
{
winner=temp;
}
}
for(i=0;i<3;i++)
{
temp=board[0][i];
for(i2=0;i2<3;i2++)
{
if(board[i2][i]!=temp)
{
temp='\0';
}
}
if(temp!='\0')
{
winner=temp;
}
}
temp=board[0][0];
for(i=0;i<3;i++)
{
if(board[i][i]!=temp)
{
temp='\0';
}
}
if(temp!='\0')
{
winner=temp;
}
temp=board[0][2];
for(i=0;i<3;i++)
{
if(board[i][2-i]!= temp)
{
temp='\0';
}
}
if(temp!='\0')
{
winner=temp;
}
return winner;
}
void AImove(char tempboard[3][3], int *rows, int *columns)
{
int points=-1, temppoints, i, i2;
for(i=0;i<3;i++)
{
for(i2=0;i2<3;i2++)
{
if(tempboard[i][i2]=='\0')
{
tempboard[i][i2]='O';
temppoints=MinMax(tempboard, 1);
if(temppoints>points)
{
points=temppoints;
*rows=i;
*columns=i2;
}
tempboard[i][i2]='\0';
}
}
}
}
int MinMax(char tempboard[3][3], int player)
{
int winner, points, temppoints, i, i2;
winner=didwin(tempboard);
if(winner=='X') return(0);
else if (winner=='O') return(999);
else
{
for(i=0;i<3;i++)
{
for(i2=0;i2<3;i2++)
{
if(tempboard[i][i2]='\0')
{
if (player==1)
{
tempboard[i][i2]='X';
}
else
{
tempboard[i][i2]='O';
}
if (player==1)
{
temppoints=MinMax(tempboard, 2);
}
else
{
temppoints=MinMax(tempboard, 1);
}
if(temppoints>points)
{
points=temppoints;
}
tempboard[i][i2]='\0';
}
}
}
}
return(points);
}
答案 0 :(得分:1)
代码在MinMax()
中进行分配而不是比较。 points
没有初始化并返回,只有UB。
int points
...
// if(tempboard[i][i2]='\0') { // never true
if (tempboard[i][i2] == '\0') {
points == ...
...
return points;
BTW:建议明确返回main()
答案 1 :(得分:0)
您的代码的关键错误是算法&#34; MinMax&#34;没有正确实施。请注意,根据您的评估,player1是Min玩家,他试图让他的积分尽可能低,而player2是试图让他的积分尽可能高的Max玩家。所以你应该分别讨论这两种情况:
if (player==1)
{
temppoints=MinMax(tempboard, 2);
}
else
{
temppoints=MinMax(tempboard, 1);
}
if(player==1 && temppoints<points) //HERE
{
points=temppoints;
}
else if(player==2 && temppoints>points) //HERE
{ //HERE
points=temppoints; //HERE
} //HERE
除了上述错误之外,您还可能会注意一些无意的错误,例如在MinMax函数中将if(tempboard[i][i2]='\0')
更改为if(tempboard[i][i2]=='\0')
。