
注意:
1.输出格式注意 程序结束的结尾换行是否有多
2.输出黑白棋子数的时候数字%2d输出
3.边界值注意
4.打印所有合法点的时候两点之间有空格 最有一个点输出没有空格
#include <stdio.h>
#include <string.h>
const int maxn=10;
char board[maxn][maxn];//棋盘信息
int legal[maxn][maxn]; //落子合法位置
int direction[maxn];//八个方向,"米"字形,重左横开始,顺时针方向。
void printdirection(){
int i;
for(i=1;i<=8;i++)
printf("%d ",direction[i]);
printf("\n");
}
void printlist(){//打印可能位置
int i,j;
int count=0;
for(i=1;i<=8;i++){
for(j=1;j<=8;j++){
if(legal[i][j]==1){
count++;
if(count==1)
printf("(%d,%d)",i,j);
else//打印有效点的时候每个点之间都有空格,但是最后一个点后面不能有,果断修改,
printf(" (%d,%d)",i,j);
}
}
}
if(count==0)
printf("No legal move.");
printf("\n");
}
void list(char c,int row,int col){//枚举当前棋子的合法位置
char other;
int i,j;
if(c=='B')//确定当前棋子,与对手棋子
other='W';
else
other='B';
//“米”字形,八个方位,左横、上竖、右横、下竖、左上斜、右上斜、左下斜、右下斜
// 左横
i=row;
j=col;
while(j-1>=1&&board[i][j-1]==other)//趟过other棋子,有快速排序代码的一点痕迹
j--;
if(j!=col&&j-1>=1&&board[i][j-1]=='-'){
j--;
legal[i][j]=1;
}
//右横
i=row;
j=col;
while(j+1<=8&&board[i][j+1]==other)//趟过other棋子
j++;
if(j!=col&&j+1<=8&&board[i][j+1]=='-'){
j++;
legal[i][j]=1;
}
//上竖
i=row;
j=col;
while(i-1>=1&&board[i-1][j]==other)//趟过other棋子
i--;
if(i!=row&&i-1>=1&&board[i-1][j]=='-'){
i--;
legal[i][j]=1;
}
//下竖
i=row;
j=col;
while(i+1>=1&&board[i+1][j]==other)//趟过other棋子
i++;
if(i!=row&&i+1<=8&&board[i+1][j]=='-'){
i++;
legal[i][j]=1;
}
//左上斜
i=row;
j=col;
while(i-1>=1&&j-1>=1&&board[i-1][j-1]==other){//趟过other棋子
i--;
j--;
}
if(i!=row&&j!=col&&i-1>=1&&j-1>=1&&board[i-1][j-1]=='-'){
i--;
j--;
legal[i][j]=1;
}
//右下斜
i=row;
j=col;
while(i+1<=8&&j+1<=8&&board[i+1][j+1]==other){//趟过other棋子
i++;
j++;
}
if(i!=row&&j!=col&&i+1<=8&&j+1<=8&&board[i+1][j+1]=='-'){
i++;
j++;
legal[i][j]=1;
}
//右上斜
i=row;
j=col;
while(i-1>=1&&j+1<=8&&board[i-1][j+1]==other){
i--;
j++;
}
if(i!=row&&j!=col&&i-1>=1&&j+1<=8&&board[i-1][j+1]=='-'){
i--;
j++;
legal[i][j]=1;
}
//左下斜
i=row;
j=col;
while(i+1<=8&&j-1>=1&&board[i+1][j-1]==other){
i++;
j--;
}
if(i!=row&&j!=col&&i+1<=8&&j-1>=1&&board[i+1][j-1]=='-'){
i++;
j--;
legal[i][j]=1;
}
}
void enumdirection(char c,int row,int col){//枚举枚举落子的作用范围
char other;
int i,j;
memset(direction,0,sizeof(direction));//初始化方向
if(c=='B')//确定当前棋子,与对手棋子
other='W';
else
other='B';
//“米”字形,八个方位,左横、上竖、右横、下竖、左上斜、右上斜、左下斜、右下斜
// 左横 米 direction[1];
i=row;
j=col;
while(j-1>=1&&board[i][j-1]==other)//趟过other棋子,有快速排序代码的一点痕迹
j--;
if(j!=col&&j-1>=1&&board[i][j-1]==c){
j--;
direction[1]=1;
}
//右横 米 dirction[5]
i=row;
j=col;
while(j+1<=8&&board[i][j+1]==other)//趟过other棋子
j++;
if(j!=col&&j+1<=8&&board[i][j+1]==c){
j++;
direction[5]=1;
}
//上竖 米 dirction[3]
i=row;
j=col;
while(i-1>=1&&board[i-1][j]==other)//趟过other棋子
i--;
if(i!=row&&i-1>=1&&board[i-1][j]==c){
i--;
direction[3]=1;
}
//下竖 米 dirction[7]
i=row;
j=col;
while(i+1>=1&&board[i+1][j]==other)//趟过other棋子
i++;
if(i!=row&&i+1<=8&&board[i+1][j]==c){
i++;
direction[7]=1;
}
//左上斜 米 direction[2]
i=row;
j=col;
while(i-1>=1&&j-1>=1&&board[i-1][j-1]==other){//趟过other棋子
i--;
j--;
}
if(i!=row&&j!=col&&i-1>=1&&j-1>=1&&board[i-1][j-1]==c){
i--;
j--;
direction[2]=1;
}
//右下斜 米 direction[6]
i=row;
j=col;
while(i+1<=8&&j+1<=8&&board[i+1][j+1]==other){//趟过other棋子
i++;
j++;
}
if(i!=row&&j!=col&&i+1<=8&&j+1<=8&&board[i+1][j+1]==c){
i++;
j++;
direction[6]=1;
}
//右上斜 米 direction[4]
i=row;
j=col;
while(i-1>=1&&j+1<=8&&board[i-1][j+1]==other){
i--;
j++;
}
if(i!=row&&j!=col&&i-1>=1&&j+1<=8&&board[i-1][j+1]==c){
i--;
j++;
direction[4]=1;
}
//左下斜 米 direction[8]
i=row;
j=col;
while(i+1<=8&&j-1>=1&&board[i+1][j-1]==other){
i++;
j--;
}
if(i!=row&&j!=col&&i+1<=8&&j-1>=1&&board[i+1][j-1]==c){
i++;
j--;
direction[8]=1;
}
}
void setboard(char c,int row,int col){//根据落子布局棋盘
char other;
int i,j;
if(c=='B')//确定当前棋子,与对手棋子
other='W';
else
other='B';
board[row][col]=c;//安放落子
//“米”字形,八个方位,左横、上竖、右横、下竖、左上斜、右上斜、左下斜、右下斜
// 左横 米 direction[1];
if(direction[1]==1){
i=row;
j=col;
while(j-1>=1&&board[i][j-1]==other){//趟过other棋子,有快速排序代码的一点痕迹
j--;
board[i][j]=c;
}
if(j!=col&&j-1>=1&&board[i][j-1]==c){
j--;
}
}
//右横 米 dirction[5]
if(direction[5]==1){
i=row;
j=col;
while(j+1<=8&&board[i][j+1]==other){//趟过other棋子
j++;
board[i][j]=c;
}
if(j!=col&&j+1<=8&&board[i][j+1]==c){
j++;
}
}
//上竖 米 dirction[3]
if(direction[3]==1){
i=row;
j=col;
while(i-1>=1&&board[i-1][j]==other){//趟过other棋子
i--;
board[i][j]=c;
}
if(i!=row&&i-1>=1&&board[i-1][j]==c){
i--;
}
}
//下竖 米 dirction[7]
if(direction[7]==1){
i=row;
j=col;
while(i+1>=1&&board[i+1][j]==other){//趟过other棋子
i++;
board[i][j]=c;
}
if(i!=row&&i+1<=8&&board[i+1][j]==c){
i++;
}
}
//左上斜 米 direction[2]
if(direction[2]==1){
i=row;
j=col;
while(i-1>=1&&j-1>=1&&board[i-1][j-1]==other){//趟过other棋子
i--;
j--;
board[i][j]=c;
}
if(i!=row&&j!=col&&i-1>=1&&j-1>=1&&board[i-1][j-1]==c){
i--;
j--;
}
}
//右下斜 米 direction[6]
if(direction[6]==1){
i=row;
j=col;
while(i+1<=8&&j+1<=8&&board[i+1][j+1]==other){//趟过other棋子
i++;
j++;
board[i][j]=c;
}
if(i!=row&&j!=col&&i+1<=8&&j+1<=8&&board[i+1][j+1]==c){
i++;
j++;
}
}
//右上斜 米 direction[4]
if(direction[4]==1){
i=row;
j=col;
while(i-1>=1&&j+1<=8&&board[i-1][j+1]==other){
i--;
j++;
board[i][j]=c;
}
if(i!=row&&j!=col&&i-1>=1&&j+1<=8&&board[i-1][j+1]==c){
i--;
j++;
}
}
//左下斜 米 direction[8]
if(direction[8]==1){
i=row;
j=col;
while(i+1<=8&&j-1>=1&&board[i+1][j-1]==other){
i++;
j--;
board[i][j]=c;
}
if(i!=row&&j!=col&&i+1<=8&&j-1>=1&&board[i+1][j-1]==c){
i++;
j--;
}
}
}
void countboard(){
int i,j;
int Bcount=0,Wcount=0;
for(i=1;i<=8;i++){
for(j=1;j<=8;j++){
if(board[i][j]=='B')
Bcount++;
if(board[i][j]=='W')
Wcount++;
}
}
printf("Black - %2d White - %2d\n",Bcount,Wcount);
}
void setlegal(char player){//设置当前颜色棋子可行区域
int i,j;
memset(legal,0,sizeof(legal));//初始化合法区域,设置为0
for(i=1;i<=8;i++){//扫描字符为player的棋子
for(j=1;j<=8;j++){
if(board[i][j]==player)
list(player,i,j);
}
}
}
void printboard(){
int i,j;
for(i=1;i<=8;i++){
for(j=1;j<=8;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
int main(){
int T;
char line[10];
int i,j;
int row,col;
int blank=0;
char s[10];
char player;
scanf("%d",&T);
while(T--){//事例次数
if(blank>0)//打印例子间空行
printf("\n");
blank++;
memset(board,0,sizeof(board));
for(i=1;i<=8;i++){//读取棋盘信息
scanf("%s",line);
for(j=1;j<=8;j++){
board[i][j]=line[j-1];
}
}
scanf("%s",s);//读取当前落子颜色
player=s[0];
while(1){
scanf("%s",s);//读取当前棋盘操作
if(s[0]=='L'){
setlegal(player);
printlist();//打印可能位置
}else if(s[0]=='M'){//每次移动后,需要增加board数据,需要重设legal值
row=s[1]-'0';
col=s[2]-'0';
setlegal(player);//每次移动前,总要先查找合法放置区域,该句漏了,整整查了两天11.3-11.4,终于AC了,想到都是泪
if(legal[row][col]==1){//合法放置
enumdirection(player,row,col);//枚举可能放置方向
setboard(player,row,col);//根据落子,重新布局棋盘
countboard();//统计棋盘黑白棋个数
}else{//非法放置,另一种颜色棋子先走,从题意看,另一种颜色棋子一定能走成功
player=player=='B'?'W':'B';//改变当前落子颜色,第一次用三目运算符
setlegal(player);
enumdirection(player,row,col);//枚举可能放置方向
setboard(player,row,col);//根据落子,重新布局棋盘
countboard();//统计棋盘黑白棋个数
}
//每次移动后,先手自动交换颜色
player=player=='B'?'W':'B';
}else if(s[0]=='Q'){//退出当前事例
printboard();
break;
}
}
}
return 0;
}