找回密码
 欢迎注册
查看: 79202|回复: 32

[讨论] 一个老题,扑克博弈

[复制链接]
发表于 2008-7-1 16:03:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
精华
A,B两人玩一个游戏,每位参加者发18张牌:三张6点,三张5点,三张4点,三张3点,三张2点,三张1点. 他们轮流出牌,A先出一张,B再出一张,每轮不能不出牌. 谁先出的牌使得桌子上的牌的全部点数之和等于50谁就算赢了, 但若那张牌使全部点数之和超过了50,他就算输了.问A和B谁有必胜策略?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-1 17:21:18 | 显示全部楼层
倒想起了原来编递归函数来算阶乘。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 07:47:32 | 显示全部楼层
A先出1点,以后看B出x点,则自己出(7-x)点,这样使桌面上的点数总和保持为(7k+1)型,可拿到50的情形。 B看出了苗头,并利用A手头1点数目不足的弱点,最后三轮中连出6点,让A无法形成上述策略而告输。 抛砖引玉。具体怎样设计策略而稳赢,还没想好。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 08:29:12 | 显示全部楼层
那显然A的策略是必输策略阿 呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 08:54:41 | 显示全部楼层
可以用程序解决吗?用程序复杂度不高
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 09:31:37 | 显示全部楼层
有简单的方法吗?计算机说只要先手先出3,4,5或6都可以赢
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 10:26:18 | 显示全部楼层
能不能出示你的程序 另外,这种策略类的游戏 能不能不用C/C++程序 Prolog/Lisp/Haskell/SML/Python等都可以 唯独不要用C/C++,呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 10:30:51 | 显示全部楼层
习惯用C/C++了,其它语言基本不会用了。
  1. #include <stdio.h>
  2. #define LIMIT (1<<24)
  3. int states[LIMIT];
  4. #define FAIL -1
  5. #define SUCC -2
  6. void gen(int left){
  7. int first_u=left&((1<<12)-1);
  8. int second_u=left>>12;
  9. int cfirst,csecond;
  10. int i,sum;
  11. cfirst=csecond=0,sum=0;
  12. for(i=0;i<6;i++){
  13. int c1=(first_u>>(2*i))&3;
  14. int c2=(second_u>>(2*i))&3;
  15. cfirst+=c1;
  16. csecond+=c2;
  17. sum+=(c1+c2)*(i+1);
  18. }
  19. sum=126-sum;
  20. if(sum>50){
  21. states[left]=FAIL;
  22. }else if(sum==50){
  23. states[left]=SUCC;
  24. }else{
  25. int s[6],j;
  26. for(i=0;i<6;i++){
  27. s[i]=(first_u>>(2*i))&3;
  28. }
  29. for(i=0;i<6;i++){
  30. int new_u=first_u;
  31. int reach;
  32. if(s[i]>0){
  33. new_u-=1<<(2*i);
  34. }
  35. reach=second_u|(new_u<<12);
  36. if(states[reach]==SUCC)
  37. break;
  38. }
  39. if(i<6){
  40. states[left]=FAIL;
  41. }else{
  42. states[left]=SUCC;
  43. }
  44. }
  45. }
  46. void output_states(int x);
  47. int next_state(int x)
  48. {
  49. int first_u=x&((1<<12)-1);
  50. int second_u=x>>12;
  51. int i,s[6];
  52. for(i=0;i<6;i++){
  53. s[i]=(first_u>>(2*i))&3;
  54. }
  55. int reach=-1;
  56. for(i=0;i<6;i++){
  57. int new_u=first_u;
  58. if(s[i]>0){
  59. new_u-=1<<(2*i);
  60. reach=second_u|(new_u<<12);
  61. if(states[reach]==SUCC){
  62. output_states(reach);
  63. }
  64. }
  65. }
  66. return reach;
  67. }
  68. void output_states(int x)
  69. {
  70. printf("State %06x:",x);
  71. if(states[x]==SUCC){
  72. printf("F");
  73. }else{
  74. printf("S");
  75. }
  76. printf("\n");
  77. }
  78. int main()
  79. {
  80. int i;
  81. for(i=0;i<LIMIT;i++){
  82. gen(i);
  83. }
  84. output_states(LIMIT-1);
  85. printf("next states:\n");
  86. next_state(LIMIT-1);
  87. return 0;
  88. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 10:36:15 | 显示全部楼层
原帖由 mathe 于 2008-7-2 09:31 发表 有简单的方法吗?计算机说只要先手先出3,4,5或6都可以赢
可否用文字具体叙述之后的出牌策略?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-7-2 10:38:21 | 显示全部楼层
程序用一个24比特的整数表示牌局中一个状态, 低12比特代表接下去出牌的人手中牌的状态,高12比特代表另外一个人手中牌的状态。 其中12比特可以看成6个两比特的数据,分别代表持有1,2,3,...,6的数目(0~3张) 然后一次计算各个局面是先手胜还是先手负,结果SUCC表示先手负(无论怎么出牌都会达到FAIL局面),FAIL表示先手胜局面(存在一种出牌方案留下SUCC的局面)

评分

参与人数 1鲜花 +2 收起 理由
gxqcn + 2 妙!建议用 0-11 / 16-27 bit试试看。

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 20:26 , Processed in 0.029320 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表