黑白棋

来源:互联网 发布:代域名备案 编辑:程序博客网 时间:2024/06/07 22:51

黑白棋是一种群众喜闻乐见的棋类游戏,双方各执黑白一色棋子,在 8 * 8 的棋盘上进行比赛(棋盘初始布局如下图),双方轮流下子,黑棋先手。

每次行动,玩家可以选择在棋盘中任意的有效格子处下子。在落子后,会进行八个方向的翻转操作。

翻转操作的过程是这样的:以刚放下的那颗棋子为中心(简称为中心棋子),在上、下、左、右、左上、左下、右上、右下八个射线方向内,分别寻找一个离中心棋子最近的己方颜色的棋子(简称为外侧棋子)。如果某个方向不存在外侧棋子,或者中心棋子和外侧棋子之间存在空白格子,或者中心棋子和外侧棋子直接相邻,则该方向是无效的,需要跳过。

如果一个翻转方向是有效的,则对其执行翻转操作,将中心棋子和外侧棋子之间的所有棋子都变成己方颜色的棋子。

而所谓的有效格子,则表示该格子是一个空白格子,并且在该格子处下子,至少有一个方向能出现有效翻转。

由于 Dr. Cat 和 Prof. Chi 的脑补水平已经达到正常人的 6 倍,他们下棋完全不需要棋盘,仅仅用语言就能在脑中进行对决。而作为一般人的 Kotomi,根本搞不清他们的 N 步操作之后会变成什么样的局面。所以 Kotomi 请求你,勇敢的少年,快用你的程序创造奇迹吧!


输入格式

一个整数 T,表示有多少组测试数据。

对于每组测试数据,第一行是一个整数 N (1 <= N <= 60),表示这局黑白棋当前已经下过了 N 步棋子。

接下来的 N 行,每一行给出一个数字 X (1 <= X <= 8) 和一个字符 Y ('A' <= Y <= 'H'),表示棋子落在的位置。这些棋子是按照从开局到结束的行动顺序依次给出的,数据保证所有操作都是合法操作,并且不存在某个人无法落子的情况。

输出格式

对于每组测试数据,输出最终的棋盘局面。黑子由 ‘#’ 表示,白子由 ‘*’ 表示,空白的格子由 ‘.’ 表示。棋盘的格子之间由一个空格隔开,棋盘的行号和列号也要输出。具体细节请参照样例,注意不要有多余的空白和换行符。

样例输入

225 F4 F65 F4 F3 E6 F5 G3 F

样例输出

  A B C D E F G H1 . . . . . . . .2 . . . . . . . .3 . . . . . . . .4 . . . * * * . .5 . . . # # # . .6 . . . . . . . .7 . . . . . . . .8 . . . . . . . .  A B C D E F G H1 . . . . . . . .2 . . . . . . . .3 . . . . # * . .4 . . . * # * . .5 . . . # # * # .6 . . . . . * . .7 . . . . . . . .8 . . . . . . . .

本人代码:

#include<stdio.h>#include<string.h>int a[9][9];int xis[]={-1,  1,  0,  0,  -1, -1,  1,   1};  //上,下,左,右,左上,坐下,右上,右下int yis[]={ 0,  0, -1,  1,  -1,  1,  -1,  1};void print(){int i,j;printf(" ");for(i=0;i<8;i++)printf(" %c",'A'+i);printf("\n");for(i=1;i<=8;i++){printf("%d",i);for(j=1;j<=8;j++)if(a[i][j]==1)printf(" #");else if(a[i][j]==-1)printf(" *");elseprintf(" .");printf("\n");}}//每走一步,执行的变换void translate(int X,int Y, bool black){int flag; //用于标记,当前是黑棋还是白棋if(black)flag=1;elseflag=-1;a[X][Y]=flag;//printf("a[%d][%d]:%d\n",X,Y,a[X][Y]);int i,xi,yi,tempX,tempY;for(i=0;i<8;i++) //遍历8个方向{  xi=xis[i];yi=yis[i];//printf("%d:%d方向搜索\n",xi,yi);tempX=X+xi;tempY=Y+yi;int count=0;  //用于计数,在xi,yi方向上走的步数while(tempX>=1 && tempY>=1 && a[tempX][tempY]==-flag) { //xi,yi方向上搜索;如果是和X,Y上棋子颜色相反的,就继续搜索count++;tempX+=xi;tempY+=yi;}//停止搜索时,如果遇到的是和X,Y上相同的棋子,就将(tempX,tempY)和(X,Y)之间的棋子,置为(X,Y)上的棋子if(tempX>=1 && tempY>=1 && a[tempX][tempY]==flag ){  //printf("%d:%d上有%d个变换\n",xi,yi,count);tempX-=xi;tempY-=yi;//循环条件用count,不能用注释中的,tempX,tempY是八个方向的,搜索停止时,不一定都满足(tempX<=X && tempY<=Y)while(count--)//while(tempX<=X && tempY<=Y), {a[tempX][tempY]=flag;tempX-=xi;    tempY-=yi;}}}}void getOneTest(){int N; //走的步数int X; //每一步走的棋子,char Y;memset(a,0,sizeof(a)); //初始化为0,黑棋1,白棋-1a[4][4]=-1;a[4][5]=1;a[5][4]=1;a[5][5]=-1;scanf("%d",&N);bool black=true;while(N--){scanf("%d %c",&X,&Y);Y=Y-'A'+1; //转换成坐标, 坐标从1开始,和棋盘对应translate(X,Y,black);black=!black;}print();}int main(){  int T;scanf("%d",&T);while(T--)getOneTest();}


0 0
原创粉丝点击