标签:style blog io color os ar 使用 java for
严格按规则实现、使用多态加异常来简化代码逻辑
Player类表示玩家
存储身份信息和持有棋子信息
Board类表示棋盘
可以通过坐标得到棋子
Piece类表示棋子
存储位置信息和持有人信息
各个棋子的实现提供对棋子走法的支持
Game类控制程序逻辑
具体见代码
1 package acm.hdu.p1691; 2 3 import java.io.FileInputStream; 4 import java.util.ArrayList; 5 import java.util.List; 6 import java.util.Scanner; 7 8 @SuppressWarnings("serial") 9 class ChessException extends Exception 10 { 11 public ChessException(String message) 12 { 13 super(message); 14 } 15 } 16 17 enum PlayerColor 18 { 19 RED, BLACK 20 } 21 22 class Player 23 { 24 private PlayerColor color; 25 private Board board; 26 private List<Piece> pieces = new ArrayList<Piece>(); 27 28 public Player(PlayerColor color) 29 { 30 this.color = color; 31 } 32 33 public PlayerColor getColor() 34 { 35 return color; 36 } 37 38 public void setBoard(Board board) 39 { 40 this.board = board; 41 } 42 43 public void addPiece(Piece piece) 44 { 45 this.pieces.add(piece); 46 } 47 48 public void removePiece(Piece piece) 49 { 50 this.pieces.remove(piece); 51 } 52 53 public List<Piece> getPieces() 54 { 55 return pieces; 56 } 57 58 public Piece getKing() 59 { 60 for (Piece piece : pieces) 61 if (piece instanceof PieceKing) 62 return piece; 63 return null; 64 } 65 } 66 67 class Board 68 { 69 private Piece pieces[][]; 70 71 public Board() 72 { 73 pieces = new Piece[10][9]; 74 } 75 76 public void setCell(int row, int column, Piece piece) 77 { 78 pieces[row - 1][column - 1] = piece; 79 } 80 81 public Piece getCell(int row, int column) 82 { 83 return pieces[row - 1][column - 1]; 84 } 85 86 @Override 87 public String toString() 88 { 89 String result = ""; 90 91 result += String.format("%2s", ""); 92 for (int column = 1; column <= 9; column++) 93 result += String.format("%12s", column); 94 result += "\n"; 95 96 for (int row = 1; row <= 10; row++) 97 { 98 result += String.format("%2s", row); 99 for (int column = 1; column <= 9; column++) 100 result += (String.format("%12s", getCell(row, column))); 101 result += "\n"; 102 } 103 return result; 104 } 105 } 106 107 abstract class Piece 108 { 109 private Player player; 110 private int currentRow; 111 private int currentColumn; 112 113 public Piece(Player player) 114 { 115 this.player = player; 116 } 117 118 public Player getPlayer() 119 { 120 return player; 121 } 122 123 public int getCurrentRow() 124 { 125 return currentRow; 126 } 127 128 public void setCurrentRow(int currentRow) 129 { 130 this.currentRow = currentRow; 131 } 132 133 public int getCurrentColumn() 134 { 135 return currentColumn; 136 } 137 138 public void setCurrentColumn(int currentColumn) 139 { 140 this.currentColumn = currentColumn; 141 } 142 143 @Override 144 public String toString() 145 { 146 String simpleName = getClass().getSimpleName().replaceAll("Piece", ""); 147 if (player.getColor() == PlayerColor.RED) 148 return simpleName; 149 else 150 return String.format("[%s]", simpleName); 151 } 152 153 public boolean isCrossRiver(int row, int column) 154 { 155 switch (player.getColor()) 156 { 157 case RED: 158 return row <= 5; 159 default: 160 return row >= 6; 161 } 162 } 163 164 public boolean isLeavePalace(int row, int column) 165 { 166 int minRow, maxRow; 167 int minColumn = 4, maxColumn = 6; 168 switch (player.getColor()) 169 { 170 case RED: 171 minRow = 8; 172 maxRow = 10; 173 break; 174 default: 175 minRow = 1; 176 maxRow = 3; 177 break; 178 } 179 if (row < minRow || row > maxRow) 180 return true; 181 if (column < minColumn || column > maxColumn) 182 return true; 183 return false; 184 } 185 186 public abstract void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) 187 throws ChessException; 188 } 189 190 class PieceKing extends Piece 191 { 192 193 public PieceKing(Player player) 194 { 195 super(player); 196 } 197 198 @Override 199 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 200 { 201 //基本走法 202 { 203 if (Math.abs(startRow - endRow) + Math.abs(startColumn - endColumn) != 1) 204 throw new ChessException("checkMove PieceKing Basic"); 205 } 206 //离开老窝 207 { 208 if (isLeavePalace(endRow, endColumn)) 209 throw new ChessException("checkMove PieceKing LeavePalace"); 210 } 211 } 212 } 213 214 class PieceMandarins extends Piece 215 { 216 217 public PieceMandarins(Player player) 218 { 219 super(player); 220 } 221 222 @Override 223 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 224 { 225 //基本走法 226 { 227 if (Math.abs(startRow - endRow) != Math.abs(startColumn - endColumn)) 228 throw new ChessException("checkMove PieceMandarins Basic"); 229 if (Math.abs(startRow - endRow) != 1) 230 throw new ChessException("checkMove PieceMandarins Basic"); 231 } 232 //离开老窝 233 { 234 if (isLeavePalace(endRow, endColumn)) 235 throw new ChessException("checkMove PieceMandarins LeavePalace"); 236 } 237 } 238 } 239 240 class PieceElephants extends Piece 241 { 242 243 public PieceElephants(Player player) 244 { 245 super(player); 246 } 247 248 @Override 249 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 250 { 251 //基本走法 252 { 253 if (Math.abs(startRow - endRow) != 2 || Math.abs(startColumn - endColumn) != 2) 254 throw new ChessException("checkMove PieceElephants Basic"); 255 } 256 //阻挡 257 { 258 if (board.getCell((startRow + endRow) / 2, (startColumn + endColumn) / 2) != null) 259 throw new ChessException("checkMove PieceElephants Block"); 260 } 261 //过河 262 { 263 if (isCrossRiver(endRow, endColumn)) 264 throw new ChessException("checkMove PieceElephants River"); 265 } 266 } 267 } 268 269 class PieceKnights extends Piece 270 { 271 272 public PieceKnights(Player player) 273 { 274 super(player); 275 } 276 277 @Override 278 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 279 { 280 //基本走法 281 { 282 boolean flag1 = (Math.abs(startRow - endRow) == 2 && Math.abs(startColumn - endColumn) == 1); 283 boolean flag2 = (Math.abs(startRow - endRow) == 1 && Math.abs(startColumn - endColumn) == 2); 284 if (!flag1 && !flag2) 285 throw new ChessException("checkMove PieceKnights Basic"); 286 } 287 //阻挡 288 { 289 if (startRow + 2 == endRow && board.getCell(startRow + 1, startColumn) != null) 290 throw new ChessException("checkMove PieceKnights Block"); 291 if (startRow - 2 == endRow && board.getCell(startRow - 1, startColumn) != null) 292 throw new ChessException("checkMove PieceKnights Block"); 293 if (startColumn + 2 == endColumn && board.getCell(startRow, startColumn + 1) != null) 294 throw new ChessException("checkMove PieceKnights Block"); 295 if (startColumn - 2 == endColumn && board.getCell(startRow, startColumn - 1) != null) 296 throw new ChessException("checkMove PieceKnights Block"); 297 } 298 } 299 } 300 301 class PieceRooks extends Piece 302 { 303 304 public PieceRooks(Player player) 305 { 306 super(player); 307 } 308 309 @Override 310 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 311 { 312 //基本走法 313 { 314 if (startRow != endRow && startColumn != endColumn) 315 throw new ChessException("checkMove PieceRooks Basic"); 316 } 317 318 //阻挡 319 { 320 if (startColumn == endColumn) 321 for (int row = Math.min(startRow, endRow) + 1; row <= Math.max(startRow, endRow) - 1; row++) 322 if (board.getCell(row, startColumn) != null) 323 throw new ChessException("checkMove PieceRooks Block"); 324 if (startRow == endRow) 325 for (int column = Math.min(startColumn, endColumn) + 1; column <= Math.max(startColumn, endColumn) - 1; column++) 326 if (board.getCell(startRow, column) != null) 327 throw new ChessException("checkMove PieceRooks Block"); 328 } 329 330 } 331 } 332 333 class PieceCannons extends Piece 334 { 335 336 public PieceCannons(Player player) 337 { 338 super(player); 339 } 340 341 @Override 342 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 343 { 344 //基本走法 345 { 346 if (startRow != endRow && startColumn != endColumn) 347 throw new ChessException("checkMove PieceCannons Basic"); 348 } 349 350 //阻挡(若目标为空) 351 if (board.getCell(endRow, endColumn) == null) 352 { 353 if (startColumn == endColumn) 354 for (int row = Math.min(startRow, endRow) + 1; row <= Math.max(startRow, endRow) - 1; row++) 355 if (board.getCell(row, startColumn) != null) 356 throw new ChessException("checkMove PieceCannons Block"); 357 if (startRow == endRow) 358 for (int column = Math.min(startColumn, endColumn) + 1; column <= Math.max(startColumn, endColumn) - 1; column++) 359 if (board.getCell(startRow, column) != null) 360 throw new ChessException("checkMove PieceCannons Block"); 361 } 362 //阻挡(若目标不为空) 363 else 364 { 365 int blockCount = 0; 366 if (startColumn == endColumn) 367 for (int row = Math.min(startRow, endRow) + 1; row <= Math.max(startRow, endRow) - 1; row++) 368 if (board.getCell(row, startColumn) != null) 369 blockCount++; 370 if (startRow == endRow) 371 for (int column = Math.min(startColumn, endColumn) + 1; column <= Math.max(startColumn, endColumn) - 1; column++) 372 if (board.getCell(startRow, column) != null) 373 blockCount++; 374 if (blockCount != 1) 375 throw new ChessException("checkMove PieceCannons Block " + blockCount); 376 } 377 378 } 379 } 380 381 class PiecePawns extends Piece 382 { 383 384 public PiecePawns(Player player) 385 { 386 super(player); 387 } 388 389 @Override 390 public void checkMove(Board board, int startRow, int startColumn, int endRow, int endColumn) throws ChessException 391 { 392 //基本走法(未过河) 393 if (!isCrossRiver(startRow, startColumn)) 394 { 395 //步数 396 if (Math.abs(startRow - endRow) + Math.abs(startColumn - endColumn) != 1) 397 throw new ChessException("checkMove PiecePawns Basic Not Cross River"); 398 //方向 399 if (startColumn != endColumn) 400 throw new ChessException("checkMove PiecePawns Basic Not Cross River"); 401 if (getPlayer().getColor() == PlayerColor.RED && startRow < endRow) 402 throw new ChessException("checkMove PiecePawns Basic Not Cross River"); 403 if (getPlayer().getColor() == PlayerColor.BLACK && startRow > endRow) 404 throw new ChessException("checkMove PiecePawns Basic Not Cross River"); 405 } 406 //基本走法(已过河) 407 else 408 { 409 //步数 410 if (Math.abs(startRow - endRow) + Math.abs(startColumn - endColumn) != 1) 411 throw new ChessException("checkMove PiecePawns Basic Crossed River"); 412 //方向 413 if (getPlayer().getColor() == PlayerColor.RED && startRow < endRow) 414 throw new ChessException("checkMove PiecePawns Basic Crossed River"); 415 if (getPlayer().getColor() == PlayerColor.BLACK && startRow > endRow) 416 throw new ChessException("checkMove PiecePawns Basic Crossed River"); 417 } 418 } 419 420 } 421 422 class PieceFactory 423 { 424 public Piece createPiece(Player playerRed, Player playerBlack, int value) 425 { 426 if (value == 0) 427 return null; 428 Player currentPlayer; 429 if (value <= 7) 430 currentPlayer = playerRed; 431 else 432 { 433 currentPlayer = playerBlack; 434 value -= 7; 435 } 436 switch (value) 437 { 438 case 1: 439 return new PieceKing(currentPlayer); 440 case 2: 441 return new PieceMandarins(currentPlayer); 442 case 3: 443 return new PieceElephants(currentPlayer); 444 case 4: 445 return new PieceKnights(currentPlayer); 446 case 5: 447 return new PieceRooks(currentPlayer); 448 case 6: 449 return new PieceCannons(currentPlayer); 450 case 7: 451 return new PiecePawns(currentPlayer); 452 default: 453 return null; 454 } 455 } 456 } 457 458 class Game 459 { 460 private Board board; 461 private Player[] players; 462 private Player playerRed, playerBlack; 463 private int currentPlayerIndex; 464 465 public Game() 466 { 467 board = new Board(); 468 playerRed = new Player(PlayerColor.RED); 469 playerBlack = new Player(PlayerColor.BLACK); 470 players = new Player[] { playerRed, playerBlack }; 471 for (int i = 0; i < 2; i++) 472 players[i].setBoard(board); 473 } 474 475 public void init(Scanner cin) 476 { 477 for (int row = 1; row <= 10; row++) 478 for (int column = 1; column <= 9; column++) 479 { 480 int value = cin.nextInt(); 481 Piece piece = new PieceFactory().createPiece(playerRed, playerBlack, value); 482 board.setCell(row, column, piece); 483 if (piece != null) 484 { 485 piece.setCurrentRow(row); 486 piece.setCurrentColumn(column); 487 piece.getPlayer().addPiece(piece); 488 } 489 } 490 // System.out.println("init ok"); 491 // System.out.println(board); 492 493 } 494 495 public int play(Scanner cin) 496 { 497 int n = cin.nextInt(); 498 int k = cin.nextInt(); 499 int errorStep = -1; 500 currentPlayerIndex = k; 501 502 for (int step = 1; step <= n; step++) 503 { 504 int startRow = cin.nextInt(); 505 int startColumn = cin.nextInt(); 506 int endRow = cin.nextInt(); 507 int endColumn = cin.nextInt(); 508 // System.out.println("Move Step : " + step); 509 // System.out.println("Command : " + startRow + " " + startColumn + " " + endRow + " " + endColumn); 510 if (errorStep != -1) 511 { 512 // System.out.println("Errored!"); 513 continue; 514 } 515 try 516 { 517 moveOneStep(startRow, startColumn, endRow, endColumn); 518 } 519 catch (ChessException e) 520 { 521 errorStep = step; 522 // System.err.println("Move Step : " + step + " Error!"); 523 // System.err.println(e); 524 } 525 // System.out.println(board); 526 currentPlayerIndex = 1 - currentPlayerIndex; 527 } 528 529 return errorStep; 530 } 531 532 private void checkGameOver() throws ChessException 533 { 534 for (Player player : players) 535 if (player.getKing() == null) 536 throw new ChessException("checkGameOver " + player.getColor()); 537 } 538 539 private void checkCoordinates(int startRow, int startColumn, int endRow, int endColumn) 540 throws ChessException 541 { 542 if (startRow < 1 || startRow > 10) 543 throw new ChessException("checkCoordinates startRow"); 544 if (startColumn < 1 || startColumn > 9) 545 throw new ChessException("checkCoordinates startColumn"); 546 if (endRow < 1 || endRow > 10) 547 throw new ChessException("checkCoordinates endRow"); 548 if (endColumn < 1 || endColumn > 9) 549 throw new ChessException("checkCoordinates endColumn"); 550 } 551 552 private void checkEmpty(int startRow, int startColumn, int endRow, int endColumn) 553 throws ChessException 554 { 555 if (board.getCell(startRow, startColumn) == null) 556 throw new ChessException("checkEmpty " + board.getCell(startRow, startColumn)); 557 } 558 559 private void checkOwner(int startRow, int startColumn, int endRow, int endColumn) 560 throws ChessException 561 { 562 Player currentPlayer = players[currentPlayerIndex]; 563 if (board.getCell(startRow, startColumn).getPlayer() != currentPlayer) 564 throw new ChessException("checkOwner " + board.getCell(startRow, startColumn)); 565 if (board.getCell(endRow, endColumn) != null && board.getCell(endRow, endColumn).getPlayer() == currentPlayer) 566 throw new ChessException("checkOwner " + board.getCell(startRow, startColumn)); 567 } 568 569 private void checkMove(int startRow, int startColumn, int endRow, int endColumn) 570 throws ChessException 571 { 572 board.getCell(startRow, startColumn).checkMove(board, startRow, startColumn, endRow, endColumn); 573 } 574 575 private void checkFaceToFace() throws ChessException 576 { 577 if (playerRed.getKing() == null || playerBlack.getKing() == null) 578 return; 579 if (playerRed.getKing().getCurrentColumn() != playerBlack.getKing().getCurrentColumn()) 580 return; 581 boolean exist = false; 582 for (int row = playerBlack.getKing().getCurrentRow() + 1; row <= playerRed.getKing().getCurrentRow() - 1; row++) 583 if (board.getCell(row, playerBlack.getKing().getCurrentColumn()) != null) 584 exist = true; 585 if (!exist) 586 throw new ChessException("checkFaceToFace "); 587 } 588 589 private boolean isGameOver() 590 { 591 return (playerRed.getKing() == null || playerBlack.getKing() == null); 592 } 593 594 private boolean isCheckmate() 595 { 596 for (Piece piece : players[1 - currentPlayerIndex].getPieces()) 597 try 598 { 599 piece.checkMove(board, piece.getCurrentRow(), piece.getCurrentColumn(), 600 players[currentPlayerIndex].getKing().getCurrentRow() 601 , players[currentPlayerIndex].getKing().getCurrentColumn()); 602 return true; 603 } 604 catch (ChessException e) 605 { 606 // TODO Auto-generated catch block 607 // e.printStackTrace(); 608 } 609 return false; 610 } 611 612 public void moveOneStep(int startRow, int startColumn, int endRow, int endColumn) 613 throws ChessException 614 { 615 //判断游戏结束 616 checkGameOver(); 617 //记录是否处于将军状态 618 boolean isCheckmateBefore = isCheckmate(); 619 //判断坐标是否合法 620 checkCoordinates(startRow, startColumn, endRow, endColumn); 621 //判断起始位置是否为空 622 checkEmpty(startRow, startColumn, endRow, endColumn); 623 //判断所有者 624 checkOwner(startRow, startColumn, endRow, endColumn); 625 //判断移动 626 checkMove(startRow, startColumn, endRow, endColumn); 627 628 //移动 629 { 630 Piece pieceStart = board.getCell(startRow, startColumn); 631 Piece pieceEnd = board.getCell(endRow, endColumn); 632 if (pieceEnd != null) 633 pieceEnd.getPlayer().removePiece(pieceEnd); 634 board.setCell(endRow, endColumn, pieceStart); 635 board.setCell(startRow, startColumn, null); 636 pieceStart.setCurrentRow(endRow); 637 pieceStart.setCurrentColumn(endColumn); 638 } 639 640 //如果游戏结束 641 if (isGameOver()) 642 return; 643 //判断是否脱离将军状态 644 boolean isCheckmateAfter = isCheckmate(); 645 if (isCheckmateBefore && isCheckmateAfter) 646 throw new ChessException("is checkmate "); 647 //判断老将对面 648 checkFaceToFace(); 649 650 } 651 } 652 653 public class Main 654 { 655 public static void main(String args[]) throws Exception 656 { 657 // System.setIn(new FileInputStream("input2")); 658 Scanner cin = new Scanner(System.in); 659 int caseCount = cin.nextInt(); 660 for (int caseIndex = 1; caseIndex <= caseCount; caseIndex++) 661 { 662 Game game = new Game(); 663 game.init(cin); 664 int result = game.play(cin); 665 if (result == -1) 666 System.out.println(String.format("Case %d: Legal move", caseIndex)); 667 else 668 System.out.println(String.format("Case %d: Illegal move on step %d", caseIndex, result)); 669 670 } 671 } 672 }
标签:style blog io color os ar 使用 java for
原文地址:http://www.cnblogs.com/gwhahaha/p/4058463.html