极小极大算法不适用于Python中的井字游戏

j5fpnvbx  于 2022-12-20  发布在  Python
关注(0)|答案(2)|浏览(171)

我最近尝试用minimax(在YouTube的帮助下)创建一个简单的井字游戏人工智能,但我无法让它工作,算法只是吐出它检查的第一个值,而不是检查所有值并给出最好的一个。
我试着从YouTube视频复制代码,但它仍然不工作,有人能告诉我出了什么问题吗?

import math
import random

print()

board = {1: '   ', 2: '   ', 3: '   ',
         4: '   ', 5: '   ', 6: '   ',
         7: '   ', 8: '   ', 9: '   '}
computerLetter = 'X'
playerLetter = 'O'

def print_board(board=board):
    for i in range(1, 8, 3):
        print('|' + board[i] + '|' + board[i + 1] + '|' + board[i + 2] + '|')

        if i < 7:
            print('-' * 13)

    print()

def space_is_free(position):
    if board[position] == '   ':
        return True
    else:
        return False

def free_spaces(board=board):

    freeSpaces = 0
    for key in board.keys():
        if key == '   ':
            freeSpaces += 1

    return freeSpaces

def make_move(letter, position):

    if space_is_free(position):

        board[position] = ' ' + letter + ' '
        print_board(board)

        if check_for_win(board):

            if letter == 'O':
                print("You win!!")
                exit()
            else:
                print("The computer wins. Better luck next time!")
                exit()

        elif check_for_tie(board):
            print("It's a tie! Well played.")
            exit()

    else:

        print("Invalid choice.")
        position = int(input("Enter new position: "))
        make_move(letter, position)

def check_for_win(board=board):

    if board[1] == board[2] == board[3] != '   ' or board[4] == board[5] == board[6] != '   ' or board[7] == board[8] \
            == board[9] != '   ' or board[1] == board[4] == board[7] != '   ' or board[2] == board[5] == board[6] != \
            '   ' or board[3] == board[6] == board[9] != '   ' or board[1] == board[5] == board[9] != '   ' or board[3]\
            == board[5] == board[7] != '   ':
        return True
    else:
        return False

def check_for_win_letter(letter):

    if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
            or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] or board[7] == ' ' +\
            letter + ' ' or board[2] == board[5] or board[6] == ' ' + letter + ' ' or board[3] == board[6] or board[9]\
            == ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
            board[7] == ' ' + letter + ' ':
        return True
    else:
        return False

def check_for_tie(board=board):

    for key in board.keys():
        if board[key] == '   ':
            return False
    else:
        return True

def player_move(playerLetter='O'):

    if free_spaces(board) >= 9:
        print_board(board)

    position = int(input("Enter position (1-9): "))
    make_move(playerLetter, position)

def computer_move(computerLetter='X'):

    if free_spaces(board) == 9:
        make_move(computerLetter, 5)

    else:

        bestScore = -math.inf
        bestPosition = 0

        for key in board.keys():
            if space_is_free(key):
                board[key] = ' ' + computerLetter + ' '
                score = minimax(board, 0, False)
                board[key] = '   '

                if score > bestScore:
                    bestScore = score
                    bestPosition = key

        make_move(computerLetter, bestPosition)
        print(f"Computer moves to {bestPosition}.")

def minimax(board, depth, isMaximising):

    if check_for_win_letter('X'):
        return 1 * (free_spaces(board) + 1)

    elif check_for_win_letter('O'):
        return -1 * (free_spaces(board) + 1)

    elif check_for_tie(board):
        return 0

    if isMaximising:

        bestScore = -math.inf

        for key in board.keys():

            if space_is_free(key):
                board[key] = ' ' + computerLetter + ' '
                score = minimax(board, depth + 1, False)
                board[key] = '   '
                bestScore = max(score, bestScore)

        return bestScore

    else:

        bestScore = math.inf

        for key in board.keys():

            if space_is_free(key):
                board[key] = ' ' + playerLetter + ' '
                score = minimax(board, depth + 1, True)
                board[key] = '   '
                bestScore = min(score, bestScore)

        return bestScore

while not check_for_win(board):
    computer_move('X')
    player_move('O')

# gameState = input("Would you like to play again? (y/n)")
#
# if gameState.lower() == 'y':
#     main()
# elif gameState.lower() == 'n':
#     exit()
# else:
#     print("Invalid choice.")

我试着改变电脑和玩家的字母,以及电脑是最大化还是最小化,但它没有工作。

zfycwa2u

zfycwa2u1#

我想我已经发现了你的代码有什么问题,在minmax函数中,第一个if,elif,else语句总是以return语句结尾。

def minimax(board, depth, isMaximising):

if check_for_win_letter('X'):
    return 1 * (free_spaces(board) + 1)

elif check_for_win_letter('O'):
    return -1 * (free_spaces(board) + 1)

elif check_for_tie(board):
    return 0

else语句是它失败的原因。
当return语句被调用时,它结束函数 * 返回 * 所声明的变量,在这种情况下,它将始终是一个介于-9和9之间的数字,并且不运行下一个代码块,从而破坏计算机寻找最佳/最差播放位置的过程。else语句意味着,即使前面的语句为假,它也将始终返回零。结束函数并停止下一代码块的处理。
希望这能有所帮助!:)

vngu2lb8

vngu2lb82#

好的,我找到问题了,实际上是函数中的一堆逻辑错误,这些函数正在检查赢家和赢家字母,每个单词都有一些错别字。

**

  • 错误1:
    **
def check_for_win(board=board):

    if board[1] == board[2] == board[3] != '   ' or board[4] == board[5] == board[6] != '   ' or board[7] == board[8] \
            == board[9] != '   ' or board[1] == board[4] == board[7] != '   ' or ****board[2] == board[5] == board[6]**** != \ # board[6] should be board[8]
            '   ' or board[3] == board[6] == board[9] != '   ' or board[1] == board[5] == board[9] != '   ' or board[3]\
            == board[5] == board[7] != '   ':
        return True

**

  • 错误二:
    **
def check_for_win_letter(letter):

if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
        or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] ****or board[7]**** == ' ' +\
        letter + ' ' or board[2] == board[5] ****or board[6]**** == ' ' + letter + ' ' or board[3] == board[6] ****or board[9]****\
        == ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
        board[7] == ' ' + letter + ' ':
    return True

星号(*)内的"1"语句表示错误,"或"语句应为"==",电路板[6]应为电路板[8]。

相关问题