找回密码
 欢迎注册
查看: 54010|回复: 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-4-20 10:47 , Processed in 0.046916 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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