惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
H
Help Net Security
B
Blog RSS Feed
G
Google Developers Blog
博客园 - 司徒正美
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
P
Proofpoint News Feed
小众软件
小众软件
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
V
V2EX
月光博客
月光博客
C
Check Point Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
Arctic Wolf
Help Net Security
Help Net Security
Schneier on Security
Schneier on Security
D
DataBreaches.Net
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
T
Tenable Blog
L
LangChain Blog
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
F
Fortinet All Blogs
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Y
Y Combinator Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
NISL@THU
NISL@THU
GbyAI
GbyAI
博客园 - Franky
S
Secure Thoughts
有赞技术团队
有赞技术团队
PCI Perspectives
PCI Perspectives
U
Unit 42

博客园 - chinese_submarine

QT项目性能调优小记 Windows下HG服务器的搭建 svn+tp-link+花生壳搭建外网服务器 udev介绍 程序优化小记 Beating the Average------为什么要学习Lisp[转] 巧用qmake工具生成专业的makefile QT中拖拽的实现(附示例代码) 从QDataStream向QByteArray中写入数据时的注意点(QT) 如何保持GUI的响应流畅(QT平台) 也谈线程同步变量 windows7到期的问题 简述FPS的计算方法 QT中的View Model模型系列一 从农夫养牛问题推广到斐波那契数列 TimeZoneChange事件的捕获 浏览器扩展系列————透明浏览器窗口的实现 浏览器扩展系列————异步可插入协议(pluggable protocol)的实现 浏览器扩展系列————给MSTHML添加内置脚本对象【包括自定义事件】
极大极小博弈树的简洁(附Tic-Tac-Toe源码)
chinese_submarine · 2011-01-26 · via 博客园 - chinese_submarine

简介

极大极小博弈树(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

   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: }

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

Reference

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

http://www.cnblogs.com/goodness/archive/2010/05/27/1745756.html

posted on 2011-01-26 21:46  chinese_submarine  阅读(5401)  评论()    收藏  举报