Недавно я создал минимаксный алгоритм Tic Tac Toe, который успешно работал. Вскоре после этого я изменил код для работы с Connect 4. Однако алгоритм продолжает работать с ошибкой
local variable 'bestMove' referenced before assignment
(ссылаясь на переменную bestMove в функции минимакса)
Методы, которые я изменил с Tic Tac Toe на Connect 4, были функциями showBoard()
, getAvailableMoves()
и getWinner()
.
Я подозреваю, что проблема может быть в getAvailableMoves()
, потому что количество доступных ходовна плате более изменчиво в Connect 4, чем Tic Tac Toe из-за всей идеи стека. Хотя я реализовал это в функции, возможно, мне не следовало бы делать это там, хотя я не уверен.
Вот мой код ниже:
minimax.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
run.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()