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\n"); 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:\n"); 245 b.read(); 246 printf("INPUT PLAYER:\n"); 247 a.read(); 248 int staT=clock(); 249 if(!play(a,b,1)){ 250 printf("DIE\n"); 251 return 0; 252 } 253 printf("\nFirst Time Use %dms\n",clock()-staT); 254 while(1){ 255 a=newA; b=newB; 256 printf("\n"); 257 if(a.empty()){ 258 printf("WIN\n"); 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\n"); 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 }