Минимаксная функция на плате Connect 4 в python - PullRequest
0 голосов
/ 07 марта 2019

Мне нужно создать минимаксную функцию (без использования альфа-бета-обрезки) для платы Connect 4. Функция должна принимать параметры поля и глубины в качестве параметров и возвращать лучший ход и результат в виде кортежа. Моему алгоритму также необходимо точно идентифицировать позиции терминала и назначить им соответствующие значения констант.

Вот код моей эвристики:

P1_WIN_SCORE = 15
P2_WIN_SCORE = -15
DRAW_SCORE = 0

def heuristic(self, board):
    cnt1 = 0 #p1 score counter
    cnt2 = 0 #p2 score counter

    for column in range(board.WIDTH):
        for row in range(board.HEIGHT):
            # horizontal checks
            # 3 in a row checks
            try:
                if board.board[column][row] == board.board[column][row+1] == board.board[column][row+2]:
                    if [column][row] == 0:
                        cnt1 += 3
                    if [column][row] == 1:
                        cnt2 -= 3
            except IndexError:
                pass

            # 2 in a row checks
            try:
                if board.board[column][row] == board.board[column][row+1]:
                    if [column][row] == 0:
                        cnt1 += 2
                    if [column][row] == 1:
                        cnt2 -= 2
            except IndexError:
                pass

            # 1 in a row checks (works for every direction)
            try:
                if board.board[column][row] == 0:
                    cnt1 += 1
                elif board.board[column][row] == 1:
                    cnt2 -= 1
            except IndexError:
                pass

            # vertical checks
            # 3 in a row checks
            try:
                if board.board[column][row] == board.board[column+1][row] == board.board[column+2][row]:
                    if [column][row] == 0:
                        cnt1 += 3
                    if [column][row] == 1:
                        cnt2 -= 3
            except IndexError:
                pass

            # 2 in a row checks
            try:
                if board.board[column][row] == board.board[column+1][row]:
                    if [column][row] == 0:
                        cnt1 += 2
                    if [column][row] == 1:
                        cnt2 -= 2
            except IndexError:
                pass

            # right diagonal up
            # 3 in a row checks
            try:
                if board.board[column][row] == board.board[column+1][row+1] == board.board[column+2][row+2]:
                    if [column][row] == 0:
                        cnt1 += 3
                    if [column][row] == 1:
                        cnt2 -= 3
            except IndexError:
                pass

            # 2 in a row checks
            try:
                if board.board[column][row] == board.board[column+1][row+1]:
                    if [column][row] == 0:
                        cnt1 += 2
                    if [column][row] == 1:
                        cnt2 -= 2
            except IndexError:
                pass

            # right diagonal down
            # 3 in a row
            try:
                if row >= 3 and board.board[column][row] == board.board[column+1][row-1] == board.board[column+2][row-2]:
                    if [column][row] == 0:
                        cnt1 += 3
                    if [column][row] == 1:
                        cnt2 -= 3
            except IndexError:
                pass

            # 2 in a row
            try:
                if row >= 3 and board.board[column][row] == board.board[column+1][row-1]:
                    if [column][row] == 0:
                        cnt1 += 2
                    if [column][row] == 1:
                        cnt2 -= 2
            except IndexError:
                pass

    return cnt1 + cnt2 

Вот моя функция, которая находит клеммные колодки:

def isTerminal(self):
    for column in range(self.WIDTH):
        for row in range(self.HEIGHT):
            try: #horizontal checks
                if self.board[column][row] == self.board[column][row+1] == self.board[column][row+2] == self.board[column][row+3]:
                    return self.board[column][row]
            except IndexError:
                pass

            try: #vertical checks
                if self.board[column][row] == self.board[column+1][row] == self.board[column+2][row] == self.board[column+3][row]:
                    return self.board[column][row]
            except IndexError:
                pass

            try: #right diagonal up
                if self.board[column][row] == self.board[column+1][row+1] == self.board[column+2][row+2] == self.board[column+3][row+3]:
                    return self.board[column][row]
            except IndexError:
                pass

            try: #right diagonal down
                if row >= 3 and self.board[column][row] == self.board[column+1][row-1] == self.board[column+2][row-2] == self.board[column+3][row-3]:
                    return self.board[column][row]
            except IndexError:
                pass
    if self.isFull():
        return -1
    return None

Вот код, который у меня есть до сих пор, я знаю, что мне нужен способ определить лучший столбец для выбора игрока, и я не уверен, как это реализовать ...

def minimax(self, board, depth):
    b = board
    #score = 0
    #move = depth
    while depth > 0:
        if board.isTerminal() == True or depth == 0:
            return heurisitic(b)
        else:
            if BasePlayer.heuristic(self, b) > score:
                score == BasePlayer.heuristic(self, b)
                depth -= 1
                self.minimax(board, depth)
    return (move, score)
...