极小化极大算法与跳棋游戏

我正在使用极小化极大算法和Python实现跳棋游戏。游戏中有两个玩家 – 都是电脑。我一直在寻找类似问题的解决方案,但没有找到任何结果,并且已经为此挣扎了几天。我的入口点是这个函数:

def run_game(board):    players = board.players    is_move_possible = True    move = 0    while is_move_possible:        is_move_possible = move_piece_minimax(board, players[move % 2])        move += 1

它启动游戏并调用下一个函数,该函数应该根据极小化极大算法为第一位玩家做出最佳移动。在第一次移动之后,它会为第二位玩家调用这个函数,这个循环将在其中一位玩家赢得游戏后结束。该函数如下所示:

def move_piece_minimax(board, player):    best_move = minimax(copy.deepcopy(board), player, 0)    if best_move.score == +infinity or best_move.score == -infinity:        return False    move_single_piece(board.fields, player, best_move)    return True

第一行调用极小化极大算法,我将在后面描述,它应该为玩家找到最佳可能的移动。我在这里传递了整个棋盘的深拷贝,因为我不想在执行极小化极大算法时编辑原始棋盘。条件检查获胜条件,因此如果最大化玩家或最小化玩家获胜。如果没有一方获胜,则执行best_move。现在回到主要问题,我实现了极小化极大算法如下:

def minimax(board, player, depth):    best_move = Move(-1, -1, -infinity if player.name == PLAYER_NAMES['P1'] else +infinity)    if depth == MAX_SEARCH_DEPTH or game_over(board):        score = evaluate(board)        return Move(-1, -1, score)    for correct_move in get_all_correct_moves(player, board.fields):        x, y, piece = correct_move.x, correct_move.y, correct_move.piece        move_single_piece(board.fields, player, correct_move)        player_to_move = get_player_to_move(board, player)        move = minimax(board, player_to_move, depth + 1)    # <--- 这里是递归        move.x = x        move.y = y        move.piece = piece        if player.name == PLAYER_NAMES['P1']:            if move.score > best_move.score:                best_move = move  # 最大值        else:            if move.score < best_move.score:                best_move = move  # 最小值    return best_move

我决定玩家‘P1’最大化玩家,玩家‘P2’最小化玩家。从第一行开始,best_move变量保存对Move对象的引用,该对象具有以下字段:

class Move:    def __init__(self, x, y, score, piece=None):        self.x = x        self.y = y        self.score = score        self.piece = piece

我将best_move.score初始化为最大化玩家的-Infinity,对于其他情况则为+Infinity。

第一个条件检查深度是否达到了最大级别(为了测试目的,设置为2)或游戏是否结束。如果是,则评估当前棋盘的情况并返回一个包含当前棋盘得分的Move对象。否则,我的算法会寻找该玩家所有合法/正确的移动,并执行第一个移动。

执行后,该函数以递归方式调用,但深度增加并更换移动的玩家。该函数在更改参数后再次运行,直到第一个if条件执行。

一旦执行进入该分支,将返回棋盘的评估得分,之后,在递归调用后的for循环中,将移动的坐标x、y和棋子分配给Move对象。

最后的条件检查新得分是否是该特定玩家的更好得分。如果这是最大化玩家,在我的例子中是P1,它会检查新得分是否高于之前的得分。对于最小化玩家,算法寻找最低得分。

在为该玩家执行所有正确移动后,我的算法应该返回一个best_move。

预期结果
Move类的单个对象,包含坐标x和y,评估的棋盘得分,仅在其中一位玩家获胜的情况下为+Infinity/-Infinity,以及将移动到[x, y]坐标的Piece类对象。

实际结果
Move类的单个对象,包含坐标x和y,评估的棋盘得分在第一次调用极小化极大函数后等于+Infinity。没有棋子改变其位置,因此游戏尚未结束。然而,得分为+Infinity,因此函数move_piece_minimax()将返回False – 意味着没有更多可能的移动。因此,我的程序将在棋盘上没有任何变化的情况下停止执行。这是初始和最终棋盘状态的截图 – 在执行过程中没有任何变化,因为第一次调用返回了+Infinity。

初始和最终棋盘状态

我的问题是,在实现极小化极大算法时我遗漏了什么?我犯了什么错误?我也欢迎任何代码改进或建议。如果您需要了解我的实现的任何其他函数,我会提供它们。谢谢!


回答:

在极小化极大函数中,您应该执行以下操作之一

1. 在放置棋子之前制作棋盘的副本

2. 在递归调用极小化极大函数后移除放置的棋子

否则,您的棋盘将在递归过程中被棋子填满,您将收到一个错误,指出没有剩余的移动。极小化极大算法旨在通过放置棋子进行深入搜索,因此您应该实现一种方法,使其不修改原始棋盘。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注