试图了解电脑游戏玩家来熟悉人工智能。2我理解极大极小如何在理论上工作,但不能让我的头周围如何这个代码我发现在线工程。3有人能解释极大极小的水果/计算机移动功能(行38-78)给我。4信用:https://gist.github.com/MatthewSteel/3158579
谢谢
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int minimax(int board[9], int player) {
//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;
move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
2条答案
按热度按时间ulmd4ohb1#
下面是
minimax
的精髓:仔细检查每一步可能的棋,对于每一步可能的棋,把棋盘转过来,假装是另一个玩家(这就是
player*-1
部分),尝试每一步可能的棋。thisScore
被设置为递归调用minimax
的负返回值,因为对另一个玩家有利等于对我们自己不利。computerMove
只是遍历所有可能的移动,为每个可能的移动调用minimax
,并使用具有最佳结果的移动。fzsnzjdm2#
这段代码是一个实现井字游戏的C程序。程序使用极大极小算法来模拟计算机的移动,并确定最佳的移动。
程序从定义主函数开始,主函数通过初始化游戏板并将其打印到控制台来设置游戏。然后,游戏继续在人类玩家和计算机玩家之间交替循环,直到游戏结束。在循环的每次迭代期间,程序检查游戏是否结束,如果结束,则打印出赢家。如果游戏以平局结束,程序打印出指示抽奖的消息。
计算机的移动是使用极小极大算法确定的,该算法递归地模拟所有可能的未来移动并确定最佳移动。极小极大函数将游戏板和一个布尔标记作为输入,该布尔标记指示当前是最大化还是最小化其分数。它返回当前板配置的分数,该分数用于确定最佳移动。
该程序还包括打印游戏板、获得人类玩家的移动以及检查游戏是否结束的帮助函数。检查函数检查游戏板是否连续三次,水平、垂直或对角。如果检测到连续三次,则该函数返回适当的分数(-1表示X,1表示O)。如果棋盘完全填满,则函数返回0,表示平局。
总的来说,该程序提供了一个简单的实现游戏的井字游戏,可以发挥对计算机对手。