http://en.wikipedia.org/wiki/Minimax
棋盘游戏的特点就是有比较简单的规则(相对于复杂的世界来讲),这些规则比较好用数学方式来描述,并且一般游戏是你死我活的,不存在双赢的情况。
最直接的方式是暴力的状态空间的搜索,首先需要定义什么是状态,状态包含哪些因素。
例如 tic-tac-toe这个游戏,游戏在 3*3的格子上面两人交替 画 X 和 O (邪恶),在某一行 某一列 对角线 上 同时三个相同则胜利。
例如下面 X 胜利。
X X O
O X O
X O X
这个游戏每一个回合的状态 包括的属性有: 棋盘当前的棋子布局, 棋盘上可以下子的位置, 当前轮到谁来下子。
而模拟的过程就是
输入: 当前状态, 当前的下子玩家
遍历 当前所有可以下子的位置
拷贝一份当前状态,修改状态下子, 交换下子方
对拷贝的状态进行 分析, 胜利,失败,无地方可走? 如果还能走则 递归处理拷贝的状态
但是上面的模拟过程没有告诉我们,当前状态下,究竟该下哪一步呢?最简单的方案,哪一步有胜利的希望就下那一步(一般会有多个可能性);
怎么描述胜利的希望呢?
假设当前下子的是 X 同学,
X同学 试探所有的可能位置,寻找可能胜利的位置
接着该轮到O同学下子, O同学在X同学下子的基础上,寻找自己可能下子的位置。
那么对于X同学来讲,开始就是要找到一个好的分支,这个分支O同学胜利希望比较小。 但是问题是我没试过这个分支,怎么知道这个分支O同学胜利希望比较小呢? 所以需要O同学来告诉我 说这个分支O胜利比较小, X胜利比较大。
同样对于O同学, 在选择分支的时候 需要X同学告诉他 某个分支的情况。
这种递归过程, 终止的条件就是棋盘下满了,或者某一步出现了胜利条件。
因此整个评估过程是 自底向上的。
例如 假设有下面的下棋过程
X . . X O . X O . X O . X O .
. . . . . . . X . O X . O X .
. . . . . . . . . . . . . . X
X胜利了, 那么 从最后一步向前分析就是:
倒数第二步 O 下子在 第二行 第一列 的 对于O的估值是 -1(失败) 对于 X 来讲是 1(胜利)
倒数第三步 X 下子在 2行 2列的 对X 估值是 1 对 O 估值是 0
倒数第4步 O 下子 2行 1列 O 估值 -1 X估值 1
倒数第5步 X 下子 1行 1列 X估值 1 O 估值 -1
ok, 上面的估值 可以看到对X O 的估值是 相反数 和是0, 这也就是 0和游戏的意思。 你死 = 我胜
但是问题是, 我们对X下子 1行 1列的估值 只考虑了一种情况, 就是上面下子的情况, 没有考虑 其它情况,没有考虑O会按照我们设定的方案来走么?
显然不会,O同学也会估计形势, 选择 当前最利于自己的方案来走, 所以第4步 O同学不会选择 2 行 1列, 而是 2行2列。
整个棋盘的 状态空间 构成一棵 层层深入的树
X 选择9种可能
X 选择 1 X选择 2 X选择3 X选择 4 。。。。。X选择8
假设我们对所有节点的估值都是相对于X来讲的。
比如我们是 X 则 X需要最大估值, max (child)
而每个子节点 是 轮到O选择, O要得到 自己最大估值 对X最小估值 min(child)
整棵树 共享了一个信息,即当前的估值是相对于谁的,也就是树的根节点是谁,有了这个信息,我们才能正确的给上层返回合理的值。