//UVA220
#include<cstdio>
#include<cstdlib>
#include<cstring>
int posi[20][20], row = 8, column = 8;
int poss[20][20];//用来标识可行方案
char po[20][20];
char ch[60];//命令记录器
int flag = -1;//flag用来标记当前玩家是黑(1)or白(0)
void Output() {
for(int i = 1; i <= row; i++) {///
for(int j = 1; j <= row; j++) {///
if(j != 1) printf(" ");
if(posi[i][j] == -1) printf("-");
if(posi[i][j] == 0) printf("W");
if(posi[i][j] == 1) printf("B");
}
printf("\n\n");
}
}
int InRow(int x, int y) {//将x和y限制在1-8内
return x >= 1 && x <= row && y >= 1 && y <= row;
}
int Judge(int i, int j, int k, int l, int pos, int done, char ch) {//判断中间是否是棋子
int tmp, m, n;
if(ch == 'r') {//横行
if(j > l) {
tmp = j; j = l; l = tmp;
tmp = i; i = k; k = tmp;//交换位置,保持(i,j)在(k,l)左侧
}
for(m = j + 1; m < l; m++)
if(posi[i][m] != pos) break;
if(m == l) return 1;
else return 0;
}
if(ch == 'c') {//纵行
if(i > k) {
tmp = j; j = l; l = tmp;
tmp = i; i = k; k = tmp;
}
for(m = i + 1; m < k; m++)
if(posi[m][j] != pos) break;
if(m == k) return 1;
else return 0;
}
if(ch == 'd') {//斜行
//斜率为1
if((i - k) * (j - l) < 0) {
if(i < k) {
tmp = j; j = l; l = tmp;
tmp = i; i = k; k = tmp;
}
m = i; n = j;
while(--m != k && ++j != l)
if(posi[m][j] != pos) break;
if(m == k) return 1;
else return 0;
}
//斜率为-1
if((i - k) * (j - l) > 0) {
if(i < k) {
tmp = j; j = l; l = tmp;
tmp = i; i = k; k = tmp;
}
m = i; n = j;
while(--m != k && --j != l)
if(posi[m][j] != pos) break;
if(m == k) return 1;
else return 0;
}
}
}
int List(int a) {//当a为1时,带有打印功能,为0则不打印
memset(poss, 0, sizeof(poss));
int tag = 0;//tag用来标记是否可走
for(int i = 1; i <= row; i++) {
for(int j = 1; j <= row; j++) {
if(posi[i][j] != -1) continue;//寻找的位置必须为空位
for(int k = 1; k <= row; k++) {//寻找将要被bracket的棋子
for(int l = 1; l <= row; l++) {
int tap = 0;
if(posi[k][l] != !flag || posi[k][l] < 0 || poss[i][j]) continue;//flag代表当前进攻棋子,我们要寻找相异的棋子且可行落子位置没有被打印过
//横行判断
if(k == i) {
if(j > l && l > 1 && posi[k][l - 1] == flag) {
if(Judge(i, j, k, l, !flag, 0, 'r')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/} }
else if(j < l && l + 1 <= row && posi[k][l + 1] == flag){
if(Judge(i, j, k, l, !flag, 0, 'r')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
}
//纵行判断
else if(l == j) {
if(k > i && k + 1 <= row && flag == posi[k + 1][l]) {
if(Judge(i, j, k, l, !flag, 0, 'c')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
else if(k < i && k - 1 >= 1 && flag == posi[k - 1][l]){
if(Judge(i, j, k, l, !flag, 0, 'c')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
}
//对角线判断
else if(abs(i - k) == abs(j - l)) {//四种相对关系
if(k < i && l < j && k - 1 >= 1 && l - 1 >= 1 && posi[k - 1][l - 1] == flag) {//(k,l)在左上
if(Judge(i, j, k, l, !flag, 0, 'd')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}//Judge用来查看中间棋子是否均有棋子,最后一个参数为0,则只是查看,若非0,则要进行翻转操作
}
else if(k < i && l > j && k - 1 >= 1 && l + 1 <= row && posi[k - 1][l + 1] == flag) {//(k,l)在右上
if(Judge(i, j, k, l, !flag, 0, 'd')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
else if(k > i && l < j && k + 1 <= row && l - 1 >= 1 && posi[k + 1][l - 1] == flag) {//(k,l)在左下
if(Judge(i, j, k, l, !flag, 0, 'd')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
else if(k > i && l > j && k + 1 <= row && l + 1 <= row && posi[k + 1][l + 1] == flag) {//(k,l)在右下
if(Judge(i, j, k, l, !flag, 0, 'd')) {tap = 1; tag++; /*printf("tag = %d, (%d,%d), poss[%d][%d] = %d\n", tag, k, l, i, j, poss[i][j]);*/}
}
}
if(tap && tag > 1 && a) printf(" ");
if(tap && a && !poss[i][j]) printf("(%d,%d)", i, j);//防止被重复打印
if(tap) poss[i][j] = 1;
}
}
}
}
if(!tag && a) {printf("No legal move.");}//
if(a)printf("\n");
return tag;
}
void Move() {
int x = ch[1] - '0', y = ch[2] - '0';//(x, y)为将要走那一步的位置
int tag = List(0);//更新当前的可走位置
if(!poss[x][y]) flag = !flag;//当不可走时,转换为下一个玩家
//插入这枚棋,并将可bracket的地方反转
posi[x][y] = flag;
//printf("posi[%d][%d] = %d\n", x, y, posi[x][y]);
int i = x, j = y;
while(InRow(--x, y) && posi[x][y] == !flag);//1
if(InRow(x, y) && posi[x][y] == flag )
while(posi[++x][y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(--x, --y) && posi[x][y] == !flag );//2
if(InRow(x, y) && posi[x][y] == flag )
while(posi[++x][++y] == !flag){/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(x, --y) && posi[x][y] == !flag) ;//3
if(InRow(x, y) && posi[x][y] == flag )
while(posi[x][++y] == !flag){/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(++x, --y) && posi[x][y] == !flag ) ;//4
if(InRow(x, y) && posi[x][y] == flag )
while(posi[--x][++y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(++x, y) && posi[x][y] == !flag ) ;//5
if(InRow(x, y) && posi[x][y] == flag )
while(posi[--x][y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(++x, ++y) && posi[x][y] == !flag) ;//6
if(InRow(x, y) && posi[x][y] == flag )
while(posi[--x][--y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(x, ++y) && posi[x][y] == !flag) ;//7
if(InRow(x, y) && posi[x][y] == flag )
while(posi[x][--y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
while(InRow(--x, ++y) && posi[x][y] == !flag) ;//8
if(InRow(x, y) && posi[x][y] == flag )
while(posi[++x][--y] == !flag) {/*printf("********"); */posi[x][y] = flag;}//
x = i; y = j;
//统计黑白棋个数并打印
int countW = 0, countB = 0;
for(i = 1; i <= row; i++) {
for(j = 1; j <= row; j++) {
if(posi[i][j] == 0) countW++;
if(posi[i][j] == 1) countB++;
}
}
printf("Black - %2d White - %2d\n", countB, countW);
flag = !flag;
}
int main() {
//记录输入的数据
int N, count = 0;
while(scanf("%d", &N) == 1) {
getchar();
for(int k = 0; k < N; k++) {
if(count++) printf("\n");
memset(posi, 0, sizeof(posi));
memset(po, 0, sizeof(po));
for(int i = 1; i <= row; i++) fgets(po[i], sizeof(po), stdin);
//检查输入
for(int i = 1; i <= row; i++) {
for(int j = 1; j <= row; j++) {
if(po[i][j - 1] == '-') posi[i][j] = -1;
if(po[i][j - 1] == 'W') posi[i][j] = 0;
if(po[i][j - 1] == 'B') posi[i][j] = 1;//白棋为0,黑棋为1
}
}//输入完成
//逐个处理命令
while(1) {
fgets(ch, sizeof(ch), stdin);
if(ch[0] == 'Q') break;
if(ch[0] == 'W') flag = 0;
if(ch[0] == 'B') flag = 1;
if(ch[0] == 'L') List(1);//有输出数据的功能
if(ch[0] == 'M') Move();//有输出数据的功能
if(ch[0] == 'P') Output();
}
//输出数据
for(int i = 1; i <= row; i++) {///
for(int j = 1; j <= row; j++) {///
if(posi[i][j] == -1) printf("-");
if(posi[i][j] == 0) printf("W");
if(posi[i][j] == 1) printf("B");///
}
printf("\n");
}
}
}
return 0;
}
UVA220_Othello
最新推荐文章于 2020-05-20 18:53:44 发布