我在Python中为基本的井字游戏AI实现了一个minimax算法,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE *passwords = fopen("/Users/mcicco/Desktop/passwords.txt", "r");
FILE *usernames = fopen("/Users/mcicco/Desktop/usernames.txt ", "r");
FILE *merged_file = fopen("/Users/mcicco/Desktop/merged.txt" , "w");
if (usernames == NULL || passwords == NULL || merged_file == NULL)
{
printf("Cannot open file \n");
return (-1);
}
char username[1024];
char password[1024];
while(1)
{
if(!fgets(username, sizeof(username), usernames))
break;
if(!fgets(password, sizeof(password), passwords))
break;
username[strcspn(username, "\n")] = 0;
password[strcspn(password, "\n")] = 0;
fprintf(merged_file, "%s\n%s\n", username, password);
}
fclose(usernames);
fclose(passwords);
fclose(merged_file);
return 0;
}
其他支持功能非常明显。但是,此脚本无法正常运行。例如,它似乎始终选择[0,0],然后继续进行相对恒定的移动,即使有更好的移动可用。此外,考虑到以下状态(以及一般情况下可获胜的行动):
其中def minimax(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
for cell in getEmptySpots(currentBoard):
x = cell[0]
y = cell[1]
currentBoard[x][y] = player
bestScore = -1000000
score = minPlay(currentBoard, -player)
currentBoard[x][y] = 0
if score > bestScore:
bestScore = score
bestMove = cell
print('Best move:')
print(bestMove)
print('\n')
return bestMove
def minPlay(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
for cell in getEmptySpots(currentBoard):
x = cell[0]
y = cell[1]
currentBoard[x][y] = player
bestScore = 1000000
score = maxPlay(currentBoard, -player)
currentBoard[x][y] = 0
if score < bestScore:
bestScore = score
return bestScore
def maxPlay(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
for cell in getEmptySpots(currentBoard):
x = cell[0]
y = cell[1]
currentBoard[x][y] = player
bestScore = -1000000
score = minPlay(currentBoard, -player)
currentBoard[x][y] = 0
if score > bestScore:
bestScore = score
return bestScore
代表人类,1
代表计算机,计算机选择移动-1
作为最佳移动,而不是[2][1]
或[2][2]
这将导致胜利。
我已经经历了一些与不同语言的minimax实现有关的问题,据我所知,我的代码在逻辑上是有道理的。因此,我不确定问题是什么。 我的完整代码可以找到here。
答案 0 :(得分:1)
你的循环中空单元格中存在逻辑错误!
您必须在循环之前初始化bestScore
,并在循环之后初始化return bestScore
。否则minimax
,minPlay
,maxPlay
将始终选择第一个空单元格。
以下是minPlay
的修正案(minimax
和maxPlay
可以同样修复):
def minPlay(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
# initialize the "best score" before the loop
bestScore = 1000000
for cell in getEmptySpots(currentBoard):
x = cell[0]
y = cell[1]
currentBoard[x][y] = player
score = maxPlay(currentBoard, -player)
currentBoard[x][y] = 0
# update the "best score"
if score < bestScore:
bestScore = score
# return the "best score" after inspecting *all* empty cells
return bestScore
答案 1 :(得分:1)
有两个问题。首先是@Flopp答案中的逻辑问题。第二个是当没有剩下的动作时isGameOver
不会返回true。得分0
作为初始最高或最低分数返回。
这里:
def minPlay(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
相关(固定)线在这里(它不漂亮,它只是证明它会起作用):
def isGameOver(currentBoard):
return checkGameOver(currentBoard, HUMAN) or checkGameOver(currentBoard, COMPUTER) or getEmptySpots(currentBoard) == []
对于minimax
,确保最初的bestMove也是一个好主意。
def minimax(currentBoard, player):
if isGameOver(currentBoard):
score = evaluate(currentBoard)
return score
allMoves = getEmptySpots(currentBoard)
bestMove = allMoves[0]
for cell in allMoves: