078. 编写一个函数,实现简单的游戏AI

在 Python 中,可以使用简单的算法来实现一个游戏 AI。这里我们将以一个经典的井字棋(Tic-Tac-Toe)游戏为例,实现一个基于 Minimax 算法的 AI。Minimax 算法是一种常用的博弈树搜索算法,用于在两人对弈游戏中找到最优策略。

示例代码

import numpy as np

# 定义井字棋的棋盘
class TicTacToe:
    def __init__(self):
        self.board = np.zeros((3, 3), dtype=int)  # 0 表示空,1 表示玩家,-1 表示 AI

    def print_board(self):
        for row in self.board:
            print(" | ".join(["X" if cell == 1 else "O" if cell == -1 else " " for cell in row]))
            print("-" * 9)

    def is_winner(self, player):
        # 检查行、列和对角线是否有赢家
        for i in range(3):
            if np.all(self.board[i, :] == player) or np.all(self.board[:, i] == player):
                return True
        if np.all(np.diag(self.board) == player) or np.all(np.diag(np.fliplr(self.board)) == player):
            return True
        return False

    def is_draw(self):
        return np.all(self.board != 0)

    def get_empty_cells(self):
        return [(i, j) for i in range(3) for j in range(3) if self.board[i, j] == 0]

# Minimax 算法
def minimax(board, depth, is_maximizing):
    if game.is_winner(1):
        return -1
    if game.is_winner(-1):
        return 1
    if game.is_draw():
        return 0

    if is_maximizing:
        best_score = -np.inf
        for (i, j) in game.get_empty_cells():
            board[i, j] = -1
            score = minimax(board, depth + 1, False)
            board[i, j] = 0
            best_score = max(score, best_score)
        return best_score
    else:
        best_score = np.inf
        for (i, j) in game.get_empty_cells():
            board[i, j] = 1
            score = minimax(board, depth + 1, True)
            board[i, j] = 0
            best_score = min(score, best_score)
        return best_score

# AI 选择下一步
def ai_move(game):
    best_score = -np.inf
    move = None
    for (i, j) in game.get_empty_cells():
        game.board[i, j] = -1
        score = minimax(game.board, 0, False)
        game.board[i, j] = 0
        if score > best_score:
            best_score = score
            move = (i, j)
    game.board[move[0], move[1]] = -1

# 玩家选择下一步
def player_move(game):
    while True:
        try:
            row, col = map(int, input("请输入你的移动(行和列,例如 '0 1'):").split())
            if game.board[row, col] == 0:
                game.board[row, col] = 1
                break
            else:
                print("该位置已被占用,请重新选择。")
        except (ValueError, IndexError):
            print("输入无效,请重新输入。")

# 主游戏循环
def play_game():
    game = TicTacToe()
    game.print_board()
    while True:
        player_move(game)
        game.print_board()
        if game.is_winner(1):
            print("玩家获胜!")
            break
        if game.is_draw():
            print("平局!")
            break

        ai_move(game)
        print("AI 的移动:")
        game.print_board()
        if game.is_winner(-1):
            print("AI 获胜!")
            break
        if game.is_draw():
            print("平局!")
            break

# 示例用法
if __name__ == "__main__":
    play_game()

代码说明

井字棋棋盘:使用一个 3x3 的 NumPy 数组表示棋盘,其中 0 表示空,1 表示玩家,-1 表示 AI。

检查赢家:检查行、列和对角线是否有赢家。

Minimax 算法

  • 使用 Minimax 算法评估棋盘状态,选择最优的下一步。

  • minimax 函数递归地评估所有可能的移动,返回最优的评分。

AI 选择下一步:AI 通过 Minimax 算法选择最优的下一步。

玩家选择下一步:玩家通过输入行和列选择下一步。

主游戏循环:交替进行玩家和 AI 的移动,直到游戏结束。

示例输出

 | | 
---------
 | | 
---------
 | | 
请输入你的移动(行和列,例如 '0 1'):0 1
 |X| 
---------
 | | 
---------
 | | 
AI 的移动:
 |X|O
---------
 | | 
---------
 | | 
请输入你的移动(行和列,例如 '0 1'):1 1
 |X|O
---------
 |X| 
---------
 | | 
AI 的移动:
 |X|O
---------
 |X|O
---------
 | | 
...

注意事项

  1. Minimax 算法的优化:对于更复杂的游戏,可以使用 Alpha-Beta 剪枝优化 Minimax 算法,减少不必要的搜索。
  2. 游戏规则:根据具体游戏规则调整代码,例如棋盘大小、胜利条件等。
  3. 用户输入:确保用户输入有效,避免程序崩溃。

视频讲解

BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)