关于对对碰游戏的研究

关于对对碰游戏的研究我真无聊

大家好,欢迎来到IT知识分享网。

(封面图片来源于网络侵权删)

关于灵感

小学时不知道同学从哪里带回来的游戏,规则是这样的:

两个玩家首先比出两个1的手势,情况是这样的:

a玩家:左手:1,右手:1

b玩家:左手:1,右手:1

然后决定先后顺序,依次在每个自己的回合做出一下行动:使用自己的左手或右手碰一下对方的左手或右手,然后将碰到的两只手所表示的数值相加,自己碰的那只手就变为该数值。如:

原局面:

a玩家:左手:1,右手:1

b玩家:左手:1,右手:1

a玩家使用左手碰了对方的右手后:

a玩家:左手:1+1=2,右手:1

b玩家:左手:1,右手:1

到b玩家时,b玩家可以用左手碰对方的右手:

a玩家:左手:2,右手:1

b玩家:左手:3,右手:1

谁先将两只手都到达目标数字(一般是10)就赢了

我在一次某讲座上和同学玩这个游戏时突然想到,这个游戏有没有必胜的策略?遂作此程序。(不知道这算不算博弈论了反正先当标题党写上吧)

思路

那当然是!dfs直接打爆力求解!

这部分没什么好说的,不会的可以去我的专栏或B站

于是我们得到以下代码:

#include "bits/stdc++.h" #include <conio.h> #include <windows.h> using namespace std; bool handMarker[20][20][20][20]; int endNumber, aLeftHand, aRightHand, bLeftHand, bRightHand; int aMayWin = 0, bMayWin = 0; void color(int m) { HANDLE consolehend; consolehend = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(consolehend, m); } void dfs(int aLeftHand, int aRightHand, int bLeftHand, int bRightHand, int step) { // 成功后输出 if ((aLeftHand == endNumber && aRightHand == endNumber) || (bLeftHand == endNumber && bRightHand == endNumber)) { if ((step - 1) % 2 == 0) { aMayWin++; } else { bMayWin++; } // color(0x02); for (int i = 1; i <= step - 1; i++) { printf(u8"│ "); } printf(u8"├─"); printf(u8"%c:Win!:)\n", (step - 1) % 2 + 'a'); for (int i = 1; i <= step - 1; i++) { printf(u8"│ "); } printf(u8"└─"); printf(u8"Used Step: %d.\n", step); // color(0x0F); return ; } handMarker[aLeftHand][aRightHand][bLeftHand][bRightHand] = 1; // 输出 if (step >= 1) { for (int i = 1; i <= step - 1; i++) { printf(u8"│ "); } printf(u8"├─"); printf(u8"%c:My turn!\n", (step + 1) % 2 + 'a'); for (int i = 1; i <= step - 1; i++) { printf(u8"│ "); } printf(u8"├─"); printf(u8"back:a:%d %d b:%d %d\n", aLeftHand, aRightHand, bLeftHand, bRightHand); } int newHand; if (step % 2 == 0) { if (aLeftHand != endNumber) { if (bLeftHand != endNumber) { newHand = (aLeftHand + bLeftHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[newHand][aRightHand][bLeftHand][bRightHand]) { dfs(newHand, aRightHand, bLeftHand, bRightHand, step + 1); } } if (bRightHand != endNumber) { newHand = (aLeftHand + bRightHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[newHand][aRightHand][bLeftHand][bRightHand]) { dfs(newHand, aRightHand, bLeftHand, bRightHand, step + 1); } } } if (aRightHand != endNumber) { if (bLeftHand != endNumber) { newHand = (aRightHand + bLeftHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][newHand][bLeftHand][bRightHand]) { dfs(aLeftHand, newHand, bLeftHand, bRightHand, step + 1); } } if (bRightHand != endNumber) { newHand = (aRightHand + bRightHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][newHand][bLeftHand][bRightHand]) { dfs(aLeftHand, newHand, bLeftHand, bRightHand, step + 1); } } } } if (step % 2 == 1) { if (bLeftHand != endNumber) { if (aLeftHand != endNumber) { newHand = (bLeftHand + aLeftHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][aRightHand][newHand][bRightHand]) { dfs(aLeftHand, aRightHand, newHand, bRightHand, step + 1); } } if (aRightHand != endNumber) { newHand = (bLeftHand + aRightHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][aRightHand][newHand][bRightHand]) { dfs(aLeftHand, aRightHand, newHand, bRightHand, step + 1); } } } if (bRightHand != endNumber) { if (aLeftHand != endNumber) { newHand = (bRightHand + aLeftHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][aRightHand][bLeftHand][newHand]) { dfs(aLeftHand, aRightHand, bLeftHand, newHand, step + 1); } } if (aRightHand != endNumber) { newHand = (bRightHand + aRightHand) % (endNumber + 1); if (newHand == 0) { newHand = 1; } if (!handMarker[aLeftHand][aRightHand][bLeftHand][newHand]) { dfs(aLeftHand, aRightHand, bLeftHand, newHand, step + 1); } } } } } int main() { printf("Change to which number will win?"); scanf("%d", &endNumber); // 输入 printf("Beginning number?"); scanf("%d%d%d%d", &aLeftHand, &aRightHand, &bLeftHand, &bRightHand); freopen("out.txt", "w", stdout); printf(u8"back:a:%d %d b:%d %d\n", aLeftHand, aRightHand, bLeftHand, bRightHand); dfs(aLeftHand, aRightHand, bLeftHand, bRightHand, 0); printf(u8"Total Win: a:%d b:%d\n", aMayWin, bMayWin); printf(u8"The possibility of a's winning: %.2f%%\n", 1.0 * aMayWin / (aMayWin + bMayWin) * 100); printf(u8"The possibility of b's winning: %.2f%%\n", 1.0 * bMayWin / (aMayWin + bMayWin) * 100); return 0; }

(做了一点输出优化)

如果你想要在控制台看的话就把main()里的freopen注释掉再把dfs里的color函数取消注释。

结果

很神奇

似乎是一个区间一个区间来的

首先,如果目标数是2的话,a玩家完胜:

Total Win: a:4 b:0 The possibility of a's winning: 100.00% The possibility of b's winning: 0.00%

目标数在3到7的区间里(含3和7)的话,b玩家的胜率先是一下提高,然后缓降:

3: Total Win: a:8 b:11 The possibility of a's winning: 42.11% The possibility of b's winning: 57.89% 4: Total Win: a:21 b:22 The possibility of a's winning: 48.84% The possibility of b's winning: 51.16% 5: Total Win: a:32 b:32 The possibility of a's winning: 50.00% The possibility of b's winning: 50.00% 6: Total Win: a:48 b:42 The possibility of a's winning: 53.33% The possibility of b's winning: 46.67% 7: Total Win: a:86 b:67 The possibility of a's winning: 56.21% The possibility of b's winning: 43.79%

随后在8到11的区间内又缓升:

8: Total Win: a:107 b:98 The possibility of a's winning: 52.20% The possibility of b's winning: 47.80% 9: Total Win: a:140 b:136 The possibility of a's winning: 50.72% The possibility of b's winning: 49.28% 10: Total Win: a:163 b:169 The possibility of a's winning: 49.10% The possibility of b's winning: 50.90% 11: Total Win: a:197 b:211 The possibility of a's winning: 48.28% The possibility of b's winning: 51.72%

而后又降:

12: Total Win: a:244 b:248 The possibility of a's winning: 49.59% The possibility of b's winning: 50.41%

(后面没算了有人跑出来的话发一下评论区谢谢了)

(我猜会不会到后面双方胜率无限接近于50%)

(所以这个游戏最好去重玩,保证不会出现重复局面)

总结

我真无聊,写这个破玩意写到现在,明天还要月考(啊我靠1点了???

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153095.html

(0)
上一篇 2025-03-05 22:15
下一篇 2025-03-05 22:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信