人工智能学习,Python实现井字棋游戏(极大极小/α-β剪枝算法)

 关于核心判断部分 maxmin()解释:

该函数根据当前游戏状态的得分,计算出下一步应该走的位置。该函数的参数如下:

  • board:表示当前的游戏状态,是一个 3x3 的二维数组。
  • depth:表示搜索的深度,即预测未来多少步。
  • alpha:表示当前最好的评分(对于 maximizing 玩家来说),初始化为负无穷。
  • beta:表示当前最好的评分(对于 minimizing 玩家来说),初始化为正无穷。
  • maximizing:表示当前是轮到哪个玩家走棋,True 表示 maximizing 玩家,False 表示 minimizing 玩家。

该函数的返回值包括两个元素:

  • best_score:表示当前的最优得分。
  • best_move:表示当前应该走的位置。

在函数内部,首先使用 check_win 和 check_tie 函数判断当前游戏状态,如果存在胜负或平局,则返回对应的得分。如果还没有到达搜索的深度,则进入下一步的搜索。

如果当前是 maximizing 玩家,则使用 for 循环遍历棋盘中所有空位,对于每个空位,都假设 maximizing 玩家会走这个位置,并计算下一步的得分。如果得分比当前最优得分更好,则更新最优得分和最优位置。同时,更新 alpha 的值为当前最优得分和 alpha 中的最大值。如果 beta 的值小于或等于 alpha,则可以停止搜索并返回结果。

如果当前是 minimizing 玩家,则与 maximizing 玩家的情况类似,只是更新的是 beta 的值。

最终返回当前的最优得分和最优位置。


 

import math


def print_board(board):
    for row in board:
        print(" | ".join(row))
    print()


# 判断是否有获胜者
def check_win(board, player):
    for i in range(3):
        if all(board[i][j] == player for j in range(3)):
            return True
        if all(board[j][i] == player for j in range(3)):
            return True
    if all(board[i][i] == player for i in range(3)):
        return True
    if all(board[i][2 - i] == player for i in range(3)):
        return True
    return False


# 判断是否平局
def check_tie(board):
    for row in board:
        for cell in row:
            if cell == " ":
                return False
    return True


# 获得玩家落子位置
def get_player_move(board):
    while True:
        try:
            row = int(input("输入行数 (1-3): ")) - 1
            col = int(input("输入列数 (1-3): ")) - 1
            if board[row][col] == " ":
                return row, col
            else:
                print("这个位置已经被占,请重新输入.")
        except ValueError:
            print("请输入1-3之间的数.")


# 极大极小/α-β剪枝算法
def minmax(board, depth, alpha, beta, maximizing):
    if check_win(board, "X"):
        return -10, None
    if check_win(board, "O"):
        return 10, None
    if check_tie(board):
        return 0, None
    if maximizing:
        best_score = -math.inf
        best_move = None
        for row in range(3):
            for col in range(3):
                if board[row][col] == " ":
                    board[row][col] = "O"
                    score, _ = minmax(board, depth - 1, alpha, beta, False)
                    board[row][col] = " "
                    if score > best_score:
                        best_score = score
                        best_move = (row, col)
                    alpha = max(alpha, best_score)
                    if beta <= alpha:
                        break
        return best_score, best_move
    else:
        best_score = math.inf
        best_move = None
        for row in range(3):
            for col in range(3):
                if board[row][col] == " ":
                    board[row][col] = "X"
                    score, _ = minmax(board, depth - 1, alpha, beta, True)
                    board[row][col] = " "
                    if score < best_score:
                        best_score = score
                        best_move = (row, col)
                    beta = min(beta, best_score)
                    if beta <= alpha:
                        break
        return best_score, best_move


def play_game():
    board = [[" " for j in range(3)] for i in range(3)]
    print_board(board)
    # 玩家选择先后手
    while True:
        user_choice = input("选择X或者O(X先手): ")
        if user_choice.lower() == "x":
            player = "X"
            break
        elif user_choice.lower() == "o":
            player = "O"
            break
        else:
            print("请输入X或O.")

    # 玩家先手
    if player == "X":
        while not check_win(board, "X") and not check_tie(board):
            row, col = get_player_move(board)
            board[row][col] = "X"
            print_board(board)
            if check_win(board, "X"):
                print("玩家获胜!")
                return
            if check_tie(board):
                print("平局!")
                return
            _, (row, col) = minmax(board, 9, -math.inf, math.inf, True)
            print("电脑思考后落子", (row+1, col+1))
            board[row][col] = "O"
            print_board(board)
            if check_win(board, "O"):
                print("玩家失败!")
                return
            if check_tie(board):
                print("平局!")
                return
    # 电脑先手
    else:
        while not check_win(board, "O") and not check_tie(board):

            _, (row, col) = minmax(board, 9, -math.inf, math.inf, True)
            print("电脑思考后落子", (row+1, col+1))
            board[row][col] = "X"
            print_board(board)
            if check_win(board, "X"):
                print("玩家失败!")
                return
            if check_tie(board):
                print("平局!")
                return
            row, col = get_player_move(board)
            board[row][col] = "O"
            print_board(board)
            if check_win(board, "O"):
                print("玩家获胜!")
                return
            if check_tie(board):
                print("平局!")
                return


if __name__ == '__main__':
    play_game()

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值