烟大 Contest1024 - 《挑战编程》第一章:入门 Problem G: Check The Check(模拟国际象棋)
Problem G: Check The Check
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 10 Solved: 3
[Submit][Status][Web Board]
Description
Your task is to write a program that reads a chessboard configuration and identifies whether a king is under attack (in check). A king is in check if it is on square which can be taken by the opponent on his next move. White pieces will be represented by uppercase letters, and black pieces by lowercase letters. The white side will always be on the bottom of the board, with the black side always on the top. For those unfamiliar with chess, here are the movements of each piece: Pawn (p or P): can only move straight ahead, one square at a time. However, it takes pieces diagonally, and that is what concerns you in this problem. Knight (n or N) : has an L-shaped movement shown below. It is the only piece that can jump over other pieces. Bishop (b or B) : can move any number of squares diagonally, either forward or backward. Rook (r or R) : can move any number of squares vertically or horizontally, either forward or backward. Queen (q or Q) : can move any number of squares in any direction (diagonally, horizontally, or vertically) either forward or backward. King (k or K) : can move one square at a time in any direction (diagonally, horizontally, or vertically) either forward or backward. Movement examples are shown below, where ``*'' indicates the positions where the piece can capture another piece:
Pawn Rook Bishop Queen King Knight ........ ...*.... .......* ...*...* ........ ........ ........ ...*.... *.....*. *..*..*. ........ ........ ........ ...*.... .*...*.. .*.*.*.. ........ ..*.*... ........ ...*.... ..*.*... ..***... ..***... .*...*.. ...p.... ***r**** ...b.... ***q**** ..*k*... ...n.... ..*.*... ...*.... ..*.*... ..***... ..***... .*...*.. ........ ...*.... .*...*.. .*.*.*.. ........ ..*.*... ........ ...*.... *.....*. *..*..*. ........ ........Remember that the knight is the only piece that can jump over other pieces. The pawn movement will depend on its side. If it is a black pawn, it can only move one square diagonally down the board. If it is a white pawn, it can only move one square diagonally up the board. The example above is a black pawn, described by a lowercase ``p''. We use ``move" to indicate the squares where the pawn can capture another piece.
Input
There will be an arbitrary number of board configurations in the input, each consisting of eight lines of eight characters each. A ``.'' denotes an empty square, while upper- and lowercase letters represent the pieces as defined above. There will be no invalid characters and no configurations where both kings are in check. You must read until you find an empty board consisting only of ``.'' characters, which should not be processed. There will be an empty line between each pair of board configurations. All boards, except for the empty one, will contain exactly one white king and one black king.
Output
For each board configuration read you must output one of the following answers: Game #d: white king is in check. Game #d: black king is in check. Game #d: no king is in check. where d stands for the game number starting from 1.
Sample Input
..k.....
ppp.pppp
........
.R...B..
........
........
PPPPPPPP
K.......
rnbqk.nr
ppp..ppp
....p...
...p....
.bPP....
.....N..
PP..PPPP
RNBQKB.R
........
........
........
........
........
........
........
........
Sample Output
Game #1: black king is in check. Game #2: white king is in check.
HINT
模拟题。模拟的是国际象棋。通过输入棋子的分布(8*8的棋盘上),判断下一步哪一方会被将军或者是平局。没什么技术含量,写一个switch语句,将所有种类棋子的情况写进去,然后依次检测每一个棋子。检测完白字就检测黑子。如果被将军就跳出输出结果。
写了300多行,真是麻烦。
My code:
1 #include <iostream> 2 3 using namespace std; 4 5 int main() 6 { 7 char q[9][9]; 8 int count = 1; 9 while(true){ 10 //input 11 int i,j; 12 bool f=true; 13 for(i=1;i<=8;i++) 14 for(j=1;j<=8;j++){ 15 cin>>q[i][j]; 16 if(q[i][j]!='.') 17 f=false; 18 } 19 if(f) break; //如果是空棋盘,退出 20 //不是空棋盘,检测每一个棋子是否有将军的能力。 21 22 bool fw=false,fb=false; //判断白子和黑子谁能赢 23 int n; 24 int ii,jj; 25 //先检测白子 26 for(i=1;i<=8;i++){ 27 for(j=1;j<=8;j++){ 28 if(q[i][j]=='.' || ('a'<=q[i][j] && q[i][j]<='z') ) continue; //如果无子或者检测到黑子(小写),则跳过 29 switch(q[i][j]){ 30 case 'P': //卒 31 if(q[i-1][j-1]=='k' || q[i-1][j+1]=='k') 32 fw=true; 33 break; 34 case 'R': //车 35 36 //左 37 n=j-1; 38 while(--n){ 39 if(q[i][n]=='k') {fw=true;break;} 40 else if(q[i][n]!='.') break; 41 } 42 //右 43 n=j+1; 44 while(fw!=true && (++n)<=8 ){ 45 if(q[i][n]=='k') {fw=true;break;} 46 else if(q[i][n]!='.') break; 47 } 48 //上 49 n=i-1; 50 while(fw!=true && --n){ 51 if(q[n][j]=='k') {fw=true;break;} 52 else if(q[n][j]!='.') break; 53 } 54 //下 55 n=i+1; 56 while(fw!=true && (++n)<=8 ){ 57 if(q[n][j]=='k') {fw=true;break;} 58 else if(q[n][j]!='.') break; 59 } 60 break; 61 case 'B': //象 62 //左上 63 ii=i-1; 64 jj=j-1; 65 while(ii>=1 && jj>=1){ 66 if(q[ii][jj]=='k') {fw=true;break;} 67 else if(q[ii][jj]!='.') break; 68 --ii,--jj; 69 } 70 //右上 71 ii=i-1; 72 jj=j+1; 73 while(!fw && ii>=1 && jj<=8){ 74 if(q[ii][jj]=='k') {fw=true;break;} 75 else if(q[ii][jj]!='.') break; 76 --ii,++jj; 77 } 78 //左下 79 ii=i+1; 80 jj=j-1; 81 while(!fw && ii<=8 && jj>=1){ 82 if(q[ii][jj]=='k') {fw=true;break;} 83 else if(q[ii][jj]!='.') break; 84 ++ii,--jj; 85 } 86 //右下 87 ii=i+1; 88 jj=j+1; 89 while(!fw && ii<=8 && jj<=8){ 90 if(q[ii][jj]=='k') {fw=true;break;} 91 else if(q[ii][jj]!='.') break; 92 ++ii,++jj; 93 } 94 break; 95 case 'Q': //后 96 //左 97 n=j-1; 98 while(--n){ 99 if(q[i][n]=='k') {fw=true;break;} 100 else if(q[i][n]!='.') break; 101 } 102 //右 103 n=j+1; 104 while(fw!=true && (++n)<=8 ){ 105 if(q[i][n]=='k') {fw=true;break;} 106 else if(q[i][n]!='.') break; 107 } 108 //上 109 n=i-1; 110 while(fw!=true && --n){ 111 if(q[n][j]=='k') {fw=true;break;} 112 else if(q[n][j]!='.') break; 113 } 114 //下 115 n=i+1; 116 while(fw!=true && (++n)<=8 ){ 117 if(q[n][j]=='k') {fw=true;break;} 118 else if(q[n][j]!='.') break; 119 } 120 //左上 121 ii=i-1; 122 jj=j-1; 123 while(ii>=1 && jj>=1){ 124 if(q[ii][jj]=='k') {fw=true;break;} 125 else if(q[ii][jj]!='.') break; 126 --ii,--jj; 127 } 128 //右上 129 ii=i-1; 130 jj=j+1; 131 while(!fw && ii>=1 && jj<=8){ 132 if(q[ii][jj]=='k') {fw=true;break;} 133 else if(q[ii][jj]!='.') break; 134 --ii,++jj; 135 } 136 //左下 137 ii=i+1; 138 jj=j-1; 139 while(!fw && ii<=8 && jj>=1){ 140 if(q[ii][jj]=='k') {fw=true;break;} 141 else if(q[ii][jj]!='.') break; 142 ++ii,--jj; 143 } 144 //右下 145 ii=i+1; 146 jj=j+1; 147 while(!fw && ii<=8 && jj<=8){ 148 if(q[ii][jj]=='k') {fw=true;break;} 149 else if(q[ii][jj]!='.') break; 150 ++ii,++jj; 151 } 152 break; 153 case 'K': //王 154 //上下左右 155 if(q[i-1][j]=='k'){fw=true;break;} 156 else if(q[i+1][j]=='k'){fw=true;break;} 157 else if(q[i][j-1]=='k'){fw=true;break;} 158 else if(q[i][j+1]=='k'){fw=true;break;} 159 //左上右上左下右下 160 else if(q[i-1][j-1]=='k'){fw=true;break;} 161 else if(q[i-1][j+1]=='k'){fw=true;break;} 162 else if(q[i+1][j-1]=='k'){fw=true;break;} 163 else if(q[i+1][j+1]=='k'){fw=true;break;} 164 break; 165 case 'N': //马 166 //转一圈检测,从正上偏左第一个开始 167 if(q[i-2][j-1]=='k'){fw=true;break;} 168 else if(q[i-2][j+1]=='k'){fw=true;break;} 169 else if(q[i-1][j+2]=='k'){fw=true;break;} 170 else if(q[i+1][j+2]=='k'){fw=true;break;} 171 172 else if(q[i+2][j+1]=='k'){fw=true;break;} 173 else if(q[i+2][j-1]=='k'){fw=true;break;} 174 else if(q[i+1][j-2]=='k'){fw=true;break;} 175 else if(q[i-1][j-2]=='k'){fw=true;break;} 176 break; 177 case '.': //无子 178 break; 179 } 180 if(fw) break; 181 } 182 if(fw) break; 183 } 184 //检测黑子 185 for(i=1;i<=8;i++){ 186 for(j=1;j<=8;j++){ 187 if(q[i][j]=='.' || ('A'<=q[i][j] && q[i][j]<='Z') ) continue; //如果无子或者检测到白子(大写),则跳过 188 switch(q[i][j]){ 189 case 'p': //卒 190 if(q[i-1][j-1]=='K' || q[i-1][j+1]=='K') 191 fb=true; 192 break; 193 case 'r': //车 194 195 //左 196 n=j-1; 197 while(--n){ 198 if(q[i][n]=='K') {fb=true;break;} 199 else if(q[i][n]!='.') break; 200 } 201 //右 202 n=j+1; 203 while(fb!=true && (++n)<=8 ){ 204 if(q[i][n]=='K') {fb=true;break;} 205 else if(q[i][n]!='.') break; 206 } 207 //上 208 n=i-1; 209 while(fb!=true && --n){ 210 if(q[n][j]=='K') {fb=true;break;} 211 else if(q[n][j]!='.') break; 212 } 213 //下 214 n=i+1; 215 while(fb!=true && (++n)<=8 ){ 216 if(q[n][j]=='K') {fb=true;break;} 217 else if(q[n][j]!='.') break; 218 } 219 break; 220 case 'b': //象 221 //左上 222 ii=i-1; 223 jj=j-1; 224 while(ii>=1 && jj>=1){ 225 if(q[ii][jj]=='K') {fb=true;break;} 226 else if(q[ii][jj]!='.') break; 227 --ii,--jj; 228 } 229 //右上 230 ii=i-1; 231 jj=j+1; 232 while(!fb && ii>=1 && jj<=8){ 233 if(q[ii][jj]=='K') {fb=true;break;} 234 else if(q[ii][jj]!='.') break; 235 --ii,++jj; 236 } 237 //左下 238 ii=i+1; 239 jj=j-1; 240 while(!fb && ii<=8 && jj>=1){ 241 if(q[ii][jj]=='K') {fb=true;break;} 242 else if(q[ii][jj]!='.') break; 243 ++ii,--jj; 244 } 245 //右下 246 ii=i+1; 247 jj=j+1; 248 while(!fb && ii<=8 && jj<=8){ 249 if(q[ii][jj]=='K') {fb=true;break;} 250 else if(q[ii][jj]!='.') break; 251 ++ii,++jj; 252 } 253 break; 254 case 'Q': //后 255 //左 256 n=j-1; 257 while(--n){ 258 if(q[i][n]=='K') {fb=true;break;} 259 else if(q[i][n]!='.') break; 260 } 261 //右 262 n=j+1; 263 while(fb!=true && (++n)<=8 ){ 264 if(q[i][n]=='K') {fb=true;break;} 265 else if(q[i][n]!='.') break; 266 } 267 //上 268 n=i-1; 269 while(fb!=true && --n){ 270 if(q[n][j]=='K') {fb=true;break;} 271 else if(q[n][j]!='.') break; 272 } 273 //下 274 n=i+1; 275 while(fb!=true && (++n)<=8 ){ 276 if(q[n][j]=='K') {fb=true;break;} 277 else if(q[n][j]!='.') break; 278 } 279 //左上 280 ii=i-1; 281 jj=j-1; 282 while(ii>=1 && jj>=1){ 283 if(q[ii][jj]=='K') {fb=true;break;} 284 else if(q[ii][jj]!='.') break; 285 --ii,--jj; 286 } 287 //右上 288 ii=i-1; 289 jj=j+1; 290 while(!fb && ii>=1 && jj<=8){ 291 if(q[ii][jj]=='K') {fb=true;break;} 292 else if(q[ii][jj]!='.') break; 293 --ii,++jj; 294 } 295 //左下 296 ii=i+1; 297 jj=j-1; 298 while(!fb && ii<=8 && jj>=1){ 299 if(q[ii][jj]=='K') {fb=true;break;} 300 else if(q[ii][jj]!='.') break; 301 ++ii,--jj; 302 } 303 //右下 304 ii=i+1; 305 jj=j+1; 306 while(!fb && ii<=8 && jj<=8){ 307 if(q[ii][jj]=='K') {fb=true;break;} 308 else if(q[ii][jj]!='.') break; 309 ++ii,++jj; 310 } 311 break; 312 case 'K': //王 313 //上下左右 314 if(q[i-1][j]=='K'){fb=true;break;} 315 else if(q[i+1][j]=='K'){fb=true;break;} 316 else if(q[i][j-1]=='K'){fb=true;break;} 317 else if(q[i][j+1]=='K'){fb=true;break;} 318 //左上右上左下右下 319 else if(q[i-1][j-1]=='K'){fb=true;break;} 320 else if(q[i-1][j+1]=='K'){fb=true;break;} 321 else if(q[i+1][j-1]=='K'){fb=true;break;} 322 else if(q[i+1][j+1]=='K'){fb=true;break;} 323 break; 324 case 'N': //马 325 //转一圈检测,从正上偏左第一个开始 326 if(q[i-2][j-1]=='k'){fb=true;break;} 327 else if(q[i-2][j+1]=='K'){fb=true;break;} 328 else if(q[i-1][j+2]=='K'){fb=true;break;} 329 else if(q[i+1][j+2]=='K'){fb=true;break;} 330 331 else if(q[i+2][j+1]=='K'){fb=true;break;} 332 else if(q[i+2][j-1]=='K'){fb=true;break;} 333 else if(q[i+1][j-2]=='K'){fb=true;break;} 334 else if(q[i-1][j-2]=='K'){fb=true;break;} 335 break; 336 default:break; 337 } 338 if(fb) break; 339 } 340 if(fb) break; 341 } 342 343 344 if(fw==true && fb==false) 345 cout<<"Game #"<<count++<<": "<<"black king is in check."<<endl; 346 else if(fb==true && fw==false) 347 cout<<"Game #"<<count++<<": "<<"white king is in check."<<endl; 348 else if(fw==false && fb==false) 349 cout<<"Game #"<<count++<<": "<<"no king is in check."<<endl; 350 else break; 351 } 352 return 0; 353 }
Freecode : www.cnblogs.com/yym2013