python - 我怎样才能弄清楚为什么我的 mini-max tic-tac-toe AI 不起作用?
问题描述
我正在尝试制作一个 minimax tic-tac-toe 游戏,因为我是 Python 的新手,并且我正在尝试弄清楚一个简单的 AI-mini-max 游戏是如何工作的。出于某种原因,人工智能仍然按照该位置出现在董事会列表中的顺序进行。
例如:如果右上角的位置是“b”列表中的第一个,则它首先选择它。看起来它正在计算分数,但我认为它出于某种原因没有使用它们。我希望它不要按照板上的空格顺序排列。我想不出一种方法来替换放置“O”的代码。
import random
import math
three = [0, 0, 0]
game = True
turnai = False
result = ""
b = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
x = "X"
o = "O"
#Spots on the board Ex: ur = upper right, mm = middle middle, lm = lower middle
ur = b[2]
um = b[1]
ul = b[0]
ml = b[3]
mm = b[4]
mr = b[5]
ll = b[6]
lm = b[7]
lr = b[8]
cw = " "
AI = ""
player = ""
#Board setup
def board(ul, um, ur, ml, mm, mr, ll, lm, lr):
print("|" + " " + ul + " " + "|" + " " + um + " " + "|" + " " + ur + " " + "|")
print("|" + " " + ml + " " + "|" + " " + mm + " " + "|" + " " + mr + " " + "|")
print("|" + " " + ll + " " + "|" + " " + lm + " " + "|" + " " + lr + " " + "|")
board(ul, um, ur, ml, mm, mr, ll, lm, lr)
print("This is the game of tic-tac-toe")
print("You will be playing against an AI")
print("Type where you want to place your letter Ex: ur = upper right, mm = middle middle, and ll = lower right")
first = "P"
player = "X"
AI = "O"
#Checks if someone has won
def checkwinner():
ur = b[2]
um = b[1]
ul = b[0]
ml = b[3]
mm = b[4]
mr = b[5]
ll = b[6]
lm = b[7]
lr = b[8]
row1 = [ul, ml, ll]
row2 = [um, mm, lm]
row3 = [ur, mr, lr]
column1 = [ul, um, ur]
column2 = [ml, mm, mr]
column3 = [ll, lm, lr]
diagonal1 = [ul, mm, lr]
diagonal2 = [ur, mm, ll]
if row1 == ["X", "X", "X"] or row2 == ["X", "X", "X"] or row3 == ["X", "X", "X"] or column1 == ["X", "X",
"X"] or column2 == [
"X", "X", "X"] or column3 == ["X", "X", "X"] or diagonal1 == ["X", "X", "X"] or diagonal2 == ["X", "X",
"X"]:
if player == x:
print("You win! (X)")
return "X"
if player != x:
print("You lose!")
return "O"
if row1 == ["O", "O", "O"] or row2 == ["O", "O", "O"] or row3 == ["O", "O", "O"] or column1 == ["O", "O",
"O"] or column2 == [
"O", "O", "O"] or column3 == ["O", "O", "O"] or diagonal1 == ["O", "O", "O"] or diagonal2 == ["O", "O",
"O"]:
if player == o:
print("You win! (O)")
return "X"
if player != o:
print("You lose")
return "O"
if b[0] != " " and b[1] != " " and b[2] != " " and b[3] != " " and b[4] != " " and b[5] != " " and b[
6] != " " and b[7] != " " and b[8] != " ":
print("TIE!")
winner = True
return "0"
return "null"
#Minimax Algorithm
def minimax(b, depth, isMaximizing):
result = checkwinner()
if result != "null":
score = scores[result] + score
return score
if (isMaximizing):
bestScore = -math.inf
j = 0
for str in b:
if str == " ":
b[j] = AI
score = minimax(b, depth + 1, False) + score
b[j] = " "
bestScore = max(score, bestScore)
j += 1
return bestScore
else:
bestScore = math.inf
k = 0
for str in b:
if str == " ":
b[k] = player
score = minimax(b, depth + 1, True) + score
b[k] = " "
bestScore = min(score, bestScore)
k += 1
return bestScore
#Game Start loop
if (first == "P"):
while (game == True):
i = 0
scores = {
'O': 1,
'X': -1,
'0': 0
}
#AI turn
bestScore = -math.inf
turnai = False
i = 0
for str in b:
if str == " ":
b[i] = AI
score = minimax(b, 0, True)
b[i] = " "
print(score)
if score > bestScore and turnai == False:
bestScore = score
b[i] = AI
turnai = True
i += 1
turnai = False
print("")
# b = [ul, um, ur, ml, mm, mr, ll, lm, lr]
ur = b[2]
um = b[1]
ul = b[0]
ml = b[3]
mm = b[4]
mr = b[5]
ll = b[6]
lm = b[7]
lr = b[8]
#Prints Board
board(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8])
cw = checkwinner()
#Checks if game ended
if cw == "X" or cw == "O" or cw == "0":
game = False
break
#Player turn
print("Where do you want to place your letter?")
turn = input(": ")
if turn == "ur" and ur == " ":
b[2] = player
uru = True
if turn == "um" and um == " ":
b[1] = player
umu = True
if turn == "ul" and ul == " ":
b[0] = player
ulu = True
if turn == "mr" and mr == " ":
b[5] = player
mru = True
if turn == "mm" and mm == " ":
b[4] = player
mmu = True
if turn == "ml" and ml == " ":
b[3] = player
mlu = True
if turn == "lr" and lr == " ":
b[8] = player
lru = True
if turn == "lm" and lm == " ":
b[7] = player
lmu = True
if turn == "ll" and ll == " ":
b[6] = player
llu = True
#Prints Board
board(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8])
sw = checkwinner()
#Checks if game needs to be ended
if cw == "X" or cw == "O" or cw == "0":
game = False
break
解决方案
- 作为一般样式规则,请尽量保持行长 < 100 个字符。
- 您不应该将
str
其用作变量名,因为它是内置的。 - 您可以
enumerate
在迭代时使用从列表中获取索引和值。 scores
应该在其中定义,minimax
因为这是唯一使用它的地方。由于这段代码,AI 占据了第一位:
bestScore = -math.inf turnai = False i = 0 for str in b: if str == " ": b[i] = AI score = minimax(b, 0, True) b[i] = " " print(score) if score > bestScore and turnai == False: # Allways true first loop bestScore = score b[i] = AI turnai = True # ^ Never true in later loops
具有讽刺意味的是,只有在
turnai == false
- 您实际上不需要
turnai
在游戏循环中使用布尔值,因为您明确编码了 AI 和用户回合。 - 你不需要检查是否
boolean == True
只是说while game:
break
如果您的控制布尔设置为 false ,则不需要。- 如果用户输入无效的输入,他们将失去轮到。
- 然后你
sw = checkwinner()
检查了cw
我可以为你解决这个问题,但我想我已经给了你足够的工作在这里,我会告诉你你的概念是合理的(ish)所以如果你再坚持一点,你应该会得到一些令人满意的结果。 .
这里的主要逻辑缺陷是您从未真正计算给定选择留下多少胜利......您的 minimax 函数每次都返回 1。
推荐阅读
- html - 在 Mysql 数据库中存储换行符
- html - 如何使用 HTML 制作水平图标栏
- javascript - 单击按钮时从地图框中删除所有标记
- css - 如何在具有相同 css 的多个元素中进行选择?
- django - 发生错误时如何防止 Django 向 ADMIN 发送某些信息
- python-3.x - 如何修复 TypeError:G 必须是 'd' 矩阵?
- node.js - 如何选择与 multer-s3 一起使用的 s3 配置文件
- android - 可靠的 BLE 广告
- language-agnostic - 规范模式应该如何处理空候选?
- python - 如何使用脚本停止 python 文件