所以我在寻找一个Tic-Tac-Toe游戏的Mini-max,但是无法理解递归是如何工作的?好的,所以基本上我的问题是:
例如在这个伪代码中
function integer minimax(node, depth)
if node is a terminal node or depth <= 0:
return the heuristic value of node
α = -∞
for child in node: # evaluation is identical for both players
α = max(α, -minimax(child, depth-1))
return α
node
是正确的?并且代码在递归中的深度是多少?什么是max
函数以及从哪里生成节点?
现在,到目前为止,我已经有了创建电路板的代码:
class Board{
public:
Board();
~Board(){};
public: // The board
// In the board, 1 is x, 2 is o, 0 is empty square.
int board[3][3];
};
但我怎么知道轮到谁了?如何为电路板生成子节点?
答案 0 :(得分:5)
我们首先以你的tic-tac-toe为例。
查看你的伪代码:
max(a, b)
是返回a
或b
中较大者的任何函数。这通常由数学库或类似工具库提供。depth
是您要搜索的最大深度。1
,-1
为其他玩家赢得的董事会职位,以及0
任何不确定的职位。一般来说,你必须自己做一个启发式的方法,或者使用一个被广泛接受的方法。如果你还没有使用图形或树木,我建议你先这样做;特别是树原语对于这个问题是必需的。
作为对此线程中的注释的回答,请求确定给定节点的转向的示例,我提供了这个伪Python:
who_started_first = None
class TreeNode:
def __init__(self, board_position = EMPTY_BOARD, depth = 0):
self.board_position = board_position
self.children = []
self.depth = depth
def construct_children(self, max_depth):
# call this only ONCE per node!
# even better, modify this so it can only ever be called once per node
if max_depth > 0:
### Here's the code you're actually interested in.
if who_started_first == COMPUTER:
to_move = (COMPUTER if self.depth % 2 == 0 else HUMAN)
elif who_started_first == HUMAN:
to_move = (HUMAN if self.depth % 2 == 0 else COMPUTER)
else:
raise ValueError('who_started_first invalid!')
for position in self.board_position.generate_all(to_move):
# That just meant that we generated all the valid moves from the
# currently stored position. Now we go through them, and...
new_node = TreeNode(position, self.depth + 1)
self.children.append(new_node)
new_node.construct_children(max_depth - 1)
每个节点都能够跟踪“根”节点的绝对深度。当我们试图确定我们应该如何为下一步行动生成董事会职位时,我们会根据深度的平价(self.depth % 2
的结果)以及我们先移动的记录来检查其移动情况。 / p>
答案 1 :(得分:2)
1)极小极大如何知道轮到谁了?什么是最好的方式来指示轮到它的球员?
你有depth
个参数。如果深度是均匀的,那么它是一个玩家的回合,如果它是奇数,那么它是另一个玩家的回合。
2)你如何产生可能的动作?
使用游戏规则。在tic tac toe中,可能的移动意味着将一个标记放入一个空闲单元格中。
3)你怎么知道你在终端节点的时间,以及如何生成终端节点?
终端节点是某人获胜的节点。你通过递归生成它们。每个递归调用应该被赋予电路板的当前状态。我想这是伪代码中的node
和child
参数。因此,如果在某种情况下有人赢了,那么它就是终点,否则你会尝试所有法律行动并递归。
答案 2 :(得分:2)
我可以提供一些关于你在寻找什么的想法,因为我为tic-tac-toe编写了一个minimax算法。
直接回答您的问题:
我的minimax算法没有确定。它接受了一个决定算法正在使用哪个玩家的论据。
知道要移动的玩家,循环遍历棋盘上的所有空白方块,并为每个方块生成一个节点,该节点包含该方块中当前玩家的标记。递归地从那里开始。
我使用了一个函数,该函数返回一个值,表明游戏是否结束,以及是抽奖还是赢。
我的基本算法做到了这一点: