您的位置:首页 > 其它

极大极小博弈树的简洁(附Tic-Tac-Toe源码)

2011-01-26 21:46 344 查看
简介

极大极小博弈树(Minimax Game Tree)用于编写电脑之间的游戏程序,这类程序由两个游戏者轮流,每次执行一个步骤。当然,所有可能的步骤构成了一个树的结构。例如下面的图就是一个MGT,它表示了Tic-Tac-Toe游戏的前两步所有可能的步骤。



在每一层中的节点通常代表不同游戏者的选择,这两个游戏者通常被称作马克思(MAX)和米恩(Min)。

例如如果第二层是Max turn,则第三层就是Min turn,第二层的每个节点就是Max的choice,它们之间是或的关系,第三层的每个节点就是Min的choice,它们之间是与的关系。根据这个树,Max要做出的选择就让下次Min做出的任意选择都最小,即Minimax这个词的含义,极小化对手的最大收益。所以它不同于Maximin最大化自己的收益。

因为往往一局要下到最后才能分出胜负,而Game Tree上nodes的增长是以指数方式的,比如深蓝(Deep Blue)可以搜索12步,假设各方每步都有10种选择,那么一次的搜索量也有1万亿次,所以对于普通的电脑能够搜索到4步也有1万次了,所以就需要一个评分系统,对局面进行打分,考虑到是双人对战,则评分从负无穷到正无穷。所以马克思就是要找到一个最大的分数,而米恩就是要找到一个最小的分数。

例子

下面用一个例子来说明,Tic-Tac-Toe游戏。

其中‘o’代表PC,‘x’代表玩家。

其中有三个主要的函数:

int minSearch( char _board[9] )

int maxSearch( char _board[9] )

int gameState(char _board[9])

分别扮演max和min的角色,寻找最大和最小值,以及一个评分函数。

下面重点说说这个游戏的核心部分,gameState评分函数:

连三 100分

双连二 50分

平局 0分

不分胜负 1

其中如果评分时不分胜负则还会继续搜索,直到找到其他三种状态。

implementation

[code]   1: int gameState(char _board[9])


2: {


3:     int state;


4:     static int table[][3] =


5:     {


6:         {0, 1, 2},


7:         {3, 4, 5},


8:         {6, 7, 8},


9:         {0, 3, 6},


10:         {1, 4, 7},


11:         {2, 5, 8},


12:         {0, 4, 8},


13:         {2, 4, 6},


14:     };


15:     char chess = _board[0];


16:     for (char i = 1; i < 9; ++i)


17:     {


18:         chess &= _board[i];


19:     }


20:     bool isFull = 0 != chess;


21:     bool isFind = false;


22:     for (int i = 0; i < sizeof(table) / sizeof(int[3]); ++i)


23:     {


24:         chess = _board[table[i][0]];


25:         int j;


26:         for (j = 1; j < 3; ++j)


27:             if (_board[table[i][j]] != chess)


28:                 break;


29:         if (chess != empty && j == 3)


30:         {


31:             isFind = true;


32:             break;


33:         }


34:     }


35:     if (isFind)


36:         //got win or lose


37:         state = chess == o ? WIN : LOSE;


38:     else


39:     {


40:         if (isFull)


41:             //all position has been set without win or lose


42:             return DRAW;


43:         else


44:         {


45:             //finds[0] -> 'o', finds[1] -> 'x'


46:             int finds[2] = {0, };


47:             for (int i = 0; i < sizeof(table) / sizeof(int[3]); ++i)


48:             {


49:                 bool findEmpty = false;


50:                 chess = 0xff;


51:                 int j;


52:                 for (j = 0; j < 3; ++j)


53:                     if (_board[table[i][j]] == empty && !findEmpty)


54:                         findEmpty = true;


55:                     else


56:                         chess &= _board[table[i][j]];


57:                 if ((chess == o || chess == x) && findEmpty)


58:                 {


59:                     isFind = true;


60:                     if (o == chess)


61:                         ++finds[0];


62:                     else


63:                         ++finds[1];


64:                 }


65:             }


66:             if (finds[0] > 1 && finds[1] < 1)


67:                 //2 'o' has been founded twice in row, column or diagonal direction


68:                 state = -(INFINITY / 2) * finds[0];


69:             else if (finds[1] > 1 && finds[0] < 1)


70:                 //2 'x' has been founded twice in row, column or diagonal direction


71:                 state = INFINITY / 2 * finds[1];


72:             else


73:                 //need to search more.


74:                 state = INPROGRESS;


75:         }


76:     }


77:     return state;


78: }

[/code]

最后附上源码:http://files.cnblogs.com/chinese-zmm/Tic-Tac-Toe.7z

Reference

http://en.wikipedia.org/wiki/Minimax

/article/6055117.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: