我如何弄清楚为什么我的 mini-max tic-tac-toe AI 不起作用?
How can I figure out why my mini-max tic-tac-toe AI does not work?
我正在尝试制作一个 minimax tic-tac-toe 游戏,因为我是 Python 的新手,我正在尝试弄清楚一个简单的 AI-mini-max 游戏是如何工作的。由于某种原因,AI 仍然按顺序出现在董事会名单上。
例如:如果右上角的位置在 "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:
- 如果您的控制布尔设置为 false,则不需要
break
。
- 如果用户输入的内容无效,他们将失去轮到他们的机会。
- 你有
sw = checkwinner()
然后你检查 cw
的值
我可以为你解决这个问题,但我想我已经给了你足够的工作空间,我会告诉你你的概念是合理的,所以如果你继续坚持下去,你应该得到一些令人满意的结果...
这里的主要逻辑缺陷是你从来没有真正计算过给定的选择留下了多少胜利......你的 minimax 函数每次只是 returns 1。
我正在尝试制作一个 minimax tic-tac-toe 游戏,因为我是 Python 的新手,我正在尝试弄清楚一个简单的 AI-mini-max 游戏是如何工作的。由于某种原因,AI 仍然按顺序出现在董事会名单上。
例如:如果右上角的位置在 "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:
- 如果您的控制布尔设置为 false,则不需要
break
。 - 如果用户输入的内容无效,他们将失去轮到他们的机会。
- 你有
sw = checkwinner()
然后你检查cw
的值
我可以为你解决这个问题,但我想我已经给了你足够的工作空间,我会告诉你你的概念是合理的,所以如果你继续坚持下去,你应该得到一些令人满意的结果...
这里的主要逻辑缺陷是你从来没有真正计算过给定的选择留下了多少胜利......你的 minimax 函数每次只是 returns 1。