1. 程式人生 > >POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC競賽訓練】

POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC競賽訓練】

目前 剪枝 find 最大 namespace row 競賽 move icpc

  1 #include<iostream>
  2 using namespace std;
  3 
  4 int row,col,chess;
  5 char board[5][5];
  6 
  7 int minSearch(int i,int j,int alpha);
  8 int maxSearch(int i,int j,int beta);
  9 
 10 
 11 bool check(int r,int c){
 12     if( board[r][0]==board[r][1] && board[r][1]==board[r][2
] && board[r][2]==board[r][3] && board[r][3]!=. ) return true; 13 if( board[0][c]==board[1][c] && board[1][c]==board[2][c] && board[2][c]==board[3][c] && board[3][c]!=. ) return true; 14 15 if( board[0][3]==board[1][2] && board[1][2]==board[2
][1] && board[2][1]==board[3][0] && board[0][3]==board[r][c] ) return true; 16 if( board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[2][2]==board[3][3] && board[0][0]==board[r][c] ) return true; 17 return false; 18 } 19 20 int minSearch(int i,int
j,int alpha){ //minsearch返回所有子結點中的【最小值】 alpha代表它父親兄弟結點的最大值 21 //上一步走在了(i,j),要判斷【這個棋子】能不能讓棋局結束 22 if( check(i,j) ) return 1;//x下完就結束了,x勝 23 if( chess==16 ) return 0; 24 25 26 27 28 int beta = 1;//這個裏面放所以子結點的最小值 == 因為是min結點 == 一開始得很大 29 for(int i=0;i<4;i++) 30 for(int j=0;j<4;j++) 31 if( board[i][j]==. ){ 32 board[i][j] = o; chess++; 33 34 beta = min(beta, maxSearch(i,j,beta) );//第三個參數是 == 目前min結點兄弟結點中的最小值 35 36 board[i][j] = .; chess--; 37 if( alpha>= beta ) return beta; 38 } 39 return beta; 40 } 41 42 int maxSearch(int i,int j,int beta){//beta是上一層兄弟結點中的最小值 43 if( check(i,j) ) return -1; 44 if( chess==16 ) return 0; 45 46 int alpha = -1;//記錄所有子結點中的最大值 47 for(int i=0;i<4;i++) 48 for(int j=0;j<4;j++) 49 if( board[i][j]==. ){ 50 board[i][j] = x; chess++; 51 52 alpha = max( alpha,minSearch(i,j,alpha) );//alpha是我兄弟結點的最大值 53 54 board[i][j] = .; chess--; 55 if( alpha>=beta ) return alpha; 56 } 57 return alpha; 58 } 59 60 61 62 bool solve(){ 63 64 int alpha=-1;//一開始最大值很小 == 根結點 == 根結點的子結點都剪不了 65 for(int i=0;i<4;i++) 66 for(int j=0;j<4;j++) 67 if( board[i][j]==. ){ 68 board[i][j] = x; chess++; 69 70 int tmp = minSearch(i,j,alpha);//第三個是alpha代表它兄弟結點的最大值 , 但root沒有兄弟節點 71 72 board[i][j] = .; chess--; 73 // cout<<i<<" "<<j<<" "<<tmp<<endl; 74 //cout<<i<<" "<<j<<endl; 75 if(tmp==1) { row=i; col=j; return true; } 76 } 77 78 return false; 79 } 80 81 82 int main(){ 83 84 85 while(1){ 86 chess=0; 87 char op; cin>>op; 88 if(op==$) break; 89 for(int i=0;i<4;i++) 90 for(int j=0;j<4;j++) { 91 cin>>board[i][j]; 92 if(board[i][j]!=.) chess++; 93 } 94 95 if( solve() ) cout<<"("<<row<<","<<col<<")"<<endl; 96 else cout<<"#####"<<endl; 97 } 98 99 100 }

POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC競賽訓練】