C++alpha beta剪枝算法 实现4*4 tic-tac-toe

先上一张alpha beta原理图,一看就懂

 

 

代码有点长,主要是因为算评估值得时候用的是穷举。 玩家是1,电脑是2,可以选择难度以及先手

  1 //
  2 //  main.cpp
  3 //  NEWTICTACTOE
  4 //
  5 //  Created by mac on 2017/5/1.
  6 //  Copyright © 2017年 mac. All rights reserved.
  7 //
  8 
  9 #include <iostream>
 10 #include <vector>
 11 #include <math.h>
 12 #include <cctype>
 13 #include <map>
 14 
 15 using namespace::std;
 16 vector<vector <int> > board(4 ,vector<int>(4,0));
 17 vector<vector <int> > boardvalues(4 ,vector<int>(4,99));
 18 int ALPHA =-1000;
 19 int BETA = 1000;
 20 int winner = -1;
 21 int searchDepth;
 22 bool isCutoffOccured = false;
 23 int maxDepthReached = 0;
 24 int totalNodesGenerated = 0;
 25 int pruningMax = 0;
 26 int pruningMin = 0;
 27 bool drawGame = false;
 28 
 29 int MaxValue(vector<vector <int> > board,int alpha,int beta,int depth);
 30 int MinValue(vector<vector <int> > board,int alpha,int beta,int depth);
 31 
 32 int get3PieceEval(vector<vector <int> > board){
 33     int PlayerScore = 0;
 34     int AIScore = 0;
 35     //row  score
 36     for(int i=0; i<4; i++){
 37         if ((board[i][0]==board[i][1])&&(board[i][0]==board[i][2])&&(board[i][3] == 0))//
 38         {
 39             if(board[i][0]==2)
 40                 AIScore += 6;
 41             if((board[i][0]==1)&&(board[i][3] == 0))
 42                 PlayerScore += 6;
 43         }
 44         if((board[i][0]==board[i][2])&&(board[i][0]==board[i][3])&&(board[i][1] == 0))
 45         {
 46             if(board[i][0]==2)
 47                 AIScore += 6;
 48             if(board[i][0]==1)
 49                 PlayerScore += 6;
 50         }
 51         if((board[i][0]==board[i][1])&&(board[i][0]==board[i][3])&&(board[i][2] ==0))
 52         {
 53             if(board[i][0]==2)
 54                 AIScore += 6;
 55             if(board[i][0]==1)
 56                 PlayerScore += 6;
 57         }
 58         if((board[i][1]==board[i][2])&&(board[i][1]==board[i][3])&&(board[i][0] ==0))
 59         {
 60             if(board[i][1]==2)
 61                 AIScore += 6;
 62             if(board[i][1]==1)
 63                 PlayerScore += 6;
 64         }
 65         
 66     }
 67     //col  score
 68     for(int i=0; i<4; i++){
 69         if ((board[0][i]==board[1][i])&&(board[0][i]==board[2][i])&&(board[3][i] ==0))//
 70         {
 71             if(board[0][i]==2)
 72                 AIScore += 6;
 73             if(board[0][i]==1)
 74                 PlayerScore += 6;
 75         }
 76         if((board[0][i]==board[2][i])&&(board[0][i]==board[3][i])&&(board[1][i] ==0))
 77         {
 78             if(board[0][i]==2)
 79                 AIScore += 6;
 80             if(board[0][i]==1)
 81                 PlayerScore += 6;
 82         }
 83         if((board[0][i]==board[1][i])&&(board[0][i]==board[3][i])&&(board[2][i] ==0))
 84         {
 85             if(board[0][i]==2)
 86                 AIScore += 6;
 87             if(board[0][i]==1)
 88                 PlayerScore += 6;
 89         }
 90         if((board[1][i]==board[2][i])&&(board[1][i]==board[3][i])&&(board[0][i] ==0))
 91         {
 92             if(board[1][i]==2)
 93                 AIScore += 6;
 94             if(board[1][i]==1)
 95                 PlayerScore += 6;
 96         }
 97         
 98     }
 99     //45 Diagnal  score
100     {
101         if((board[0][0]==board[1][1])&&(board[1][1]==board[2][2])&&(board[3][3] ==0))//
102         {
103             if(board[0][0]==2)
104                 AIScore += 6;
105             if(board[0][0]==1)
106                 PlayerScore += 6;
107         }
108         if((board[0][0]==board[2][2])&&(board[2][2]==board[3][3])&&(board[1][1] ==0))//
109         {
110             if(board[0][0]==2)
111                 AIScore += 6;
112             if(board[0][0]==1)
113                 PlayerScore += 6;
114         }
115         if((board[0][0]==board[1][1])&&(board[1][1]==board[3][3])&&(board[2][2] ==0))//
116         {
117             if(board[0][0]==2)
118                 AIScore += 6;
119             if(board[0][0]==1)
120                 PlayerScore += 6;
121         }
122         if((board[1][1]==board[2][2])&&(board[2][2]==board[3][3])&&(board[0][0] ==0))//
123         {
124             if(board[1][1]==2)
125                 AIScore += 6;
126             if(board[1][1]==1)
127                 PlayerScore += 6;
128         }
129         
130     }
131     //135 Diagnal  score
132     {
133         if((board[0][3]==board[1][2])&&(board[1][2]==board[2][1])&&(board[3][0] ==0))//
134         {
135             if(board[0][3]==2)
136                 AIScore += 6;
137             if(board[0][3]==1)
138                 PlayerScore += 6;
139         }
140         if((board[0][3]==board[1][2])&&(board[1][2]==board[3][0])&&(board[2][1] ==0))//
141         {
142             if(board[0][3]==2)
143                 AIScore += 6;
144             if(board[0][3]==1)
145                 PlayerScore += 6;
146         }
147         if((board[0][3]==board[2][1])&&(board[2][1]==board[3][0])&&(board[1][2] ==0))//
148         {
149             if(board[0][3]==2)
150                 AIScore += 6;
151             if(board[0][3]==1)
152                 PlayerScore += 6;
153         }
154         if((board[1][2]==board[2][1])&&(board[2][1]==board[3][0])&&(board[0][3] ==0))//
155         {
156             if(board[1][2]==2)
157                 AIScore += 6;
158             if(board[1][2]==1)
159                PlayerScore += 6;
160         }
161         
162     }
163     //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl;
164     return AIScore-PlayerScore;
165     
166 }
167 //calculaye 2 pieces in a line
168 int get2PieceEval(vector<vector <int> > board){
169     int PlayerScore = 0;
170     int AIScore = 0;
171     //row score
172     for(int i=0; i<4; i++){
173         if((board[i][0]==board[i][1])&&(board[i][3]==0)&&(board[i][2]==0))//
174         {
175             if(board[i][0]==2)
176                 AIScore += 3;
177             if(board[i][0]==1)
178                 PlayerScore += 3;
179         }
180         if((board[i][0]==board[i][2])&&(board[i][1]==0)&&(board[i][3]==0))
181         {
182             if(board[i][0]==2)
183                 AIScore += 3;
184             if(board[i][0]==1)
185                 PlayerScore += 3;
186         }
187         if((board[i][0]==board[i][3])&&(board[i][1]==0)&&(board[i][2]==0))
188         {
189             if(board[i][0]==2)
190                 AIScore += 3;
191             if(board[i][0]==1)
192                 PlayerScore += 3;
193         }
194         if((board[i][1]==board[i][2])&&(board[i][0]==0)&&(board[i][3]==0))
195         {
196             if(board[i][1]==2)
197                 AIScore += 3;
198             if(board[i][1]==1)
199                 PlayerScore += 3;
200         }
201         if((board[i][1]==board[i][3])&&(board[i][0]==0)&&(board[i][2]==0))
202         {
203             if(board[i][1]==2)
204                 AIScore += 3;
205             if(board[i][1]==1)
206                 PlayerScore += 3;
207         }
208         if((board[i][2]==board[i][3])&&(board[i][0]==0)&&(board[i][1]==0))
209         {
210             if(board[i][2]==2)
211                 AIScore += 3;
212             if(board[i][2]==1)
213                 PlayerScore += 3;
214         }
215         
216         
217     }
218     //col  score
219     for(int i=0; i<4; i++){
220         if((board[0][i]==board[1][i])&&(board[2][i]==0)&&(board[3][i]==0))//
221         {
222             if(board[0][i]==2)
223                 AIScore += 3;
224             if(board[0][i]==1)
225                 PlayerScore += 3;
226         }
227         if((board[0][i]==board[2][i])&&(board[1][i]==0)&&(board[3][i]==0))
228         {
229             if(board[0][i]==2)
230                 AIScore += 3;
231             if(board[0][i]==1)
232                 PlayerScore += 3;
233         }
234         if((board[0][i]==board[3][i])&&(board[1][i]==0)&&(board[2][i]==0))
235         {
236             if(board[0][i]==2)
237                 AIScore += 3;
238             if(board[0][i]==1)
239                 PlayerScore += 3;
240         }
241         if((board[1][i]==board[2][i])&&(board[0][i]==0)&&(board[3][i]==0))
242         {
243             if(board[1][i]==2)
244                 AIScore += 3;
245             if(board[1][i]==1)
246                 PlayerScore += 3;
247         }
248         if((board[1][i]==board[3][i])&&(board[0][i]==0)&&(board[2][i]==0))
249         {
250             if(board[1][i]==2)
251                 AIScore += 3;
252             if(board[1][i]==1)
253                PlayerScore += 3;
254         }
255         if((board[2][i]==board[3][i])&&(board[0][i]==0)&&(board[1][i]==0))
256         {
257             if(board[2][i]==2)
258                 AIScore += 3;
259             if(board[2][i]==1)
260                 PlayerScore += 3;
261         }
262         
263         
264     }
265     //45 Diagnal  score
266     {
267         if((board[0][0]==board[1][1])&&(board[2][2]==0)&&(board[3][3]==0))//
268         {
269             if(board[0][0]==2)
270                 AIScore += 3;
271             if(board[0][0]==1)
272                 PlayerScore += 3;
273         }
274         if((board[0][0]==board[2][2])&&(board[1][1]==0)&&(board[3][3]==0))//
275         {
276             if(board[0][0]==2)
277                 AIScore += 3;
278             if(board[0][0]==1)
279                 PlayerScore += 3;
280         }
281         if((board[0][0]==board[3][3])&&(board[1][1]==0)&&(board[2][2]==0))//
282         {
283             if(board[0][0]==2)
284                 AIScore += 3;
285             if(board[0][0]==1)
286                 PlayerScore += 3;
287         }
288         if((board[1][1]==board[2][2])&&(board[0][0]==0)&&(board[3][3]==0))//
289         {
290             if(board[1][1]==2)
291                 AIScore += 3;
292             if(board[1][1]==1)
293                 PlayerScore += 3;
294         }
295         if((board[1][1]==board[3][3])&&(board[0][0]==0)&&(board[2][2]==0))//
296         {
297             if(board[1][1]==2)
298                 AIScore += 3;
299             if(board[1][1]==1)
300                 PlayerScore += 3;
301         }
302         if((board[2][2]==board[3][3])&&(board[0][0]==0)&&(board[1][1]==0))//
303         {
304             if(board[2][2]==2)
305                 AIScore += 3;
306             if(board[2][2]==1)
307                 PlayerScore += 3;
308         }
309         
310     }
311     //135 Diagnal  score
312     {
313         if((board[0][3]==board[1][2])&&(board[2][1]==0)&&(board[3][0]==0))//
314         {
315             if(board[0][3]==2)
316                 AIScore += 3;
317             if(board[0][3]==1)
318                 PlayerScore += 3;
319         }
320         if((board[0][3]==board[2][1])&&(board[1][2]==0)&&(board[3][0]==0))//
321         {
322             if(board[0][3]==2)
323                 AIScore += 3;
324             if(board[0][3]==1)
325                 PlayerScore += 3;
326         }
327         if((board[0][3]==board[3][0])&&(board[1][2]==0)&&(board[2][1]==0))//
328         {
329             if(board[0][3]==2)
330                 AIScore += 3;
331             if(board[0][3]==1)
332                 PlayerScore += 3;
333         }
334         if((board[1][2]==board[2][1])&&(board[0][3]==0)&&(board[3][0]==0))//
335         {
336             if(board[1][2]==2)
337                 AIScore += 3;
338             if(board[1][2]==1)
339                PlayerScore += 3;
340         }
341         if((board[1][2]==board[3][0])&&(board[0][3]==0)&&(board[2][1]==0))//
342         {
343             if(board[1][2]==2)
344                 AIScore += 3;
345             if(board[1][2]==1)
346                 PlayerScore += 3;
347         }
348         if((board[2][1]==board[3][0])&&(board[0][3]==0)&&(board[1][2]==0))//
349         {
350             if(board[1][2]==2)
351                 AIScore += 3;
352             if(board[1][2]==1)
353                 PlayerScore += 3;
354         }
355         
356     }
357     //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl;
358     return AIScore-PlayerScore;
359 }
360 //calculaye 1 piece score in a line
361 int get1PieceEval(vector<vector <int> > board){
362     int PlayerScore = 0;
363     int AIScore = 0;
364     for(int i=0; i<4; i++){
365         if (board[i][1]==0 && board[i][2]==0 && board[i][3]==0 )//
366         {
367             if(board[i][0]==1){
368                 PlayerScore++;
369                 //cout<<"player add score row at"<<i<<" 0"<<endl;
370             }
371             if(board[i][0]==2){
372                 AIScore++;
373                 //cout<<"AI add score row at"<<i<<" 0"<<endl;
374             }
375         }
376         if (board[i][0]==0 && board[i][2]==0 && board[i][3]==0 )//
377         {
378             if(board[i][1]==1){
379                 PlayerScore++;
380                 //cout<<"player add score at"<<i<<" 1"<<endl;
381             }
382             if(board[i][1]==2){
383                 AIScore++;
384                 //cout<<"AI add score row at"<<i<<" 1"<<endl;
385             }
386         }
387         if (board[i][0]==0 && board[i][1]==0 && board[i][2]==0 )//
388         {
389             if(board[i][3]==1){
390                 PlayerScore++;
391                 //cout<<"player add score at"<<i<<" 2"<<endl;
392             }
393             if(board[i][3]==2){
394                 AIScore++;
395                 //cout<<"AI add score row at"<<i<<" 2"<<endl;
396             }
397         }
398         if (board[i][0]==0 && board[i][1]==0 && board[i][3]==0 )//
399         {
400             if(board[i][2]==1){
401                 PlayerScore++;
402                 //cout<<"player add score at"<<i<<" 3"<<endl;
403             }
404             if(board[i][2]==2){
405                 AIScore++;
406                 //cout<<"AI add score row at"<<i<<" 3"<<endl;
407             }
408         }
409     }
410     
411     for(int i=0; i<4; i++){
412         if (board[1][i]==0 && board[2][i]==0 && board[3][i]==0 )//
413         {
414             if(board[0][i]==1){
415                 PlayerScore++;
416                 //cout<<"player add score col at"<<"0 "<<i<<endl;
417             }
418             if(board[0][i]==2){
419                 AIScore++;
420                 //cout<<"AI add score col at"<<"0 "<<i<<endl;
421             }
422         }
423         if (board[0][i]==0 && board[2][i]==0 && board[3][i]==0 )//
424         {
425             if(board[1][i]==1){
426                 PlayerScore++;
427                 //cout<<"player add score at"<<"1 "<<i<<endl;
428             }
429             if(board[1][i]==2){
430                 AIScore++;
431                 //cout<<"AI add score col at"<<"1 "<<i<<endl;
432             }
433         }
434         if (board[0][i]==0 && board[1][i]==0 && board[2][i]==0 )//
435         {
436             if(board[3][i]==1){
437                 PlayerScore++;
438                 //cout<<"player add score at"<<"3 "<<i<<endl;
439             }
440             if(board[3][i]==2){
441                 AIScore++;
442                 //cout<<"AI add score col at"<<"3 "<<i<<endl;
443             }
444         }
445         if (board[0][i]==0 && board[1][i]==0 && board[3][i]==0 )//
446         {
447             if(board[2][i]==1){
448                 PlayerScore++;
449                 //cout<<"player add score at"<<"2 "<<i<<endl;
450             }
451             if(board[2][i]==2){
452                 AIScore++;
453                 //cout<<"AI add score col at"<<"2 "<<i<<endl;
454             }
455         }
456     }
457     //diagnal 45
458     {
459         if (board[0][0]==0 && board[1][1]==0 && board[2][2]==0 )//
460         {
461             if(board[3][3]==1){
462                 PlayerScore++;
463                 //cout<<"player add score at"<<"3 "<<"3"<<endl;
464             }
465             if(board[3][3]==2){
466                 AIScore++;
467                 //cout<<"AI add score 45 at"<<"3 "<<"3"<<endl;
468             }
469         }
470         if (board[0][0]==0 && board[2][2]==0 && board[3][3]==0 )//
471         {
472             if(board[1][1]==1){
473                 PlayerScore++;
474                 //cout<<"player add score at"<<"1 "<<"1"<<endl;
475                 
476             }
477             if(board[1][1]==2){
478                 AIScore++;
479                 //cout<<"AI add score 45 at"<<"1 "<<"1"<<endl;
480             }
481         }
482         if (board[0][0]==0 && board[1][1]==0 && board[3][3]==0 )//
483         {
484             if(board[2][2]==1){
485                 PlayerScore++;
486                 //cout<<"player add score at"<<"2 "<<"2"<<endl;
487                 
488             }
489             if(board[2][2]==2){
490                 AIScore++;
491                 //cout<<"AI add score 45 at"<<"2 "<<"2"<<endl;
492             }
493         }
494         if (board[1][1]==0 && board[2][2]==0 && board[3][3]==0 )//
495         {
496             if(board[0][0]==1){
497                 PlayerScore++;
498                 //cout<<"player add score at"<<"0 "<<"0"<<endl;
499                 
500             }
501             if(board[0][0]==2){
502                 AIScore++;
503                 //cout<<"AI add score 45 at"<<"0 "<<"0"<<endl;
504             }
505         }
506         
507     }
508     
509     {
510         if (board[0][3]==0 && board[1][2]==0 && board[2][1]==0 )//
511         {
512             if(board[3][0]==1){
513                 PlayerScore++;
514                 //cout<<"player add score at"<<"3 "<<"0"<<endl;
515                 
516             }
517             if(board[3][0]==2){
518                 AIScore++;
519                 //cout<<"AI add score 135 at"<<"3 "<<"0"<<endl;
520             }
521         }
522         if (board[0][3]==0 && board[1][2]==0 && board[3][0]==0 )//
523         {
524             if(board[2][1]==1){
525                 PlayerScore++;
526                 //cout<<"player add score at"<<"2 "<<"1"<<endl;
527                 
528             }
529             if(board[2][1]==2){
530                 AIScore++;
531                 //cout<<"AI add score 135 at"<<"2 "<<"1"<<endl;
532             }
533         }
534         if (board[0][3]==0 && board[2][1]==0 && board[3][0]==0 )//
535         {
536             if(board[1][2]==1){
537                 PlayerScore++;
538                 //cout<<"player add score at"<<"1 "<<"2"<<endl;
539                 
540             }
541             if(board[1][2]==2){
542                 AIScore++;
543                 //cout<<"AI add score 135 at"<<"1 "<<"2"<<endl;
544             }
545         }
546         if (board[1][2]==0 && board[2][1]==0 && board[3][0]==0 )//
547         {
548             if(board[0][3]==1){
549                 PlayerScore++;
550                 //cout<<"player add score at"<<"0 "<<"3"<<endl;
551                 
552             }
553             if(board[0][3]==2){
554                 AIScore++;
555                 //cout<<"AI add score 135 at"<<"0 "<<"3"<<endl;
556             }
557         }
558         
559     }
560     //cout<<"get1PieceEval"<<AIScore-PlayerScore<<endl;
561     return AIScore-PlayerScore;
562 }
563 //get evaluate score
564 int GetEvals(vector<vector <int> > board){
565     int result = 0;
566     result = get3PieceEval(board) + get2PieceEval(board) + get1PieceEval(board);
567     return result;
568 }
569 //print current board
570 void print_board(vector<vector <int> > board){
571     cout<<"-----------------"<<endl;
572     for(int i = 0; i<4 ;i++){
573         cout<<"|";
574         for(int j = 0; j<4 ;j++){
575             cout<<" "<<board[i][j]<<" ";
576             cout<<"|";
577         }
578         cout<<endl;
579         cout<<"-----------------"<<endl;
580     }
581 }
582 //check if game end
583 bool Terminal_Test(vector<vector <int> > board){
584     //row check
585     for(int i=0; i<4; i++){
586         if ((board[i][0]!=0)&&(board[i][0]==board[i][1])&&(board[i][1]==board[i][2])&&(board[i][2]==board[i][3]))//
587         {
588             winner = board[i][0];
589             //cout<<"row winnner:"<<winner<<endl;
590             return true;
591         }
592     }
593     //col check
594     for(int j=0; j<4; j++){
595         if ((board[0][j]!=0)&&(board[0][j]==board[1][j])&&(board[1][j]==board[2][j])&&(board[2][j]==board[3][j]))//
596         {
597             winner = board[0][j];
598             //cout<<"col winnner:"<<winner<<endl;
599             return true;
600         }
601     }
602     //diagnal check
603     if((board[0][0]!=0)&&(board[0][0]==board[1][1])&&(board[1][1]==board[2][2])&&(board[2][2]==board[3][3]))//
604     {
605         winner = board[0][0];
606         //cout<<"diagnal winnner:"<<winner<<endl;
607         return true;
608     }
609     if((board[0][3]!=0)&&(board[0][3]==board[1][2])&&(board[1][2]==board[2][1])&&(board[2][1]==board[3][0]))//
610     {
611         winner = board[0][3];
612         //cout<<"diagnal winnner:"<<winner<<endl;
613         return true;
614     }
615     for(int m = 0 ;m< 4 ;m++){
616         for(int n =0; n< 4; n++){
617             if(board[m][n]==0){ //is there an empty position?
618                 winner = -1;
619                 return false;
620             }
621         }
622     }
623     winner = 0;
624     //cout<<"full board no winner"<<endl;
625     return true;;
626 }
627 
628 vector<int> findPlaceable(vector<vector <int> > board){
629     vector<int> position;
630     for(int i=0; i< 4;i++){
631         for(int j=0; j<4;j++){
632             if(board[i][j]==0){
633                 position.push_back(i*4+j);
634             }
635         }
636     }
637     return position;
638 }
639 
640 int MaxValue(vector<vector <int> > board,int alpha,int beta,int depth){
641     //cout<<"depth"<<depth<<endl;
642     //print_board(board);
643     if(Terminal_Test(board))
644     {
645         if (winner == 0){
646             drawGame = true;
647             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
648             //cout<<"game end draw game"<<endl;
649             return 0;
650         }
651         else if (winner == 1){
652             drawGame = false;
653             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
654             //cout<<"game end player win"<<endl;
655             return -1000;
656         }
657         else{
658             drawGame = false;
659             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
660             //cout<<"game end AI win"<<endl;
661             return 1000;
662         }
663     }
664     //game not end
665     if(depth==0)
666     {
667         //cout<<"cutoff happened"<<endl;
668         maxDepthReached = searchDepth;
669         isCutoffOccured = true;
670         return GetEvals(board);
671     }
672     else{
673         drawGame = false;
674         int v = INT_MIN;
675         map<int,int> posScoreMap;
676         vector<int> avaliablePos = findPlaceable(board);
677         
678         for(int i = 0; i<avaliablePos.size(); i++){
679             int row,col;
680             row = avaliablePos[i]/4;
681             col = avaliablePos[i]%4;
682             board[row][col] = 2;
683             //cout<<"enter minvalue func"<<endl;
684             totalNodesGenerated++;
685             posScoreMap[avaliablePos[i]] = MinValue(board, alpha, beta, depth-1);
686             //cout<<"back to maxvalue func,"<<"returned value is:"<<posScoreMap[avaliablePos[i]]<<endl;
687             //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl;
688             board[row][col] = 0;
689             v =max(posScoreMap[avaliablePos[i]],v);
690             if (v>=beta){
691                 //cout<<"new v>=beta pruning happen"<<endl;
692                 pruningMax++;
693                 return v;
694             }
695             alpha = max(alpha, v);
696             //cout<<"new v is:"<<v<<" new alpha is:"<<alpha<<endl;
697         }
698         return v;
699     }
700 }
701 
702 int MinValue(vector<vector <int> > board,int alpha,int beta,int depth){
703     //cout<<"depth"<<depth<<endl;
704     //print_board(board);
705     if(Terminal_Test(board))
706     {
707         if (winner == 0){
708             drawGame = true;
709             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
710             //cout<<"game end draw game"<<endl;
711             return 0;
712         }
713         else if (winner == 1){
714             drawGame = false;
715             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
716             //cout<<"game end player win"<<endl;
717             return -1000;
718         }
719         else{
720             drawGame = false;
721             maxDepthReached = maxDepthReached>(searchDepth-depth) ? maxDepthReached:(searchDepth-depth);
722             //cout<<"game end AI win"<<endl;
723             return 1000;
724         }
725     }
726     //game not end
727     if(depth==0)
728     {
729         maxDepthReached = searchDepth;
730         isCutoffOccured = true;
731         //cout<<"cutoff happened"<<endl;
732         return GetEvals(board);
733     }
734     else{
735         drawGame = false;
736         int v = INT_MAX;
737         map<int,int> posScoreMap;
738         vector<int> avaliablePos = findPlaceable(board);
739         
740         for(int i = 0; i<avaliablePos.size(); i++){
741             int row,col;
742             row = avaliablePos[i]/4;
743             col = avaliablePos[i]%4;
744             board[row][col] = 1;
745             //cout<<"enter maxvalue func"<<endl;
746             totalNodesGenerated++;
747             posScoreMap[avaliablePos[i]] = MaxValue(board, alpha, beta, depth-1);
748             //cout<<"back to minvalue func,"<<"returned value is:"<<posScoreMap[avaliablePos[i]]<<endl;
749             //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl;
750             board[row][col] = 0;
751             v =min(posScoreMap[avaliablePos[i]],v);
752             if (v<=alpha){
753                 //cout<<"new v<=alpha pruning happen"<<endl;
754                 pruningMin++;
755                 return v;
756             }
757             beta = min(beta, v);
758             //cout<<"new v is:"<<v<<" new beta is:"<<beta<<endl;
759         }
760         return v;
761     }
762 }
763 
764 int Alpha_Beta_Search(){
765     cout<<"enter alphabeta search"<<endl;
766     int move,alpha,beta,bestScore;
767     vector<int> avaliablePos;
768     map<int,int> posScoreMap; //move, score
769     int v = INT_MIN;
770     
771     alpha = ALPHA;
772     beta = BETA;
773     avaliablePos = findPlaceable(board);
774     for(int i = 0; i<avaliablePos.size(); i++){
775         int row,col;
776         row = avaliablePos[i]/4;
777         col = avaliablePos[i]%4;
778         board[row][col] = 2;
779         totalNodesGenerated++;
780         posScoreMap[avaliablePos[i]] = MinValue(board, alpha, beta, searchDepth-1);
781         board[row][col] = 0;
782         boardvalues[row][col] = posScoreMap[avaliablePos[i]];
783         //cout<<"get score on position:"<<avaliablePos[i]<<"is:"<<posScoreMap[avaliablePos[i]]<<endl;
784         //cout<<"alpha is:"<<alpha<<" beta is:"<<beta<<" v is:"<<v<<endl;
785         v =max(posScoreMap[avaliablePos[i]],v);
786         if (v>=beta){
787             //cout<<"new v>=beta pruning happen"<<endl;
788             pruningMax++;
789             return avaliablePos[i];
790         }
791         alpha = max(alpha, v);
792         //cout<<"new v is:"<<v<<" new alpha is:"<<alpha<<endl;
793     }
794     
795     move = avaliablePos[0];
796     bestScore = posScoreMap[move];
797     for (map<int,int>::iterator it=posScoreMap.begin(); it!=posScoreMap.end(); ++it){
798         if(it->second > bestScore){
799             bestScore = it->second;
800             move = it->first;
801         }
802     }
803     
804     if(isCutoffOccured)
805         cout<<"Cutoff Occured: "<< "true"<<endl;
806     else
807         cout<<"Cutoff Occured: "<< "false"<<endl;
808     cout<<"max Depth Reached: "<< maxDepthReached<<endl;
809     cout<<"------------------------------------------------------------"<<endl;
810     cout<<"total Nodes Generated: "<< totalNodesGenerated<<endl;
811     cout<<"------------------------------------------------------------"<<endl;
812     cout<<"pruning in Max func: "<< pruningMax<<endl;
813     cout<<"------------------------------------------------------------"<<endl;
814     cout<<"pruning in Min func: "<< pruningMin<<endl;
815     cout<<"------------------------------------------------------------"<<endl;
816     cout<<"Max Search Depth: "<< searchDepth<<endl;
817     cout<<"------------------------------------------------------------"<<endl;
818     isCutoffOccured = false;
819     maxDepthReached = 0;
820     totalNodesGenerated = 0;
821     pruningMax = 0;
822     pruningMin = 0;
823 
824     
825     cout<<"score board:"<<endl;
826     print_board(boardvalues);
827     for(int i =0;i<4;i++){
828         for(int j=0;j<4;j++){
829             boardvalues[i][j]=99;
830         }
831     }
832     return move;
833 }
834 
835 
836 int main(int argc, const char * argv[]) {
837     //board[0][0] = 1;
838     //board[1][0] = 1;
839     //board[2][0] = 1;
840     //board[3][0] = 2;
841     //board[0][3] = 2;
842     //print_board(board);
843     cout<<"**************************************"<<endl;
844     cout<<"        Welcome To Tic-Tac-Toe        "<<endl;
845     cout<<"**************************************"<<endl;
846     cout<<endl;
847     cout<<endl;
848     cout<<endl;
849     int difficulty;
850     bool firstMove=true;
851     
852     cout<<"Please select difficulty:(1.easy 2.intermediate 3.difficult)"<<endl;
853     cout<<"------------------------------------------------------------"<<endl;
854     cin >> difficulty;
855     
856     int firstmove=0;
857     cout<<"Do you want to move first:(1.yes 2.no)"<<endl;
858     cout<<"------------------------------------------------------------"<<endl;
859     cin >> firstmove;
860     //3 levels difficulty matches 3 search depth;
861     switch (difficulty){
862         case 1:
863             searchDepth = 3;
864             break;
865         case 2:
866             searchDepth = 5;
867             break;
868         case 3:
869             searchDepth = 7;
870             break;
871     }
872     //determine if player want to move first
873     switch (firstmove){
874         case 1:
875             firstMove = true;
876             break;
877         case 2:
878             firstMove = false;
879             break;
880     }
881     
882      if(firstMove){
883          while(1){
884              int row,col;
885              cout<<"Enter your Move:(format: a b, a is row b is col)"<<endl;
886              cout<<"------------------------------------------------------------"<<endl;
887              cin>>row>>col;
888              cout<<"your move is row: "<<row<<" and col: "<<col<<endl;
889              cout<<"------------------------------------------------------------"<<endl;
890              board[row][col] = 1;
891              print_board(board);
892              if(Terminal_Test(board))
893              {
894                  if(winner == 1){
895                      cout<< "You Win!"<<endl;
896                      break;
897                  }
898                  else{
899                      cout<< "Draw Game!"<<endl;
900                      break;
901                  }
902              }
903              int AIMove = Alpha_Beta_Search();
904              cout<<"AI move is row: "<<AIMove/4<<" and col: "<<AIMove%4<<endl;
905              cout<<"------------------------------------------------------------"<<endl;
906              board[AIMove/4][AIMove%4] = 2;
907              print_board(board);
908              if(Terminal_Test(board))
909              {
910                  if(!drawGame){
911                      cout<< "Computer Win!"<<endl;
912                      break;
913                  }
914                  else{
915                      cout<< "Draw Game!"<<endl;
916                      break;
917                  }
918              }
919          }
920      }
921      else{
922          while(1)
923          {
924              int row,col;
925              int AIMove = Alpha_Beta_Search();
926              cout<<"AI move is row: "<<AIMove/4<<" and col: "<<AIMove%4<<endl;
927              cout<<"------------------------------------------------------------"<<endl;
928              board[AIMove/4][AIMove%4] = 2;
929              print_board(board);
930              if(Terminal_Test(board))
931              {
932                  if(!drawGame){
933                      cout<< "Computer Win!"<<endl;
934                      break;
935                  }
936                  else{
937                      cout<< "Draw Game!"<<endl;
938                      break;
939                  }
940              }
941              cout<<"Enter your Move:(format: a b, a is row b is col)"<<endl;
942              cout<<"------------------------------------------------------------"<<endl;
943              cin>>row>>col;
944              cout<<"your move is row: "<<row<<" and col: "<<col<<endl;
945              cout<<"------------------------------------------------------------"<<endl;
946              board[row][col] = 1;
947              print_board(board);
948              if(Terminal_Test(board))
949              {
950                  if(winner == 1){
951                      cout<< "You Win!"<<endl;
952                      break;
953                  }
954                  else{
955                      cout<< "Draw Game!"<<endl;
956                      break;
957                  }
958              }
959          }
960      }
961     
962     return 0;
963 }

 

 

运行截图:

 

posted @ 2017-05-02 06:25  熊阳  阅读(1303)  评论(0编辑  收藏  举报