zoukankan      html  css  js  c++  java
  • 基于Alpha-Beta剪枝的欢乐斗地主残局辅助

    2019年4月17日更新:

    将搜索主函数优化为局部记忆化搜索,再次提高若干倍搜索速度

    更新了main和player,helper无更新

      1 #include "Player-v3.0.cpp"
      2 #include "Helper.cpp"
      3 
      4 #define END {if(fir){newA=a; newB=b;} return 1;}
      5 #define NXT {if(ok&&play(b,a,0)==0) return 1; else return 0;}
      6 #define NO  {printf("Can't Out
    "); newA=a; newB=b;}
      7 player newA,newB;
      8 bool play(player,player,bool);
      9 
     10 bool Play_Rocket(player a,player b,bool fir){
     11     if(b.empty()) return 0;
     12     if(a.CanPlayRocket()){
     13         a.PlayRocket();
     14         bool now=play(a,b,0);
     15         if(now){
     16             if(fir) Out_Rocket();
     17             END;
     18         }
     19     }
     20     return 0;
     21 }
     22 
     23 bool Play_Boom(player a,player b,int last,bool fir,bool ok){
     24     if(b.empty()) return 0;
     25     if(Play_Rocket(a,b,fir)) return 1;
     26     player _a=a;
     27     if(a.CanBoom)
     28     for(int i=last+1;i<15;i++)
     29     if(a.CanPlayBoom(i)){
     30         a.PlayBoom(i);
     31         a.ResetCan();
     32         bool now=Play_Boom(b,a,i,0,1);
     33         if(!now){
     34             if(fir) Out_Boom(i);
     35             END;
     36         }
     37         a=_a;
     38     }
     39     NXT;
     40 }
     41 
     42 bool Play_Single(player a,player b,int last,bool fir,bool ok){
     43     if(b.empty()) return 0;
     44     player _a=a;
     45     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     46     for(int i=last+1;i<15;i++)
     47     if(a.CanPlaySingle(i)){
     48         a.PlaySingle(i);
     49         bool now=Play_Single(b,a,i,0,1);
     50         if(!now){
     51             if(fir) Out_Single(i);
     52             END;
     53         }
     54         a=_a;
     55     }
     56     NXT;
     57 }
     58 
     59 bool Play_Couple(player a,player b,int last,bool fir,bool ok){
     60     if(b.empty()) return 0;
     61     player _a=a;
     62     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     63     for(int i=last+1;i<13;i++)
     64     if(a.CanPlayCouple(i)){
     65         a.PlayCouple(i);
     66         bool now=Play_Couple(b,a,i,0,1);
     67         if(!now){
     68             if(fir) Out_Couple(i);
     69             END;
     70         }
     71         a=_a;
     72     }
     73     NXT;
     74 }
     75 
     76 bool Play_Three(player a,player b,int last,bool fir,bool ok){
     77     if(b.empty()) return 0;
     78     player _a=a;
     79     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     80     if(a.CanThree)
     81     for(int i=last+1;i<13;i++)
     82     if(a.CanPlayThree(i)){
     83         a.PlayThree(i);
     84         a.ResetCan();
     85         bool now=Play_Three(b,a,i,0,1);
     86         if(!now){
     87             if(fir) Out_Three(i);
     88             END;
     89         }
     90         a=_a;
     91     }
     92     NXT;
     93 }
     94 
     95 bool Play_3Single(player a,player b,int last,bool fir,bool ok){
     96     if(b.empty()) return 0;
     97     player _a=a;
     98     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     99     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
    100     if(a.CanThree)
    101     for(int j=0;j<15;j++)
    102     if(a.CanPlay3Single(i,j)){
    103         a.Play3Single(i,j);
    104         a.ResetCan();
    105         bool now=Play_3Single(b,a,i,0,1);
    106         if(!now){
    107             if(fir) Out_3Single(i,j);
    108             END;
    109         }
    110         a=_a;
    111     }
    112     NXT;
    113 }
    114 
    115 bool Play_3Couple(player a,player b,int last,bool fir,bool ok){
    116     if(b.empty()) return 0;
    117     player _a=a;
    118     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    119     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
    120     if(a.CanThree)
    121     for(int j=0;j<15;j++)
    122     if(a.CanPlay3Couple(i,j)){
    123         a.Play3Couple(i,j);
    124         a.ResetCan();
    125         bool now=Play_3Couple(b,a,i,0,1);
    126         if(!now){
    127             if(fir) Out_3Couple(i,j);
    128             END;
    129         }
    130         a=_a;
    131     }
    132     NXT;
    133 }
    134 
    135 bool Play_4Single(player a,player b,int last,bool fir,bool ok){
    136     if(b.empty()) return 0;
    137     player _a=a;
    138     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    139     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    140     if(a.CanBoom)
    141     for(int j=0;j<15;j++)
    142     for(int k=0;k<15;k++)
    143     if(a.CanPlay4Single(i,j,k)){
    144         a.Play4Single(i,j,k);
    145         a.ResetCan();
    146         bool now=Play_4Single(b,a,i,0,1);
    147         if(!now){
    148             if(fir) Out_4Single(i,j,k);
    149             END;
    150         }
    151         a=_a;
    152     }
    153     NXT;
    154 }
    155 
    156 bool Play_4Couple(player a,player b,int last,bool fir,bool ok){
    157     if(b.empty()) return 0;
    158     player _a=a;
    159     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    160     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    161     if(a.CanBoom)
    162     for(int j=0;j<15;j++)
    163     for(int k=0;k<15;k++)
    164     if(a.CanPlay4Couple(i,j,k)){
    165         a.Play4Couple(i,j,k);
    166         a.ResetCan();
    167         bool now=Play_4Couple(b,a,i,0,1);
    168         if(!now){
    169             if(fir) Out_4Couple(i,j,k);
    170             END;
    171         }
    172         a=_a;
    173     }
    174     NXT;
    175 }
    176 
    177 bool Play_MS(player a,player b,int l,int r,bool fir,bool ok){
    178     if(b.empty()) return 0;
    179     player _a=a; int pls=r-l;
    180     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    181     if(a.CanMS)
    182     for(int i=l+1;i+pls<=11;i++)
    183     if(a.CanPlayMoreSingle(i,i+pls)){
    184         a.PlayMoreSingle(i,i+pls);
    185         a.ResetCan();
    186         bool now=Play_MS(b,a,i,i+pls,0,1);
    187         if(!now){
    188             if(fir) Out_MS(i,i+pls);
    189             END;
    190         }
    191         a=_a;
    192     }
    193     NXT;
    194 }
    195 
    196 bool Play_MC(player a,player b,int l,int r,bool fir,bool ok){
    197     if(b.empty()) return 0;
    198     player _a=a; int pls=r-l;
    199     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    200     if(a.CanMC)
    201     for(int i=l+1;i+pls<=11;i++)
    202     if(a.CanPlayMoreCouple(i,i+pls)){
    203         a.PlayMoreCouple(i,i+pls);
    204         a.ResetCan();
    205         bool now=Play_MC(b,a,i,i+pls,0,1);
    206         if(!now){
    207             if(fir) Out_MC(i,i+pls);
    208             END;
    209         }
    210         a=_a;
    211     }
    212     NXT;
    213 }
    214 
    215 map<pair<long long,long long>,int> Visit;
    216 bool play(player a,player b,bool fir=0){
    217     if(b.empty()) return Visit[make_pair(a.Hash(),b.Hash())]=0;
    218     if(a.cnt+b.cnt<16&&fir==0){
    219         if(Visit.count(make_pair(a.Hash(),b.Hash())))
    220             return Visit[make_pair(a.Hash(),b.Hash())];
    221     }
    222     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    223     if(a.CanMS)
    224     for(int i=11;i>=4;i--){
    225         if(Play_MS(a,b,-1,-1+i,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    226     }
    227     if(a.CanMC)
    228     for(int i=8;i>=2;i--){
    229         if(Play_MC(a,b,-1,-1+i,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    230     }
    231     if(a.CanThree) if(Play_Three(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    232     if(a.CanThree) if(Play_3Single(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    233     if(a.CanThree) if(Play_3Couple(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    234     if(Play_Couple(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    235     if(Play_Single(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    236     if(a.CanBoom) if(Play_4Single(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    237     if(a.CanBoom) if(Play_4Couple(a,b,-1,fir,0)) return Visit[make_pair(a.Hash(),b.Hash())]=1;
    238     return Visit[make_pair(a.Hash(),b.Hash())]=0;
    239 }
    240 
    241 int Main(){
    242     Visit.clear();
    243     player a,b;
    244     printf("INPUT AI:
    ");
    245     b.read(); 
    246     printf("INPUT PLAYER:
    ");
    247     a.read();
    248     int staT=clock();
    249     if(!play(a,b,1)){
    250         printf("DIE
    ");
    251         return 0;
    252     }
    253     printf("
    First Time Use %dms
    ",clock()-staT);
    254     while(1){
    255         a=newA; b=newB;
    256         printf("
    ");
    257         if(a.empty()){
    258             printf("WIN
    ");
    259             return 0;
    260         }
    261         
    262         string now; cin>>now;
    263         if(now=="EXIT") return 0;
    264         if(Is_Empty(now)){
    265             if(!play(a,b,1)){
    266                 printf("DIE
    ");
    267             }
    268             continue;
    269         }
    270         for(int i=0;i<now.length();i++) b.PlaySingle(GetVal(now[i]));
    271         
    272         if(Is_Single(now)&&Play_Single(a,b,GetVal(now[0]),1,0)==0) NO;
    273         if(Is_Couple(now)&&Play_Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    274         if(Is_Three(now)&&Play_Three(a,b,GetVal(now[0]),1,0)==0) NO;
    275         if(Is_Boom(now)&&Play_Boom(a,b,GetVal(now[0]),1,0)==0) NO;
    276         if(Is_Rocket(now)&&Play_Rocket(a,b,1)==0) NO;
    277         if(Is_3Single(now)&&Play_3Single(a,b,GetVal(now[0]),1,0)==0) NO;
    278         if(Is_3Couple(now)&&Play_3Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    279         if(Is_4Single(now)&&Play_4Single(a,b,GetVal(now[0]),1,0)==0) NO;
    280         if(Is_4Couple(now)&&Play_4Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    281         if(Is_MS(now)&&Play_MS(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    282         if(Is_MC(now)&&Play_MC(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    283     }
    284 }
    285 
    286 int main(){
    287     while(1) Main();
    288 }
    main-v3.0
      1 /*
      2     ???????????????????
      3     ??
      4     ??????
      5 */ 
      6 
      7 #include<bits/stdc++.h>
      8 using namespace std;
      9 
     10 int GetVal(char c){
     11     if(c=='T') return 7;
     12     if(c=='J') return 8;
     13     if(c=='Q') return 9;
     14     if(c=='K') return 10;
     15     if(c=='A') return 11;
     16     if(c=='2') return 12;
     17     if(c=='w') return 13;
     18     if(c=='W') return 14;
     19     if('3'<=c&&c<='9') return c-'3';
     20     assert(0);
     21 }
     22 char SetChar(int x){
     23     if(x<=6) return '3'+x;
     24     if(x==7) return 'T';
     25     if(x==8) return 'J';
     26     if(x==9) return 'Q';
     27     if(x==10) return 'K';
     28     if(x==11) return 'A';
     29     if(x==12) return '2';
     30     if(x==13) return 'w';
     31     if(x==14) return 'W';
     32     assert(0);
     33 }
     34 
     35 struct player{
     36     int a[16],cnt; 
     37     bool CanThree,CanBoom,CanMS,CanMC;
     38     player(){memset(a,0,sizeof(a));cnt=0;}
     39     
     40     void out(){//Output Poker
     41         for(int i=0;i<16;i++) 
     42         for(int j=0;j<a[i];j++)
     43         putchar(SetChar(i));
     44         putchar('
    ');
     45     }
     46     
     47     inline bool CanPlaySingle(int x){return a[x]>=1;}//? 
     48     
     49     inline bool CanPlayCouple(int x){return a[x]>=2;}//? 
     50     
     51     inline bool CanPlayThree(int x){return a[x]>=3;}//?? 
     52     
     53     inline bool CanPlayBoom(int x){return a[x]>=4;}//?? 
     54     
     55     inline bool CanPlayRocket(){return a[13]&&a[14];}//?? 
     56     
     57     inline bool CanPlayMoreSingle(int l,int r){//?? 
     58         if(r-l+1<5||r>=12) return 0;
     59         for(int i=l;i<=r;i++) if(!CanPlaySingle(i)) return 0;
     60         return 1;
     61     }
     62     
     63     inline bool CanPlayMoreCouple(int l,int r){//?? 
     64         if(r-l+1<3||r>=12) return 0;
     65         for(int i=l;i<=r;i++) if(!CanPlayCouple(i)) return 0;
     66         return 1;
     67     }
     68     
     69     inline bool CanPlayMoreThree(int l,int r){//?? 
     70         if(r-l+1<2||r>=12) return 0;
     71         for(int i=l;i<=r;i++) if(!CanPlayThree(i)) return 0;
     72         return 1;
     73     }
     74     
     75     inline bool CanPlay4Single(int x,int l,int r){//??? 
     76         if(x==l||x==r) return 0;
     77         if(l==r) return CanPlayBoom(x)&&CanPlayCouple(l);
     78         return CanPlayBoom(x)&&CanPlaySingle(l)&&CanPlaySingle(r);
     79     }
     80     
     81     inline bool CanPlay4Couple(int x,int l,int r){//???
     82         if(x==l||x==r) return 0;
     83         if(l==r) return CanPlayBoom(x)&&CanPlayBoom(l);
     84         return CanPlayBoom(x)&&CanPlayCouple(l)&&CanPlayCouple(r);
     85     }
     86     
     87     inline bool CanPlay3Single(int x,int y){
     88         if(x==y) return 0;
     89         return CanPlayThree(x)&&CanPlaySingle(y);
     90     }
     91     
     92     inline bool CanPlay3Couple(int x,int y){
     93         if(x==y) return 0;
     94         return CanPlayThree(x)&&CanPlayCouple(y);
     95     }
     96     
     97     inline void PlaySingle(int x){a[x]--; cnt--;}
     98     
     99     inline void PlayCouple(int x){a[x]-=2; cnt-=2;}
    100     
    101     inline void PlayThree(int x){a[x]-=3; cnt-=3;}
    102     
    103     inline void PlayBoom(int x){a[x]-=4; cnt-=4;}
    104     
    105     inline void PlayRocket(){a[13]--;a[14]--; cnt-=2;}
    106     
    107     inline void PlayMoreSingle(int l,int r){for(int i=l;i<=r;i++) PlaySingle(i);}
    108     
    109     inline void PlayMoreCouple(int l,int r){for(int i=l;i<=r;i++) PlayCouple(i);}
    110     
    111     inline void PlayMoreThree(int l,int r){for(int i=l;i<=r;i++) PlayThree(i);}
    112     
    113     inline void Play4Single(int x,int l,int r){PlayBoom(x); PlaySingle(l); PlaySingle(r);}
    114     
    115     inline void Play4Couple(int x,int l,int r){PlayBoom(x); PlayCouple(l); PlayCouple(r);}
    116     
    117     inline void Play3Single(int x,int y){PlayThree(x); PlaySingle(y);}
    118     
    119     inline void Play3Couple(int x,int y){PlayThree(x); PlayCouple(y);}
    120     
    121     inline bool empty(){
    122         return cnt==0;
    123     }//?????? 
    124     
    125     inline long long Hash(){long long res=0; for(int i=0;i<16;i++) res=res<<2|a[i]; return res;}//??? 
    126     
    127     inline int GetMin(){for(int i=0;i<16;i++) if(a[i]) return i; assert(0);}
    128     inline int GetMax(){for(int i=13;~i;i--) if(a[i]) return i; return -1;}
    129     
    130     inline void ResetCan(){
    131         CanThree=CanBoom=CanMS=CanMC=0;//!!!
    132         for(int i=0;i<16;i++){
    133             if(CanPlayThree(i)) CanThree=1;
    134             if(CanPlayBoom(i)) CanBoom=1;
    135         }
    136         if(CanPlayRocket()) CanBoom=1; 
    137         for(int i=0;i<=7;i++){
    138             if(CanPlayMoreSingle(i,i+4)) {CanMS=1; break;}
    139         }
    140         for(int i=0;i<=9;i++){
    141             if(CanPlayMoreCouple(i,i+2)) {CanMC=1; break;}
    142         }
    143     }
    144     
    145     void read(){//Input Poker
    146         memset(a,0,sizeof(a)); cnt=0;
    147         string s; cin>>s; int len=s.length(); cnt=len;
    148         for(int i=0;i<len;i++)
    149         a[GetVal(s[i])]++;
    150         ResetCan();
    151     }
    152 };
    Player-v3.0

     3.0版本在双方牌数不大于15张时,基本可以在1s内出解

    (OFast编译,CPU:I5-4210M,辣鸡CPU)

    2019年4月16日更新:

    优化了分支判断速度,快了若干倍

    更新了main和player,helper无更新

      1 #include "Player-v2.0.cpp"
      2 #include "Helper.cpp"
      3 
      4 #define END {if(fir){newA=a; newB=b;} return 1;}
      5 #define NXT {if(ok&&play(b,a,0)==0) return 1; else return 0;}
      6 #define NO  {printf("Can't Out
    "); newA=a; newB=b;}
      7 player newA,newB;
      8 bool play(player,player,bool);
      9 
     10 bool Play_Rocket(player a,player b,bool fir){
     11     if(b.empty()) return 0;
     12     if(a.CanPlayRocket()){
     13         a.PlayRocket();
     14         bool now=play(a,b,0);
     15         if(now){
     16             if(fir) Out_Rocket();
     17             END;
     18         }
     19     }
     20     return 0;
     21 }
     22 
     23 bool Play_Boom(player a,player b,int last,bool fir,bool ok){
     24     if(b.empty()) return 0;
     25     if(Play_Rocket(a,b,fir)) return 1;
     26     player _a=a;
     27     if(a.CanBoom)
     28     for(int i=last+1;i<15;i++)
     29     if(a.CanPlayBoom(i)){
     30         a.PlayBoom(i);
     31         a.ResetCan();
     32         bool now=Play_Boom(b,a,i,0,1);
     33         if(!now){
     34             if(fir) Out_Boom(i);
     35             END;
     36         }
     37         a=_a;
     38     }
     39     NXT;
     40 }
     41 
     42 bool Play_Single(player a,player b,int last,bool fir,bool ok){
     43     if(b.empty()) return 0;
     44     player _a=a;
     45     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     46     for(int i=last+1;i<15;i++)
     47     if(a.CanPlaySingle(i)){
     48         a.PlaySingle(i);
     49         bool now=Play_Single(b,a,i,0,1);
     50         if(!now){
     51             if(fir) Out_Single(i);
     52             END;
     53         }
     54         a=_a;
     55     }
     56     NXT;
     57 }
     58 
     59 bool Play_Couple(player a,player b,int last,bool fir,bool ok){
     60     if(b.empty()) return 0;
     61     player _a=a;
     62     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     63     for(int i=last+1;i<13;i++)
     64     if(a.CanPlayCouple(i)){
     65         a.PlayCouple(i);
     66         bool now=Play_Couple(b,a,i,0,1);
     67         if(!now){
     68             if(fir) Out_Couple(i);
     69             END;
     70         }
     71         a=_a;
     72     }
     73     NXT;
     74 }
     75 
     76 bool Play_Three(player a,player b,int last,bool fir,bool ok){
     77     if(b.empty()) return 0;
     78     player _a=a;
     79     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     80     if(a.CanThree)
     81     for(int i=last+1;i<13;i++)
     82     if(a.CanPlayThree(i)){
     83         a.PlayThree(i);
     84         a.ResetCan();
     85         bool now=Play_Three(b,a,i,0,1);
     86         if(!now){
     87             if(fir) Out_Three(i);
     88             END;
     89         }
     90         a=_a;
     91     }
     92     NXT;
     93 }
     94 
     95 bool Play_3Single(player a,player b,int last,bool fir,bool ok){
     96     if(b.empty()) return 0;
     97     player _a=a;
     98     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
     99     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
    100     if(a.CanThree)
    101     for(int j=0;j<15;j++)
    102     if(a.CanPlay3Single(i,j)){
    103         a.Play3Single(i,j);
    104         a.ResetCan();
    105         bool now=Play_3Single(b,a,i,0,1);
    106         if(!now){
    107             if(fir) Out_3Single(i,j);
    108             END;
    109         }
    110         a=_a;
    111     }
    112     NXT;
    113 }
    114 
    115 bool Play_3Couple(player a,player b,int last,bool fir,bool ok){
    116     if(b.empty()) return 0;
    117     player _a=a;
    118     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    119     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
    120     if(a.CanThree)
    121     for(int j=0;j<15;j++)
    122     if(a.CanPlay3Couple(i,j)){
    123         a.Play3Couple(i,j);
    124         a.ResetCan();
    125         bool now=Play_3Couple(b,a,i,0,1);
    126         if(!now){
    127             if(fir) Out_3Couple(i,j);
    128             END;
    129         }
    130         a=_a;
    131     }
    132     NXT;
    133 }
    134 
    135 bool Play_4Single(player a,player b,int last,bool fir,bool ok){
    136     if(b.empty()) return 0;
    137     player _a=a;
    138     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    139     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    140     if(a.CanBoom)
    141     for(int j=0;j<15;j++)
    142     for(int k=0;k<15;k++)
    143     if(a.CanPlay4Single(i,j,k)){
    144         a.Play4Single(i,j,k);
    145     //    a.ResetCan();
    146         bool now=Play_4Single(b,a,i,0,1);
    147         if(!now){
    148             if(fir) Out_4Single(i,j,k);
    149             END;
    150         }
    151         a=_a;
    152     }
    153     NXT;
    154 }
    155 
    156 bool Play_4Couple(player a,player b,int last,bool fir,bool ok){
    157     if(b.empty()) return 0;
    158     player _a=a;
    159     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    160     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    161     if(a.CanBoom)
    162     for(int j=0;j<15;j++)
    163     for(int k=0;k<15;k++)
    164     if(a.CanPlay4Couple(i,j,k)){
    165         a.Play4Couple(i,j,k);
    166         a.ResetCan();
    167         bool now=Play_4Couple(b,a,i,0,1);
    168         if(!now){
    169             if(fir) Out_4Couple(i,j,k);
    170             END;
    171         }
    172         a=_a;
    173     }
    174     NXT;
    175 }
    176 
    177 bool Play_MS(player a,player b,int l,int r,bool fir,bool ok){
    178     if(b.empty()) return 0;
    179     player _a=a; int pls=r-l;
    180     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    181     if(a.CanMS)
    182     for(int i=l+1;i+pls<=11;i++)
    183     if(a.CanPlayMoreSingle(i,i+pls)){
    184         a.PlayMoreSingle(i,i+pls);
    185         a.ResetCan();
    186         bool now=Play_MS(b,a,i,i+pls,0,1);
    187         if(!now){
    188             if(fir) Out_MS(i,i+pls);
    189             END;
    190         }
    191         a=_a;
    192     }
    193     NXT;
    194 }
    195 
    196 bool Play_MC(player a,player b,int l,int r,bool fir,bool ok){
    197     if(b.empty()) return 0;
    198     player _a=a; int pls=r-l;
    199     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    200     if(a.CanMC)
    201     for(int i=l+1;i+pls<=11;i++)
    202     if(a.CanPlayMoreCouple(i,i+pls)){
    203         a.PlayMoreCouple(i,i+pls);
    204         a.ResetCan();
    205         bool now=Play_MC(b,a,i,i+pls,0,1);
    206         if(!now){
    207             if(fir) Out_MC(i,i+pls);
    208             END;
    209         }
    210         a=_a;
    211     }
    212     NXT;
    213 }
    214 
    215 bool play(player a,player b,bool fir=0){
    216     if(b.empty()) return 0;
    217     if(a.CanBoom) if(Play_Boom(a,b,-1,fir,0)) return 1;
    218     if(a.CanMS)
    219     for(int i=11;i>=4;i--){
    220         if(Play_MS(a,b,-1,-1+i,fir,0)) return 1;
    221     }
    222     if(a.CanMC)
    223     for(int i=8;i>=2;i--){
    224         if(Play_MC(a,b,-1,-1+i,fir,0)) return 1;
    225     }
    226     if(a.CanThree) if(Play_Three(a,b,-1,fir,0)) return 1;
    227     if(a.CanThree) if(Play_3Single(a,b,-1,fir,0)) return 1;
    228     if(a.CanThree) if(Play_3Couple(a,b,-1,fir,0)) return 1;
    229     if(Play_Couple(a,b,-1,fir,0)) return 1;
    230     if(Play_Single(a,b,-1,fir,0)) return 1;
    231     if(a.CanBoom) if(Play_4Single(a,b,-1,fir,0)) return 1;
    232     if(a.CanBoom) if(Play_4Couple(a,b,-1,fir,0)) return 1;
    233     return 0;
    234 }
    235 
    236 int Main(){
    237     player a,b;
    238     printf("INPUT AI:
    ");
    239     b.read(); 
    240     printf("INPUT PLAYER:
    ");
    241     a.read();
    242     if(!play(a,b,1)){
    243         printf("DIE
    ");
    244         return 0;
    245     }
    246     while(1){
    247         a=newA; b=newB;
    248         printf("
    ");
    249         if(a.empty()){
    250             printf("WIN
    ");
    251             return 0;
    252         }
    253         
    254         string now; cin>>now;
    255         if(now=="EXIT") return 0;
    256         if(Is_Empty(now)){
    257             if(!play(a,b,1)){
    258                 printf("DIE
    ");
    259             }
    260             continue;
    261         }
    262         for(int i=0;i<now.length();i++) b.PlaySingle(GetVal(now[i]));
    263         
    264         if(Is_Single(now)&&Play_Single(a,b,GetVal(now[0]),1,0)==0) NO;
    265         if(Is_Couple(now)&&Play_Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    266         if(Is_Three(now)&&Play_Three(a,b,GetVal(now[0]),1,0)==0) NO;
    267         if(Is_Boom(now)&&Play_Boom(a,b,GetVal(now[0]),1,0)==0) NO;
    268         if(Is_Rocket(now)&&Play_Rocket(a,b,1)==0) NO;
    269         if(Is_3Single(now)&&Play_3Single(a,b,GetVal(now[0]),1,0)==0) NO;
    270         if(Is_3Couple(now)&&Play_3Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    271         if(Is_4Single(now)&&Play_4Single(a,b,GetVal(now[0]),1,0)==0) NO;
    272         if(Is_4Couple(now)&&Play_4Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    273         if(Is_MS(now)&&Play_MS(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    274         if(Is_MC(now)&&Play_MC(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    275     }
    276 }
    277 
    278 int main(){
    279     while(1) Main();
    280 }
    main-v2.0
      1 /*
      2     ???????????????????
      3     ??
      4     ??????
      5 */ 
      6 
      7 #include<bits/stdc++.h>
      8 using namespace std;
      9 
     10 int GetVal(char c){
     11     if(c=='T') return 7;
     12     if(c=='J') return 8;
     13     if(c=='Q') return 9;
     14     if(c=='K') return 10;
     15     if(c=='A') return 11;
     16     if(c=='2') return 12;
     17     if(c=='w') return 13;
     18     if(c=='W') return 14;
     19     if('3'<=c&&c<='9') return c-'3';
     20     assert(0);
     21 }
     22 char SetChar(int x){
     23     if(x<=6) return '3'+x;
     24     if(x==7) return 'T';
     25     if(x==8) return 'J';
     26     if(x==9) return 'Q';
     27     if(x==10) return 'K';
     28     if(x==11) return 'A';
     29     if(x==12) return '2';
     30     if(x==13) return 'w';
     31     if(x==14) return 'W';
     32     assert(0);
     33 }
     34 
     35 struct player{
     36     int a[16]; 
     37     bool CanThree,CanBoom,CanMS,CanMC;
     38     player(){memset(a,0,sizeof(a));}
     39     
     40     void out(){//Output Poker
     41         for(int i=0;i<16;i++) 
     42         for(int j=0;j<a[i];j++)
     43         putchar(SetChar(i));
     44         putchar('
    ');
     45     }
     46     
     47     inline bool CanPlaySingle(int x){return a[x]>=1;}//? 
     48     
     49     inline bool CanPlayCouple(int x){return a[x]>=2;}//? 
     50     
     51     inline bool CanPlayThree(int x){return a[x]>=3;}//?? 
     52     
     53     inline bool CanPlayBoom(int x){return a[x]>=4;}//?? 
     54     
     55     inline bool CanPlayRocket(){return a[13]&&a[14];}//?? 
     56     
     57     inline bool CanPlayMoreSingle(int l,int r){//?? 
     58         if(r-l+1<5||r>=12) return 0;
     59         for(int i=l;i<=r;i++) if(!CanPlaySingle(i)) return 0;
     60         return 1;
     61     }
     62     
     63     inline bool CanPlayMoreCouple(int l,int r){//?? 
     64         if(r-l+1<3||r>=12) return 0;
     65         for(int i=l;i<=r;i++) if(!CanPlayCouple(i)) return 0;
     66         return 1;
     67     }
     68     
     69     inline bool CanPlayMoreThree(int l,int r){//?? 
     70         if(r-l+1<2||r>=12) return 0;
     71         for(int i=l;i<=r;i++) if(!CanPlayThree(i)) return 0;
     72         return 1;
     73     }
     74     
     75     inline bool CanPlay4Single(int x,int l,int r){//??? 
     76         if(x==l||x==r) return 0;
     77         if(l==r) return CanPlayBoom(x)&&CanPlayCouple(l);
     78         return CanPlayBoom(x)&&CanPlaySingle(l)&&CanPlaySingle(r);
     79     }
     80     
     81     inline bool CanPlay4Couple(int x,int l,int r){//???
     82         if(x==l||x==r) return 0;
     83         if(l==r) return CanPlayBoom(x)&&CanPlayBoom(l);
     84         return CanPlayBoom(x)&&CanPlayCouple(l)&&CanPlayCouple(r);
     85     }
     86     
     87     inline bool CanPlay3Single(int x,int y){
     88         if(x==y) return 0;
     89         return CanPlayThree(x)&&CanPlaySingle(y);
     90     }
     91     
     92     inline bool CanPlay3Couple(int x,int y){
     93         if(x==y) return 0;
     94         return CanPlayThree(x)&&CanPlayCouple(y);
     95     }
     96     
     97     inline void PlaySingle(int x){a[x]--;}
     98     
     99     inline void PlayCouple(int x){a[x]-=2;}
    100     
    101     inline void PlayThree(int x){a[x]-=3;}
    102     
    103     inline void PlayBoom(int x){a[x]-=4;}
    104     
    105     inline void PlayRocket(){a[13]--;a[14]--;}
    106     
    107     inline void PlayMoreSingle(int l,int r){for(int i=l;i<=r;i++) PlaySingle(i);}
    108     
    109     inline void PlayMoreCouple(int l,int r){for(int i=l;i<=r;i++) PlayCouple(i);}
    110     
    111     inline void PlayMoreThree(int l,int r){for(int i=l;i<=r;i++) PlayThree(i);}
    112     
    113     inline void Play4Single(int x,int l,int r){PlayBoom(x); PlaySingle(l); PlaySingle(r);}
    114     
    115     inline void Play4Couple(int x,int l,int r){PlayBoom(x); PlayCouple(l); PlayCouple(r);}
    116     
    117     inline void Play3Single(int x,int y){PlayThree(x); PlaySingle(y);}
    118     
    119     inline void Play3Couple(int x,int y){PlayThree(x); PlayCouple(y);}
    120     
    121     inline bool empty(){
    122         for(int i=0;i<16;i++) 
    123         if(a[i]) 
    124         return 0; 
    125     return 1;}//?????? 
    126     
    127     inline long long Hash(){long long res=0; for(int i=0;i<16;i++) res=res<<2|a[i]; return res;}//??? 
    128     
    129     inline int GetMin(){for(int i=0;i<16;i++) if(a[i]) return i; assert(0);}
    130     inline int GetMax(){for(int i=13;~i;i--) if(a[i]) return i; return -1;}
    131     
    132     inline void ResetCan(){
    133         CanThree=CanBoom=CanMS=CanMC=0;//!!!
    134         for(int i=0;i<16;i++){
    135             if(CanPlayThree(i)) CanThree=1;
    136             if(CanPlayBoom(i)) CanBoom=1;
    137         }
    138         if(CanPlayRocket()) CanBoom=1; 
    139         for(int i=0;i<=7;i++){
    140             if(CanPlayMoreSingle(i,i+4)) {CanMS=1; break;}
    141         }
    142         for(int i=0;i<=9;i++){
    143             if(CanPlayMoreCouple(i,i+2)) {CanMC=1; break;}
    144         }
    145     }
    146     
    147     void read(){//Input Poker
    148         memset(a,0,sizeof(a));
    149         string s; cin>>s; int len=s.length();
    150         for(int i=0;i<len;i++)
    151         a[GetVal(s[i])]++;
    152         ResetCan();
    153     }
    154 };
    Player-v2.0

    众所周知欢乐斗地主这个游戏有一个叫做残局的模式

    模式的特征:你和机器人都互相知道对方的牌,且对面的机器人绝顶聪明

    正常的斗地主规则,问你要如何出牌,才能保证你一定能赢。

    我们考虑直接爆搜,发现需要搜一年。

    于是我们加一个Alpha-Beta剪枝来加速整个爆搜过程即可。

    貌似绝大部分情况下都是秒出结果的

    目前最长时间只搜了15s(这是v2.0的时间,旧版貌似接近一分钟了)

    正确率100%,快速通关利器233333

    输入牌型要求:2~9直接输入,JQKA直接输入,10用T表示,大王小王分别用Ww表示。

    输入顺子/连对要从小到大输入(按照斗地主规则的从小到大),输入三带一/对,四带二/对,需要先输入三张/四张,再输入剩下的东西

    代码貌似只要10k多一点

    注意细节

    两个关联文件的代码:

     1 /*
     2     该部分函数用于输出打出的牌
     3     以及
     4     分析当前输入的牌型
     5     
     6 */ 
     7 
     8 inline void Out_Single(int x){printf("%c",SetChar(x));}
     9 
    10 inline void Out_Couple(int x){printf("%c%c",SetChar(x),SetChar(x));}
    11 
    12 inline void Out_Three(int x){printf("%c%c%c",SetChar(x),SetChar(x),SetChar(x));}
    13 
    14 inline void Out_Boom(int x){printf("%c%c%c%c",SetChar(x),SetChar(x),SetChar(x),SetChar(x));}
    15 
    16 inline void Out_3Single(int x,int y){Out_Three(x); Out_Single(y);}
    17 
    18 inline void Out_3Couple(int x,int y){Out_Three(x); Out_Couple(y);}
    19 
    20 inline void Out_MS(int l,int r){for(int i=l;i<=r;i++) Out_Single(i);}
    21 
    22 inline void Out_MC(int l,int r){for(int i=l;i<=r;i++) Out_Couple(i);}
    23 
    24 inline void Out_M3(int l,int r){for(int i=l;i<=r;i++) Out_Three(i);}
    25 
    26 inline void Out_Rocket(){printf("Ww");}
    27 
    28 inline void Out_4Single(int x,int l,int r){Out_Boom(x); Out_Single(l); Out_Single(r);}
    29 
    30 inline void Out_4Couple(int x,int l,int r){Out_Boom(x); Out_Couple(l); Out_Couple(r);}
    31 
    32 inline bool Is_Empty(string s){return s.length()==1&&s[0]=='*';}
    33 
    34 inline bool Is_Single(string s){return s.length()==1;}
    35 
    36 inline bool Is_Rocket(string s){return s=="Ww"||s=="wW";}
    37 
    38 inline bool Is_Couple(string s){return s.length()==2&&s[0]==s[1];}
    39 
    40 inline bool Is_Three(string s){return s.length()==3&&s[0]==s[1]&&s[1]==s[2];}
    41 
    42 inline bool Is_Boom(string s){return s.length()==4&&s[0]==s[1]&&s[1]==s[2]&&s[2]==s[3];}
    43 
    44 inline bool Is_3Single(string s){return s.length()==4&&s[0]==s[1]&&s[1]==s[2]&&s[2]!=s[3];}
    45 
    46 inline bool Is_3Couple(string s){return s.length()==5&&s[0]==s[1]&&s[1]==s[2]&&s[2]!=s[3]&&s[3]==s[4];}
    47 
    48 inline bool Is_MS(string s){
    49     int len=s.length(); if(len<5) return 0; 
    50     for(int i=1;i<len;i++) if(GetVal(s[i-1])+1!=GetVal(s[i])) return 0; 
    51     return 1;
    52 }
    53 
    54 inline bool Is_MC(string s){
    55     int len=s.length(); if((len&1)||len<6) return 0;
    56     for(int i=1;i<len;i+=2){
    57         if(s[i]!=s[i-1]) return 0;
    58     }
    59     for(int i=2;i<len;i+=2){
    60         if(GetVal(s[i-2])+1!=GetVal(s[i])) return 0;
    61     }
    62     return 1;
    63 }
    64 
    65 inline bool Is_4Single(string s){return s.length()==6&&s[0]==s[1]&&s[1]==s[2]&&s[2]==s[3]&&s[3]!=s[4];}
    66 
    67 inline bool Is_4Couple(string s){return s.length()==8&&s[0]==s[1]&&s[1]==s[2]&&s[2]==s[3]&&s[3]!=s[4]&&s[4]==s[5]&&s[6]==s[7];}
    Helper.cpp
      1 /*
      2     该部分函数用于判定是否可以出该类型的牌
      3     以及
      4     模拟出牌过程
      5 */ 
      6 
      7 #include<bits/stdc++.h>
      8 using namespace std;
      9 
     10 int GetVal(char c){
     11     if(c=='T') return 7;
     12     if(c=='J') return 8;
     13     if(c=='Q') return 9;
     14     if(c=='K') return 10;
     15     if(c=='A') return 11;
     16     if(c=='2') return 12;
     17     if(c=='w') return 13;
     18     if(c=='W') return 14;
     19     if('3'<=c&&c<='9') return c-'3';
     20     assert(0);
     21 }
     22 char SetChar(int x){
     23     if(x<=6) return '3'+x;
     24     if(x==7) return 'T';
     25     if(x==8) return 'J';
     26     if(x==9) return 'Q';
     27     if(x==10) return 'K';
     28     if(x==11) return 'A';
     29     if(x==12) return '2';
     30     if(x==13) return 'w';
     31     if(x==14) return 'W';
     32     assert(0);
     33 }
     34 
     35 struct player{
     36     int a[16]; 
     37     player(){memset(a,0,sizeof(a));}
     38     void read(){//Input Poker
     39         memset(a,0,sizeof(a));
     40         string s; cin>>s; int len=s.length();
     41         for(int i=0;i<len;i++)
     42         a[GetVal(s[i])]++;
     43     }
     44     
     45     void out(){//Output Poker
     46         for(int i=0;i<16;i++) 
     47         for(int j=0;j<a[i];j++)
     48         putchar(SetChar(i));
     49         putchar('
    ');
     50     }
     51     
     52     inline bool CanPlaySingle(int x){return a[x]>=1;}//
     53     
     54     inline bool CanPlayCouple(int x){return a[x]>=2;}//
     55     
     56     inline bool CanPlayThree(int x){return a[x]>=3;}//三张 
     57     
     58     inline bool CanPlayBoom(int x){return a[x]>=4;}//炸弹 
     59     
     60     inline bool CanPlayRocket(){return a[13]&&a[14];}//火箭 
     61     
     62     inline bool CanPlayMoreSingle(int l,int r){//顺子 
     63         if(r-l+1<5||r>=12) return 0;
     64         for(int i=l;i<=r;i++) if(!CanPlaySingle(i)) return 0;
     65         return 1;
     66     }
     67     
     68     inline bool CanPlayMoreCouple(int l,int r){//连对 
     69         if(r-l+1<3||r>=12) return 0;
     70         for(int i=l;i<=r;i++) if(!CanPlayCouple(i)) return 0;
     71         return 1;
     72     }
     73     
     74     inline bool CanPlayMoreThree(int l,int r){//飞机 
     75         if(r-l+1<2||r>=12) return 0;
     76         for(int i=l;i<=r;i++) if(!CanPlayThree(i)) return 0;
     77         return 1;
     78     }
     79     
     80     inline bool CanPlay4Single(int x,int l,int r){//四带二 
     81         if(x==l||x==r) return 0;
     82         if(l==r) return CanPlayBoom(x)&&CanPlayCouple(l);
     83         return CanPlayBoom(x)&&CanPlaySingle(l)&&CanPlaySingle(r);
     84     }
     85     
     86     inline bool CanPlay4Couple(int x,int l,int r){//四带对
     87         if(x==l||x==r) return 0;
     88         if(l==r) return CanPlayBoom(x)&&CanPlayBoom(l);
     89         return CanPlayBoom(x)&&CanPlayCouple(l)&&CanPlayCouple(r);
     90     }
     91     
     92     inline bool CanPlay3Single(int x,int y){
     93         if(x==y) return 0;
     94         return CanPlayThree(x)&&CanPlaySingle(y);
     95     }
     96     
     97     inline bool CanPlay3Couple(int x,int y){
     98         if(x==y) return 0;
     99         return CanPlayThree(x)&&CanPlayCouple(y);
    100     }
    101     
    102     inline void PlaySingle(int x){a[x]--;}
    103     
    104     inline void PlayCouple(int x){a[x]-=2;}
    105     
    106     inline void PlayThree(int x){a[x]-=3;}
    107     
    108     inline void PlayBoom(int x){a[x]-=4;}
    109     
    110     inline void PlayRocket(){a[13]--;a[14]--;}
    111     
    112     inline void PlayMoreSingle(int l,int r){for(int i=l;i<=r;i++) PlaySingle(i);}
    113     
    114     inline void PlayMoreCouple(int l,int r){for(int i=l;i<=r;i++) PlayCouple(i);}
    115     
    116     inline void PlayMoreThree(int l,int r){for(int i=l;i<=r;i++) PlayThree(i);}
    117     
    118     inline void Play4Single(int x,int l,int r){PlayBoom(x); PlaySingle(l); PlaySingle(r);}
    119     
    120     inline void Play4Couple(int x,int l,int r){PlayBoom(x); PlayCouple(l); PlayCouple(r);}
    121     
    122     inline void Play3Single(int x,int y){PlayThree(x); PlaySingle(y);}
    123     
    124     inline void Play3Couple(int x,int y){PlayThree(x); PlayCouple(y);}
    125     
    126     inline bool empty(){
    127         for(int i=0;i<16;i++) 
    128         if(a[i]) 
    129         return 0; 
    130     return 1;}//判断是否出完 
    131     
    132     inline long long Hash(){long long res=0; for(int i=0;i<16;i++) res=res<<2|a[i]; return res;}//哈希值 
    133     
    134     inline int GetMin(){for(int i=0;i<16;i++) if(a[i]) return i; assert(0);}
    135     inline int GetMax(){for(int i=13;~i;i--) if(a[i]) return i; return -1;}
    136 };
    Player.cpp

    主代码:

      1 #include "Player.cpp"
      2 #include "Helper.cpp"
      3 
      4 #define END {if(fir){newA=a; newB=b;} return 1;}
      5 #define NXT {if(ok&&play(b,a,0)==0) return 1; else return 0;}
      6 #define NO  {printf("Can't Out
    "); newA=a; newB=b;}
      7 player newA,newB;
      8 bool play(player,player,bool);
      9 
     10 bool Play_Rocket(player a,player b,bool fir){
     11     if(b.empty()) return 0;
     12     if(a.CanPlayRocket()){
     13         a.PlayRocket();
     14         bool now=play(a,b,0);
     15         if(now){
     16             if(fir) Out_Rocket();
     17             END;
     18         }
     19     }
     20     return 0;
     21 }
     22 
     23 bool Play_Boom(player a,player b,int last,bool fir,bool ok){
     24     if(b.empty()) return 0;
     25     if(Play_Rocket(a,b,fir)) return 1;
     26     player _a=a;
     27     for(int i=last+1;i<15;i++)
     28     if(a.CanPlayBoom(i)){
     29         a.PlayBoom(i);
     30         bool now=Play_Boom(b,a,i,0,1);
     31         if(!now){
     32             if(fir) Out_Boom(i);
     33             END;
     34         }
     35         a=_a;
     36     }
     37     NXT;
     38 }
     39 
     40 bool Play_Single(player a,player b,int last,bool fir,bool ok){
     41     if(b.empty()) return 0;
     42     player _a=a;
     43     if(Play_Boom(a,b,-1,fir,0)) return 1;
     44     for(int i=last+1;i<15;i++)
     45     if(a.CanPlaySingle(i)){
     46         a.PlaySingle(i);
     47         bool now=Play_Single(b,a,i,0,1);
     48         if(!now){
     49             if(fir) Out_Single(i);
     50             END;
     51         }
     52         a=_a;
     53     }
     54     NXT;
     55 }
     56 
     57 bool Play_Couple(player a,player b,int last,bool fir,bool ok){
     58     if(b.empty()) return 0;
     59     player _a=a;
     60     if(Play_Boom(a,b,-1,fir,0)) return 1;
     61     for(int i=last+1;i<13;i++)
     62     if(a.CanPlayCouple(i)){
     63         a.PlayCouple(i);
     64         bool now=Play_Couple(b,a,i,0,1);
     65         if(!now){
     66             if(fir) Out_Couple(i);
     67             END;
     68         }
     69         a=_a;
     70     }
     71     NXT;
     72 }
     73 
     74 bool Play_Three(player a,player b,int last,bool fir,bool ok){
     75     if(b.empty()) return 0;
     76     player _a=a;
     77     if(Play_Boom(a,b,-1,fir,0)) return 1;
     78     for(int i=last+1;i<13;i++)
     79     if(a.CanPlayThree(i)){
     80         a.PlayThree(i);
     81         bool now=Play_Three(b,a,i,0,1);
     82         if(!now){
     83             if(fir) Out_Three(i);
     84             END;
     85         }
     86         a=_a;
     87     }
     88     NXT;
     89 }
     90 
     91 bool Play_3Single(player a,player b,int last,bool fir,bool ok){
     92     if(b.empty()) return 0;
     93     player _a=a;
     94     if(Play_Boom(a,b,-1,fir,0)) return 1;
     95     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
     96     for(int j=0;j<15;j++)
     97     if(a.CanPlay3Single(i,j)){
     98         a.Play3Single(i,j);
     99         bool now=Play_3Single(b,a,i,0,1);
    100         if(!now){
    101             if(fir) Out_3Single(i,j);
    102             END;
    103         }
    104         a=_a;
    105     }
    106     NXT;
    107 }
    108 
    109 bool Play_3Couple(player a,player b,int last,bool fir,bool ok){
    110     if(b.empty()) return 0;
    111     player _a=a;
    112     if(Play_Boom(a,b,-1,fir,0)) return 1;
    113     for(int i=last+1;i<13;i++) if(a.CanPlayThree(i))
    114     for(int j=0;j<15;j++)
    115     if(a.CanPlay3Couple(i,j)){
    116         a.Play3Couple(i,j);
    117         bool now=Play_3Couple(b,a,i,0,1);
    118         if(!now){
    119             if(fir) Out_3Couple(i,j);
    120             END;
    121         }
    122         a=_a;
    123     }
    124     NXT;
    125 }
    126 
    127 bool Play_4Single(player a,player b,int last,bool fir,bool ok){
    128     if(b.empty()) return 0;
    129     player _a=a;
    130     if(Play_Boom(a,b,-1,fir,0)) return 1;
    131     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    132     for(int j=0;j<15;j++)
    133     for(int k=0;k<15;k++)
    134     if(a.CanPlay4Single(i,j,k)){
    135         a.Play4Single(i,j,k);
    136         bool now=Play_4Single(b,a,i,0,1);
    137         if(!now){
    138             if(fir) Out_4Single(i,j,k);
    139             END;
    140         }
    141         a=_a;
    142     }
    143     NXT;
    144 }
    145 
    146 bool Play_4Couple(player a,player b,int last,bool fir,bool ok){
    147     if(b.empty()) return 0;
    148     player _a=a;
    149     if(Play_Boom(a,b,-1,fir,0)) return 1;
    150     for(int i=last+1;i<13;i++) if(a.CanPlayBoom(i))
    151     for(int j=0;j<15;j++)
    152     for(int k=0;k<15;k++)
    153     if(a.CanPlay4Couple(i,j,k)){
    154         a.Play4Couple(i,j,k);
    155         bool now=Play_4Couple(b,a,i,0,1);
    156         if(!now){
    157             if(fir) Out_4Couple(i,j,k);
    158             END;
    159         }
    160         a=_a;
    161     }
    162     NXT;
    163 }
    164 
    165 bool Play_MS(player a,player b,int l,int r,bool fir,bool ok){
    166     if(b.empty()) return 0;
    167     player _a=a; int pls=r-l;
    168     if(Play_Boom(a,b,-1,fir,0)) return 1;
    169     for(int i=l+1;i+pls<=11;i++)
    170     if(a.CanPlayMoreSingle(i,i+pls)){
    171         a.PlayMoreSingle(i,i+pls);
    172         bool now=Play_MS(b,a,i,i+pls,0,1);
    173         if(!now){
    174             if(fir) Out_MS(i,i+pls);
    175             END;
    176         }
    177         a=_a;
    178     }
    179     NXT;
    180 }
    181 
    182 bool Play_MC(player a,player b,int l,int r,bool fir,bool ok){
    183     if(b.empty()) return 0;
    184     player _a=a; int pls=r-l;
    185     if(Play_Boom(a,b,-1,fir,0)) return 1;
    186     for(int i=l+1;i+pls<=11;i++)
    187     if(a.CanPlayMoreCouple(i,i+pls)){
    188         a.PlayMoreCouple(i,i+pls);
    189         bool now=Play_MC(b,a,i,i+pls,0,1);
    190         if(!now){
    191             if(fir) Out_MC(i,i+pls);
    192             END;
    193         }
    194         a=_a;
    195     }
    196     NXT;
    197 }
    198 
    199 bool play(player a,player b,bool fir=0){
    200     if(b.empty()) return 0;
    201     if(Play_Boom(a,b,-1,fir,0)) return 1;
    202     for(int i=11;i>=4;i--){
    203         if(Play_MS(a,b,-1,-1+i,fir,0)) return 1;
    204     }
    205     for(int i=8;i>=2;i--){
    206         if(Play_MC(a,b,-1,-1+i,fir,0)) return 1;
    207     }
    208     if(Play_Three(a,b,-1,fir,0)) return 1;
    209     if(Play_3Single(a,b,-1,fir,0)) return 1;
    210     if(Play_3Couple(a,b,-1,fir,0)) return 1;
    211     if(Play_Couple(a,b,-1,fir,0)) return 1;
    212     if(Play_Single(a,b,-1,fir,0)) return 1;
    213     if(Play_4Single(a,b,-1,fir,0)) return 1;
    214     if(Play_4Couple(a,b,-1,fir,0)) return 1;
    215     return 0;
    216 }
    217 
    218 int Main(){
    219     player a,b;
    220     printf("INPUT AI:
    ");
    221     b.read(); 
    222     printf("INPUT PLAYER:
    ");
    223     a.read();
    224     if(!play(a,b,1)){
    225         printf("DIE
    ");
    226         return 0;
    227     }
    228     while(1){
    229         a=newA; b=newB;
    230         printf("
    ");
    231         if(a.empty()){
    232             printf("WIN
    ");
    233             return 0;
    234         }
    235         
    236         string now; cin>>now;
    237         if(now=="EXIT") return 0;
    238         if(Is_Empty(now)){
    239             if(!play(a,b,1)){
    240                 printf("DIE
    ");
    241             }
    242             continue;
    243         }
    244         for(int i=0;i<now.length();i++) b.PlaySingle(GetVal(now[i]));
    245         
    246         if(Is_Single(now)&&Play_Single(a,b,GetVal(now[0]),1,0)==0) NO;
    247         if(Is_Couple(now)&&Play_Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    248         if(Is_Three(now)&&Play_Three(a,b,GetVal(now[0]),1,0)==0) NO;
    249         if(Is_Boom(now)&&Play_Boom(a,b,GetVal(now[0]),1,0)==0) NO;
    250         if(Is_Rocket(now)&&Play_Rocket(a,b,1)==0) NO;
    251         if(Is_3Single(now)&&Play_3Single(a,b,GetVal(now[0]),1,0)==0) NO;
    252         if(Is_3Couple(now)&&Play_3Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    253         if(Is_4Single(now)&&Play_4Single(a,b,GetVal(now[0]),1,0)==0) NO;
    254         if(Is_4Couple(now)&&Play_4Couple(a,b,GetVal(now[0]),1,0)==0) NO;
    255         if(Is_MS(now)&&Play_MS(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    256         if(Is_MC(now)&&Play_MC(a,b,GetVal(now[0]),GetVal(now[now.length()-1]),1,0)==0) NO;
    257     }
    258 }
    259 
    260 int main(){
    261     while(1) Main();
    262 }
  • 相关阅读:
    __declspec关键字详细用法
    【转载】前端面试“http全过程”将所有HTTP相关知识抛出来了...
    【转载】理解C语言中的关键字extern
    Linux应用环境实战
    【转载】深入解析连接点
    【转载】COM多线程原理与应用
    【转载】COM的多线程模型
    【转载】COM 连接点
    【转载】COM:IUnknown、IClassFactory、IDispatch
    101. Symmetric Tree
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10567207.html
Copyright © 2011-2022 走看看