Find the Winning Move
Time Limit: 3000MS |
|
Memory Limit: 32768K |
Total Submissions: 1286 |
|
Accepted: 626 |
Description
4x4 Tic-Tac-Toe is played in a board with four rows (numbered 0 to 3 from top to bottom) and four columns (numbered 0 to 3 From left to right). There is players, X and O, who moves alternately with X going first. The game is won by the first player to get a four of his or hers pieces on the same row, column, or diagonal. If the board is full and neither player have won then the game is a draw.
Assuming that it's X's turn to move, X's said to has a forced win if X can make a move such this no matter what moves O Makes for the rest of the game, X can win. This does isn't necessarily mean that X would win on the very next move, although a possibility. It means that X have a winning strategy that would guarantee an eventual victory regardless of what O does.
Your job is to write a program this, given a partially-completed game with X to move next, 'll determine whether X has a Forced win. You can assume so each player have made at least-moves, that's the game have not already been won by either player, and That the board are not full.
Input
The input contains one or more test cases, followed by a line beginning with a dollar sign that signals the end of the FIL E. Each test case begins with a line containing a question mark and are followed by four lines representing the board; Formatting is exactly as shown in the example. The characters used in a board description is the period (representing an empty space), lowercase x, and lowercase o. for Each test case, output a line containing the (row, column) position of the first forced win for X, or ' ##### ' if there is No forced win. Format the output exactly as shown in the example.
Output
For this problem, the first forced win was determined by board position and not the number of moves required for victory. Search for a forced win by examining positions (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), ..., (3, 2), (3, 3), in tha T order, and output the first forced win you find. In the second test case below, note this x could win immediately by playing at (0, 3) or (2, 0), but playing at (0, 1) Wil L still ensure victory (although it unnecessarily delays it), and position (0, 1) comes first.
Sample Input
?..... XO. Ox ...? O....ox. xxxxooo$
Sample Output
##### (0,1)
Source
Mid-Central USA 1999
#include <cstdio>using namespacestd;Chars[5][5];intChess,x,y;inlineintAbsintx) {returnX>0? x:-x;}BOOLCheckintXintY) {//Judging whether a situation is over inttot=0; for(intI=0;i<4; i++) s[x][i]=='o'? tot++:s[x][i]=='x'? tot--:tot;//Horizontal Judgment if(ABS (TOT) = =4)return 1; tot=0; for(intI=0;i<4; i++) s[i][y]=='o'? tot++:s[i][y]=='x'? tot--:tot;//longitudinal judgment if(ABS (TOT) = =4)return 1; tot=0; for(intI=0;i<4; i++) s[i][i]=='o'? tot++:s[i][i]=='x'? tot--:tot;//Positive Diagonal Judging if(ABS (TOT) = =4)return 1; tot=0; for(intI=0;i<4; i++) s[i][3-i]=='o'? tot++:s[i][3-i]=='x'? tot--:tot;//anti-diagonal judgment if(ABS (TOT) = =4)return 1; return 0;}intMin (int,int);intMax (int,int);intMax (intXinty) { if(check (x, y))return-1;//is over (the opponent wins) if(chess== -)return 0;//Draw for(intI=0,now;i<4; i++){ for(intj=0;j<4; j + +){ if(s[i][j]=='.') {S[i][j]='x'; chess++; now=Min (I,J); S[I][J]='.'; chess--; //the other side needs to find the worst estimate, if current is worse than before, α pruning if(now==1)return 1; } } } return-1;}intMin (intXinty) { if(check (x, y))return 1;//is over (win by yourself) if(chess== -)return 0; for(intI=0,now;i<4; i++){ for(intj=0;j<4; j + +){ if(s[i][j]=='.') {S[i][j]='o'; chess++; now=Max (I,J); S[I][J]='.'; chess--; //oneself need to find the highest valuation, if current is lower than the worst before, beta pruning if(!now| | now==-1)return-1; } } } return 1;}BOOLsolve () { for(intI=0,now;i<4; i++){ for(intj=0;j<4; j + +) {//enumeration, and then search if(s[i][j]=='.') {S[i][j]='x'; chess++; now=Min (I,J); S[I][J]='.'; chess--; if(now==1) {X=i; y=J; return 1; } } } } return 0;}intMain () {Charch[3]; while(~SCANF ("%s", ch) &&ch[0]=='?'){ for(intI=0;i<4; i++) scanf ("%s", S[i]); chess=0; for(intI=0;i<4; i++) for(intj=0;j<4; j + +) chess+=s[i][j]!='.'; if(chess<=4) {puts ("#####");Continue;}//must be a draw (the other side is very smart) if(Solve ()) printf ("(%d,%d) \ n", x, y); ElsePuts"#####"); } return 0;}
poj1568 Find the Winning move[Minimax search +alpha-beta Pruning]