极大极小过程 UVA 10838 - The Pawn Chess

The pawns move as in ordinary chess, except that they can never move two steps. That is, a pawn may either move one step forward (toward the opposite rank), assuming that this square is empty. A pawn can also capture a pawn of the opposite color if it's one step ahead and to the left or right. Captured pieces are removed from the game.

Given the position of the pawns on a chessboard, determine who will win the game assuming both players play optimally. You should also determine the number of moves the game will last before it's decided (assuming the player that will win tries to win as fast as possible and the player to lose will lose as slow as possible). It will always be white's turn to move from the given position.

Input

The first line in the input contains the number of test cases (at most 50). Each case contains four lines describing the chessboard, preceeded by a blank line. The first of the four lines will be the last rank of the chessboard (the starting point for the black pawns). Black pawns will be denoted with a 'p', white pawns with a 'P', and empty squares with a '.'. There will be between one and four pawns of each color. The inital position will not be a final game position, and white will always have at least one legal move. Note that the input position may not necessarily be one that could have arisen from legal play from the games starting position.

 

Output

For each test case, output a line containing the text white (xx) if white will win, or black (xx) if black will win. Replace xx with the number of moves (which will always be an odd number if white wins and an even number if black wins).

 

Sample Input                                 Output for Sample Input

2
 
.ppp
....
.PPP
....
 
...p
...p
pP.P
...P
 
white (7)
black (2)

 

 

                     


Problem setter: Jimmy Mårdell 

Special Thanks: Md. Kamruzzaman


题意:有一个4x4的棋盘,上面有“小兵”,走法和国际象棋里面的兵一样,然后白棋的目标是让其中自己的其中一个棋子到最上面一行,黑棋的目标是到最后一行,或者让对方没有合法的移动。如果双方的足够聪明不会失误,一定能赢的人会尽可能快的赢,一定会输的人尽可能的不那么快输。问要多少步能得出结果。


思路:我们从开始状态一直搜索到结束状态,然后给局面一个分数,如果白棋赢,分数为inf-d ,反之为d-inf, 假设处于黑棋状态,如果他的所有状态都是负的,那么就表明黑棋其实已经输了,但是他还要尽可能拖下去,所以要选一个步数最大的状态,白棋同理。这个就是套一下alpha-beta的框架就行了。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string.h>
using namespace std;
const int inf = 1e8;
#define mp make_pair
struct State
{
	int isFinal()
	{
		for (int i = 0 ; i < 4 ; ++i) 
		{
			if (board[0][i]=='P') return 1;
			if (board[3][i]=='p') return 2;
		}
		return -1;
	}

	char board[5][5];
	void expand(int player,vector<State>& next)
	{
		if (player==0) {
			for (int i = 1 ; i < 4 ; ++i)
			{
				for (int j = 0 ; j < 4 ; ++j) if (board[i][j]=='P')
				{
					if (board[i-1][j]=='.') {
						State now = *this;
						now.board[i-1][j] = 'P';
						now.board[i][j] = '.';
						next.push_back(now);
					}
					if (j > 0 && board[i-1][j-1]=='p') {
						State now = *this;
						now.board[i-1][j-1] = 'P';
						now.board[i][j] = '.';
						next.push_back(now);
					}
					if (j < 3 && board[i-1][j+1]=='p') {
						State now = *this;
						now.board[i-1][j+1] = 'P';
						now.board[i][j] = '.';
						next.push_back(now);
					}
				}
			}
		}
		else {
			for (int i = 0 ; i < 3 ; ++i) 
			{
				for (int j = 0 ; j < 4 ; ++j) if (board[i][j]=='p')
				{
					if (board[i+1][j]=='.') {
						State now = *this;
						now.board[i+1][j] = 'p';
						now.board[i][j] = '.';
						next.push_back(now);
					}
					if (j<3&&board[i+1][j+1]=='P') {
						State now = *this;
						now.board[i+1][j+1] = 'p';
						now.board[i][j] = '.';
						next.push_back(now);
					}
					if (j>0&&board[i+1][j-1]=='P') {
						State now = *this;
						now.board[i+1][j-1] = 'p';
						now.board[i][j] = '.';
						next.push_back(now);
					}
				}
			}
		}
	}
};

int alphabeta(State & s,int player,int d,int alpha,int beta) 
{
	int ret = s.isFinal();
	if (ret==1) return inf-d;
	else if (ret==2) return -inf+d;
	vector<State> next;
	s.expand(player,next);
	if (next.size()==0) return player ? inf-d : -inf+d;
	int n = next.size();
	for (int i = 0 ; i < n ; ++i) {
		int ret = alphabeta(next[i],player^1,d+1,alpha,beta);
		if (!player) alpha = max(alpha,ret);
		else beta = min(beta,ret);
		if (beta <= alpha) break;
	}
	return player ? beta : alpha; 
}

int main()
{
	int T; cin>>T;
	while (T--) {
		State start;
		for (int i = 0 ; i < 4 ; ++i) scanf("%s",start.board[i]);
		int ret = alphabeta(start,0,0,-2*inf,2*inf);
		if (ret < 0) printf("black (%d)\n",ret+inf);
		else printf("white (%d)\n",-ret+inf);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值