http://en.wikipedia.org/wiki/Minimax布局
棋盘游戏的特色就是有比较简单的规则(相对于复杂的世界来说),这些规则比较好用数学方式来描述,而且通常游戏是你死我活的,不存在共赢的状况。递归
最直接的方式是暴力的状态空间的搜索,首先须要定义什么是状态,状态包含哪些因素。游戏
例如 tic-tac-toe这个游戏,游戏在 3*3的格子上面两人交替 画 X 和 O (邪恶),在某一行 某一列 对角线 上 同时三个相同则胜利。ip
例以下面 X 胜利。get
X X O数学
O X O基础
X O X搜索
这个游戏每个回合的状态 包括的属性有: 棋盘当前的棋子布局, 棋盘上能够下子的位置, 当前轮到谁来下子。遍历
而模拟的过程就是 im
输入: 当前状态, 当前的下子玩家
遍历 当前全部能够下子的位置
拷贝一份当前状态,修改状态下子, 交换下子方
对拷贝的状态进行 分析, 胜利,失败,无地方可走? 若是还能走则 递归处理拷贝的状态
可是上面的模拟过程没有告诉咱们,当前状态下,究竟该下哪一步呢?最简单的方案,哪一步有胜利的但愿就下那一步(通常会有多个可能性);
怎么描述胜利的但愿呢?
假设当前下子的是 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)
整棵树 共享了一个信息,即当前的估值是相对于谁的,也就是树的根节点是谁,有了这个信息,咱们才能正确的给上层返回合理的值。