吴昊品游戏核心算法 Round 6 (特刊) —— 吴昊教你玩石头剪刀布AI(数据挖掘)
我曾经请教过我在华科的同班同学李田同学,我问他 《圣母颂——巴赫第一平均律》是不是很难弹?他说是的,而且,他说了一点,就是,越简单的曲子越难。这个可以类推,比如,围棋的规则最简单,却蕴含着最深 刻的哲理,而石头剪刀布也是类似的,看似非常简单的规则,却考验着人的许多弱点。比如,再客观的人,在机器面前也不可能保持着绝对的客观,所以,他/她的 出拳总是存在一定的规律,而这些数据特性一经过计算机的分析,就很容易破解你的招数了。
在 Android手机上,有一款软件叫做——智能猜拳机器人,根据不完全统计,但总回合数达到50局以上时,智能猜拳机器人的优势会开始体现,胜率基本保持 在60%左右,例如果玩了50局,电脑和对方的比分会达到 30:20(此数据仅仅是推测,具体视当前情况而定)。此外,在一定范围内,积累的数据越多,胜率就会越高!如图所示,以下是一些结果:
确实,猜拳绝对不是一个随机的游戏,它考验了玩家的很多方面,比如眼睛的敏锐度,手指的灵敏度。甚至,不经过任何观察的手机,也可以根据你每次出的手势利 用数据挖掘的某些技术让胜率随着你的出拳Style进行一些改变。于是乎,很多类似于以上的android小应用诞生。纽约时报还刊登了一个更加权威的石 头剪刀布的游戏,算法应该说更全面,更优秀。
这个http://www.worldrps.com/是国际石协,简称国际石头剪刀布协会。
关于其的模拟算法,由于过于简单,这里不给出解释,直接给出源代码好了,我想说的是后面的基于数据挖掘技术的AI。该算法模拟全程,可以统计出最后双方是谁战胜了谁,以及各自的胜负次数。
2 #include<string>
3 using namespace std;
4
5 string P("P"); //石头
6 string R("R"); //布
7 string S("S"); //剪刀
8
9 void getinfor(string &t,string &t1)
10 {
11 cin>>t>>t1;
12 }
13
14 bool process(int &p1,int &p2,string tm,string tm1)
15 {
16 if(tm==P)
17 {
18 if(tm1==R)
19 {
20 p1++;
21 }
22 else if(tm1==S)
23 {
24 p2++;
25 }
26 }
27 else if(tm==R)
28 {
29 if(tm1==P)
30 {
31 p2++;
32 }
33 else if(tm1==S)
34 {
35 p1++;
36 }
37 }
38 else
39 {
40 if(tm1==P)
41 {
42 p1++;
43 }
44 else if(tm1==R)
45 {
46 p2++;
47 }
48 }
49 return true;
50 }
51
52 int main()
53 {
54 int test;
55 int n;
56 cin>>test;
57 while(test--)
58 {
59 cin>>n;
60 string temp;
61 string temp1;
62 int player1=0;
63 int player2=0;
64 for(int i=0;i<n;i++)
65 {
66 getinfor(temp,temp1);
67 process(player1,player2,temp,temp1);
68 }
69 if(player1==player2)
70 {
71 puts("TIE");
72 }
73 else if(player1>player2)
74 {
75 puts("Player 1");
76 }
77 else
78 {
79 puts("Player 2");
80 }
81 }
82 return 0;
83 }
84
吴昊继续,现在我来说下AI,首先还是看一张图吧,这张图比较权威:
从这张图中可以看出,猜拳考验了人的很多品质问题,而这些问题不单单地归结为“人品”,不光是观察力,以及你对对手出的招数的计策以及对手算计你的计策之 后的反计策。以上这些都是需要综合考虑的。故,计算机获得的关于你的主观数据越多,它的胜算也就越大。通过单一的统计数据的方式,也可以得到一些基于这些 数据的经验贝叶斯估计,但是,具体的论文在网上貌似还没有,自己的想法还过于幼稚,这里就不给出了。
最后,值得一说的是,在日本,有一位科学家发明了人类历史上最NB的猜拳机器人,听说是通过人的反应的千分之二秒的时间差来出自己的招数,可以达到必胜的效果。由于0.002s在允许的“作弊时间”之内,所以,这个机器人的猜拳是合乎规则的的。