墨小兰的玩具之嵌套博弈树的井字棋

井字棋玩具进阶!实现人机交互!

核心博弈算法解释:

博弈函数minimax使用了极小化极大算法,通过递归和回溯的方式来模拟整个决策树的搜索过程,并根据每个节点的收益评估来进行选择。

极小化极大算法尝试在决策树的每个层级上最大化自己的收益,并且假设对手会在其层级上选择最有利于对手自己的行动。该算法递归地搜索所有可能的游戏局面,并评估它们的分数来确定最优的下一步行动。在实现过程中,假设计算机为极大化玩家,用户为极小化玩家。

该函数有三个输入参数:

  • board:表示当前游戏局面的状态。
  • depth:表示当前搜索的深度。通常用于在达到一定深度时停止搜索或评估局面。
  • maximizing_player:表示当前轮到的玩家是否是极大化收益的玩家。

函数会根据棋盘状态给出不同的返回值。若用户获胜,返回-1。若计算机获胜,返回1,若平局则返回0。

接下来,如果当前轮到的是极大化(极小化)收益的玩家,则进入一个循环,遍历所有可用的移动(空位)。对于每个移动,都将创建一个新的局面,并在该位置上标记,然后递归调用 minimax 函数来评估新局面,并将返回的评估分数与当前的最大(最小)分数进行比较,更新并返回最大(最小)分数。

通过不断递归调用 minimax 函数,最终找到了最优的下一步行动,该行动的分数已经经过评估和比较,实现人机博弈。

python实现:

#标记
EMPTY = ' '
HUMAN = 'X'
COMPUTER = 'O'


def print_board(board):
    print('---------')
    for i in range(3):
        print('|', end='')
        for j in range(3):
            print(board[i*3 + j], end='|')
        print('\n---------')

#平局之棋盘满
def is_full(board):
    return EMPTY not in board

#定义胜利
def is_winner(board, player):
    winning_rows = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
                    [0, 3, 6], [1, 4, 7], [2, 5, 8],
                    [0, 4, 8], [2, 4, 6]]
    for row in winning_rows:
        if all(board[i] == player for i in row):
            return True
    return False

#合法标记
def get_available_moves(board):
    return [i for i, spot in enumerate(board) if spot == EMPTY]

#博弈
def minimax(board, depth, maximizing_player):
    if is_winner(board, HUMAN):
        return -1
    elif is_winner(board, COMPUTER):
        return 1
    elif is_full(board):
        return 0

    if maximizing_player:
        max_eval = float('-inf')
        for move in get_available_moves(board):
            new_board = board.copy()
            new_board[move] = COMPUTER
            eval = minimax(new_board, depth+1, False)
            max_eval = max(max_eval, eval)
        return max_eval
    else:
        min_eval = float('inf')
        for move in get_available_moves(board):
            new_board = board.copy()
            new_board[move] = HUMAN
            eval = minimax(new_board, depth+1, True)
            min_eval = min(min_eval, eval)
        return min_eval

#博弈结论
def get_best_move(board):
    best_eval = float('-inf')
    best_move = None
    for move in get_available_moves(board):
        new_board = board.copy()
        new_board[move] = COMPUTER
        eval = minimax(new_board, 0, False)
        if eval > best_eval:
            best_eval = eval
            best_move = move
    return best_move

#启动
def main():
    board = [EMPTY] * 9

    while True:
        print_board(board)

        if is_full(board):
            print("It's a tie!")
            break

        move = -1
        available_moves = get_available_moves(board)
        while move not in available_moves:
            move = int(input("Enter your move (0-8): "))

        board[move] = HUMAN

        if is_winner(board, HUMAN):
            print("You win!")
            break

        if is_full(board):
            print("It's a tie!")
            break
        
        print("Computer is thinking...")
        move = get_best_move(board)
        board[move] = COMPUTER

        if is_winner(board, COMPUTER):
            print("Computer wins!")
            break


if __name__ == '__main__':
    main()

本文仅为娱乐之作,如有错误欢迎指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值