Find the Winning Move
Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Description
4x4 tic-tac-toe is played on 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 are two players, x and o, who move alternately with x always going first. The game is won by the first player to get four of his or her pieces on the same row, column, or diagonal. If the board is full and neither player has won then the game is a draw.
Assuming that it is x’s turn to move, x is said to have a forced win if x can make a move such that no matter what moves o makes for the rest of the game, x can win. This does not necessarily mean that x will win on the very next move, although that is a possibility. It means that x has a winning strategy that will guarantee an eventual victory regardless of what o does.
Your job is to write a program that, given a partially-completed game with x to move next, will determine whether x has a forced win. You can assume that each player has made at least two moves, that the game has not already been won by either player, and that the board is 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 file. Each test case begins with a line containing a question mark and is followed by four lines representing the board; formatting is exactly as shown in the example. The characters used in a board description are 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 is determined by board position, 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 that order, and output the first forced win you find. In the second test case below, note that x could win immediately by playing at (0, 3) or (2, 0), but playing at (0, 1) will still ensure victory (although it unnecessarily delays it), and position (0, 1) comes first.
Sample Input
?
….
.xo.
.ox.
….
?
o…
.ox.
.xxx
xooo
$
Sample Output
(0,1)
a-b搜索是对极大极小搜索的剪枝优化,一般运用在下棋类博弈上。简而言之就是双方每轮最大可能扩大自己的优势,增加对方的劣势,在搜索的过程中a和b是两个常量分别表示双方的状态,每一层搜索都是a方或者b方的决策状态,a方需要将该层回溯的值最大,b方(为负值)则需要回溯最小(表示对方的优势最小,即自己优势最大),这样就可以将比这些值没有优势的搜索枝减掉。详细见http://blog.csdn.net/u013351484/article/details/50789521
框架可以照着这篇文章写。
#include
#include
#include
using namespace std;
char g[5][5];
int ansx;
int ansy;
int judge()//判断是否已赢
{
int i, j;
int xa = 0, xb = 0;
int ya = 0, yb = 0;
for(i = 0; i < 4; i++){
int ra = 0, rb = 0;
int ca = 0, cb = 0;
if(g[i][i] == 'x')
xa += 1;
else if(g[i][i] == 'o')
xb += 1;
if(g[i][3-i] == 'x')
ya += 1;
else if(g[i][3-i] == 'o')
yb += 1;
for(j = 0; j < 4; j++){
if(g[i][j] == 'x')
ra += 1;
else if(g[i][j] == 'o')
rb += 1;
if(g[j][i] == 'x')
ca += 1;
else if(g[j][i] == 'o')
cb += 1;
}
if(ra == 4 || ca == 4 || xa == 4 || ya == 4)
return 1;
else if(rb == 4 || cb == 4 || xb == 4 || yb == 4)
return -1;
}
return 0;
}
int alpha_beta(int player, int alpha, int beta)
{
int i, j;
int flag;
flag = judge();
if(flag)
return flag;
if(player){
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(g[i][j] == '.'){
int val;
g[i][j] = 'x';
val = alpha_beta(player^1, alpha, beta);
g[i][j] = '.';
if(val > alpha){
alpha = val;
ansy = i;
ansx = j;
}
if(alpha >= beta)
return alpha;
}
}
}
return alpha;
}
else{
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(g[i][j] == '.'){
int val;
g[i][j] = 'o';
val = alpha_beta(player^1, alpha, beta);
g[i][j] = '.';
if(val < beta)
beta = val;
if(alpha >= beta)
return beta;
}
}
}
return beta;
}
}
int main()
{
char od[2];
while(scanf("%s", od), od[0] != '$'){
int i, j;
int alpha = -1;
int beta = 1;
int ans;
int count = 0;
for(i = 0; i < 4; i++){
scanf("%s", g[i]);
for(j = 0; j < 4; j++)
if(g[i][j] != '.')
count++;
}
if(count < 5){
printf("#####\n");
continue;
}
ans = alpha_beta(1, alpha, beta);
if(ans > 0)
printf("(%d,%d)\n", ansy, ansx);
else
printf("#####\n");
}
return 0;
}