繁体   English   中英

Python 连接四极小极大算法问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM