UVA220_Othello

//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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值