POJ 2996 Help Me with the Game

该博客主要介绍了如何解析一个给定的棋盘图,并按特定规则输出棋子的位置。通过遍历棋盘并模拟国际象棋的规则,程序能够正确地识别和排序各种棋子,包括国王、女王、车、主教、骑士和小卒。对于白色棋子,位置按照行号从小到大排列,黑色棋子则相反。输出结果清晰地展示了每种棋子在棋盘上的位置。
摘要由CSDN通过智能技术生成

题干

描述

给一个棋盘的图,要求描述棋子的位置。

输入

一个棋盘的图,具体看样例,棋子是“K”(国王)、“Q”(女王)、“R”(车)、“B”(主教)、“N”(骑士)或“P”(小卒)。

输出

棋子的位置,具体看样例,很好理解:第一行是白子,第二行是黑子。后面的可以理解为<name><y><x>。“K”(国王)、“Q”(女王)、“R”(车)、“B”(主教)、“N”(骑士),后面的字母代表列标,随后的数字表示行。需要注意的是小卒不需要名称字段。由于每种棋子可能有多枚(国际象棋的奇怪规则,升变),排序规则如下:
如果棋子是白色的,则行号较小的棋子必须在另一个之前描述,如果棋子是黑色的,则必须先描述行号较大的棋子.如果相同类型的两块出现在同一行中,则列字母较小的必须先出现。

样例输入

+---+---+---+---+---+---+---+---+
|.r.|:::|.b.|:q:|.k.|:::|.n.|:r:|
+---+---+---+---+---+---+---+---+
|:p:|.p.|:p:|.p.|:p:|.p.|:::|.p.|
+---+---+---+---+---+---+---+---+
|...|:::|.n.|:::|...|:::|...|:p:|
+---+---+---+---+---+---+---+---+
|:::|...|:::|...|:::|...|:::|...|
+---+---+---+---+---+---+---+---+
|...|:::|...|:::|.P.|:::|...|:::|
+---+---+---+---+---+---+---+---+
|:P:|...|:::|...|:::|...|:::|...|
+---+---+---+---+---+---+---+---+
|.P.|:::|.P.|:P:|...|:P:|.P.|:P:|
+---+---+---+---+---+---+---+---+
|:R:|.N.|:B:|.Q.|:K:|.B.|:::|.R.|
+---+---+---+---+---+---+---+---+

样例输出

White: Ke1,Qd1,Ra1,Rh1,Bc1,Bf1,Nb1,a2,c2,d2,f2,g2,h2,a3,e4
Black: Ke8,Qd8,Ra8,Rh8,Bc8,Ng8,Nc6,a7,b7,c7,d7,e7,f7,h7,h6

解题

思路

模拟,硬着头皮写就是了。需要注意的是在遍历棋盘的时候不需要挨个找,跳着找就可以了,只有第1,3,5…行可能有棋子,只有第2,6,10…列可能有棋子。
还有一个大坑,White:后面是跟了一个空格的。幸亏我这种输出习惯性扔到文本比较里面看了一眼,不然就被坑了。
还有poj的编译器版本比较低,不支持直接在结构体里给变量赋值。

代码

#include <stdio.h>
#include <algorithm>
#include <memory>

using namespace std;

struct positions{
  int x ;
  int y ;
};

bool cmp1(positions a , positions b){
  if (a.x > b.x)
    return 0;
  else if (a.x == b.x && a.y > b.y)
    return 0;
  else
    return 1;
}

bool cmp2(positions a , positions b){
  if (a.x < b.x)
    return 0;
  else if (a.x == b.x && a.y > b.y)
    return 0;
  else
    return 1;
}

int getnum(char &c){
  if (c > 'a'-1){
    c = c + 'A' - 'a';
  }
  switch (c){
    case 'K':
      return 0;
    case 'Q':
      return 1;
    case 'R':
      return 2;
    case 'B':
      return 3;
    case 'N':
      return 4;
    case 'P':
      return 5;
  }
  return 0;
}


int main(){
  char map[18][34];
  positions find[2][6][33];
  memset(find,0,sizeof(find));
  char cs[6] = "KQRBN";
  for ( int i = 0 ; i < 17 ; i++ ){
    //for ( int j = 0 ; j < 33 ; j++ ){
    //  scanf("%c",&map[i][j]);
    //}
    scanf("%s",map[i]);
    //getchar();
  }
  char tmp;
  int player;
  int number;
  int same;
  for ( int i = 1 ; i < 17 ; i+=2 ){
    for ( int j = 2 ; j < 33 ; j+=4 ){
      tmp = map[i][j];
      if (tmp == '.' || tmp == ':')
        continue;
      if (tmp < 'a'){
        player = 0;
      }else {
        player = 1;
      }
      number = getnum(tmp);
      same = ++find[player][number][0].x;
      //printf("tmp = %c , player = %d , number = %d , same = %d , x = %d , y = %d\n", tmp, player, number, same , i , j);
      find[player][number][same].x = 9 - (i+1)/2;
      find[player][number][same].y = (j+2)/4;
    }
  }
  for(int i = 0 ; i < 2 ; i++){
    for (int j = 0 ; j < 6 ; j++ ){
      same = find[i][j][0].x;
      if (i == 0)
      sort(find[i][j]+1 , find[i][j]+1+same ,cmp1);
      else if(i == 1)
      sort(find[i][j]+1 , find[i][j]+1+same ,cmp2);
    }
  }
  printf("White: ");
  for (int i = 0 ; i < 5 ; i++){
    same = find[0][i][0].x;
    for (int j = 1 ; j < same+1 ; j++){
      printf("%c%c%d,",cs[i],'a'-1+find[0][i][j].y,find[0][i][j].x);
    }
  }
  same = find[0][5][0].x;
  for (int j = 1 ; j < same+1 ; j++){
    printf("%c%d",'a'-1+find[0][5][j].y,find[0][5][j].x);
    if(j != same)
      printf(",");
  }
  printf("\nBlack: ");
  for (int i = 0 ; i < 5 ; i++){
    same = find[1][i][0].x;
    for (int j = 1 ; j < same+1 ; j++){
      printf("%c%c%d,",cs[i],'a'-1+find[1][i][j].y,find[1][i][j].x);
    }
  }
  same = find[1][5][0].x;
  for (int j = 1 ; j < same+1 ; j++){
    printf("%c%d",'a'-1+find[1][5][j].y,find[1][5][j].x);
    if(j != same)
      printf(",");
  }
  printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值