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 }
main-v3.0

相关文章: