![](/img/trans.png)
[英]Python/Connect-four minimax, first column piece placement Issue (School Project)
[英]Python Connect Four Minimax Algorithm Issue
我最近创建了一个成功运行的井字游戏 Minimax 算法。 不久之后,我修改了代码以适用于 Connect 4。但是,算法不断因错误而崩溃
local variable 'bestMove' referenced before assignment
(指minimax函数中的变量bestMove)
我从井字游戏更改为 Connect 4 的唯一方法是showBoard()
、 getAvailableMoves()
和getWinner()
函数。
我怀疑问题可能出在getAvailableMoves()
中,因为由于整个堆叠的想法,在 Connect 4 中,棋盘上可用移动的数量比井字游戏更易变化。 虽然我确实在 function 中实现了这一点,但也许我不应该在那里这样做,但不确定。
下面是我的代码:
极小极大.py
class ComputerBrain :
def __init__(self, player = "x") :
self._squares = {}
def createBoard(self) :
for i in range(6) :
for j in range(7):
self._squares[i, j] = " "
self.showBoard()
print("\n")
def showBoard(self) :
print ()
print("------------------------------")
print("|", self._squares[0, 0], "|", self._squares[0, 1], "|", self._squares[0, 2], "|", self._squares[0, 3],
"|", self._squares[0, 4], "|", self._squares[0, 5], "|", self._squares[0, 6], "|")
print("------------------------------")
print("|", self._squares[1, 0], "|", self._squares[1, 1], "|", self._squares[1, 2], "|", self._squares[1, 3],
"|", self._squares[1, 4], "|", self._squares[1, 5], "|", self._squares[1, 6], "|")
print("------------------------------")
print("|", self._squares[2, 0], "|", self._squares[2, 1], "|", self._squares[2, 2], "|", self._squares[2, 3],
"|", self._squares[2, 4], "|", self._squares[2, 5], "|", self._squares[2, 6], "|")
print("------------------------------")
print("|", self._squares[3, 0], "|", self._squares[3, 1], "|", self._squares[3, 2], "|", self._squares[3, 3],
"|", self._squares[3, 4], "|", self._squares[3, 5], "|", self._squares[3, 6], "|")
print("------------------------------")
print("|", self._squares[4, 0], "|", self._squares[4, 1], "|", self._squares[4, 2], "|", self._squares[4, 3],
"|", self._squares[4, 4], "|", self._squares[4, 5], "|", self._squares[4, 6], "|")
print("------------------------------")
print("|", self._squares[5, 0], "|", self._squares[5, 1], "|", self._squares[5, 2], "|", self._squares[5, 3],
"|", self._squares[5, 4], "|", self._squares[5, 5], "|", self._squares[5, 6], "|")
print("------------------------------")
def getAvailableMoves(self) :
self._availableMoves = []
for i in range(6) :
for j in range(7):
is_legal = False
if i == 5:
is_legal = True
else:
if self._squares[i + 1, j] != " ":
is_legal = True
else:
is_legal = False
if self._squares[i, j] == " " and is_legal:
self._availableMoves.append((i, j))
return self._availableMoves
def makeMove(self, position, player) :
x, y = position
self._squares[x, y] = player
def complete(self) :
if " " not in self._squares.values() :
return True
if self.getWinner() != None :
return True
return False
def getWinner(self) :
for player in ("x", "o") :
for i in range(6):
for j in range(7):
if i < 3:
if self._squares[i, j] == player and self._squares[i + 1, j] == player and self._squares[i + 2, j] == player and self._squares[i + 3, j] == player:
return player
if j < 4:
if self._squares[i, j] == player and self._squares[i, j + 1] == player and self._squares[i, j + 2] == player and self._squares[i, j + 3] == player:
return player
if self._squares[i, j] == player and self._squares[i + 1, j + 1] == player and self._squares[i + 2, j + 2] == player and self._squares[i + 3, j + 3] == player:
return player
if j > 2:
if self._squares[i, j] == player and self._squares[i + 1, j - 1] == player and self._squares[i + 2, j - 2] == player and self._squares[i + 3, j - 3] == player:
return player
if i >= 3 and j < 4:
if self._squares[i, j] == player and self._squares[i, j + 1] == player and self._squares[i, j + 2] == player and self._squares[i, j + 3] == player:
return player
if " " not in self._squares.values() :
return "tie"
return None
def getEnemyPlayer(self, player) :
if player == "x" :
return "o"
return "x"
def minimax(self, player, depth = 0) :
self.showBoard()
if player == "o":
best = -10
else:
best = 10
if self.complete() :
if self.getWinner() == "x" :
return -10 + depth, None
elif self.getWinner() == "tie" :
return 0, None
elif self.getWinner() == "o" :
return 10 - depth, None
for move in self.getAvailableMoves() :
self.makeMove(move, player)
val, _ = self.minimax(self.getEnemyPlayer(player), depth+1)
self.makeMove(move, " ")
if player == "o" :
if val > best :
best, bestMove = val, move
else :
if val < best :
best, bestMove = val, move
return best, bestMove
运行.py
from minimax import ComputerBrain
def findPlace(available, value):
for i in range(7):
x, y = available[i]
if value == y:
return x
return False
def run():
game = ComputerBrain()
game.createBoard()
print("Computer is X and you are O");
print("Who goes first? Computer (1) or You (2): ");
choice = int(input())
if choice == 1:
_, bestMove1 = game.minimax("x")
game.makeMove(bestMove1, "x")
game.showBoard()
# game.makeMove(randint(0, 9), "x")
# game.showBoard()
while (not game.complete()):
canMove = True;
badMove = False;
while canMove:
if (badMove):
print("No More Spaces Available Here")
print("Please enter your move: ")
new_move = int(input()) - 1
move = findPlace(game.getAvailableMoves(), new_move)
if move == False:
badMove = True;
canMove = True;
else:
game.makeMove((move, new_move), "o")
badMove = False;
canMove = False;
game.showBoard();
if game.complete():
break;
_, bestMove1 = game.minimax("x")
print("best move: ", bestMove1)
game.makeMove(bestMove1, "x")
game.showBoard()
if game.getWinner() != None:
print("\n Result: ", game.getWinner())
else:
print("\n DRAW")
print("\n New Game? (y, n)")
answer = str(input())
if answer == "y":
print("\n \n \n")
run()
else:
return
run()
正如@RicardoAbe 在他的评论中所说,我错误地为初始极小值 function 分配了 -10 和 +10 值,而不是将它们设置为负无穷大和正无穷大。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.