问题陈述:问题是使用面向对象原理设计国际象棋游戏。
询问对象: Adobe,Amazon,Microsoft等
解决方案:
在面试中会问这些类型的问题,以判断候选人的面向对象设计技能。因此,首先我们应该考虑类。
主要课程将是:
- 点:点表示8×8网格的一个块和一个可选块。
- 件:系统的基本构建块,每件都将放置在一个位置上。计件类是抽象类。扩展类(Pawn,King,Queen,Rook,Knight,Bishop)实现了抽象的操作。
- 棋盘:棋盘是一组8×8的盒子,其中包含所有活动的棋子。
- 玩家:玩家类别代表玩游戏的参与者之一。
- 移动:代表游戏的移动,包含起点和终点。 Move类还将跟踪进行该移动的玩家。
- 游戏:此类控制游戏流程。它跟踪所有游戏动作,哪个玩家当前的回合以及游戏的最终结果。
让我们看一下细节。这些代码是不言自明的。您可以查看不同类的属性/变量和方法。
点:在国际象棋棋盘上代表一个单元:
public class Spot { private Piece piece; private int x; private int y; public Spot(int x, int y, Piece piece) { this.setPiece(piece); this.setX(x); this.setY(y); } public Piece getPiece() { return this.piece; } public void setPiece(Piece p) { this.piece = p; } public int getX() { return this.x; } public void setX(int x) { this.x = x; } public int getY() { return this.y; } public void setY(int y) { this.y = y; } }
棋子:代表所有国际象棋棋子的通用功能的抽象类:
public abstract class Piece { private boolean killed = false; private boolean white = false; public Piece(boolean white) { this.setWhite(white); } public boolean isWhite() { return this.white; } public void setWhite(boolean white) { this.white = white; } public boolean isKilled() { return this.killed; } public void setKilled(boolean killed) { this.killed = killed; } public abstract boolean canMove(Board board, Spot start, Spot end); }
King:将King表示为棋子:
public class King extends Piece { private boolean castlingDone = false; public King(boolean white) { super(white); } public boolean isCastlingDone() { return this.castlingDone; } public void setCastlingDone(boolean castlingDone) { this.castlingDone = castlingDone; } @Override public boolean canMove(Board board, Spot start, Spot end) { // we can't move the piece to a Spot that // has a piece of the same color if (end.getPiece().isWhite() == this.isWhite()) { return false; } int x = Math.abs(start.getX() - end.getX()); int y = Math.abs(start.getY() - end.getY()); if (x + y == 1) { // check if this move will not result in the king // being attacked if so return true return true; } return this.isValidCastling(board, start, end); } private boolean isValidCastling(Board board, Spot start, Spot end) { if (this.isCastlingDone()) { return false; } // Logic for returning true or false } public boolean isCastlingMove(Spot start, Spot end) { // check if the starting and // ending position are correct } }
骑士:将骑士代表棋子
public class Knight extends Piece { public Knight(boolean white) { super(white); } @Override public boolean canMove(Board board, Spot start, Spot end) { // we can't move the piece to a spot that has // a piece of the same colour if (end.getPiece().isWhite() == this.isWhite()) { return false; } int x = Math.abs(start.getX() - end.getX()); int y = Math.abs(start.getY() - end.getY()); return x * y == 2; } }
同样,我们可以为其他作品(例如Queen , Pawns , Rooks , Bishops等)创建类。
棋盘:代表国际象棋棋盘:
public class Board { Spot[][] boxes; public Board() { this.resetBoard(); } public Spot getBox(int x, int y) { if (x < 0 || x > 7 || y < 0 || y > 7) { throw new Exception("Index out of bound"); } return boxes[x][y]; } public void resetBoard() { // initialize white pieces boxes[0][0] = new Spot(0, 0, new Rook(true)); boxes[0][1] = new Spot(0, 1, new Knight(true)); boxes[0][2] = new Spot(0, 2, new Bishop(true)); //... boxes[1][0] = new Spot(1, 0, new Pawn(true)); boxes[1][1] = new Spot(1, 1, new Pawn(true)); //... // initialize black pieces boxes[7][0] = new Spot(7, 0, new Rook(false)); boxes[7][1] = new Spot(7, 1, new Knight(false)); boxes[7][2] = new Spot(7, 2, new Bishop(false)); //... boxes[6][0] = new Spot(6, 0, new Pawn(false)); boxes[6][1] = new Spot(6, 1, new Pawn(false)); //... // initialize remaining boxes without any piece for (int i = 2; i < 6; i++) { for (int j = 0; j < 8; j++) { boxes[i][j] = new Spot(i, j, null); } } } }
播放器:播放器的抽象类,它可以是人或计算机。
public abstract class Player { public boolean whiteSide; public boolean humanPlayer; public boolean isWhiteSide() { return this.whiteSide; } public boolean isHumanPlayer() { return this.humanPlayer; } } public class HumanPlayer extends Player { public HumanPlayer(boolean whiteSide) { this.whiteSide = whiteSide; this.humanPlayer = true; } } public class ComputerPlayer extends Player { public ComputerPlayer(boolean whiteSide) { this.whiteSide = whiteSide; this.humanPlayer = false; } }
移动:代表国际象棋移动:
public class Move { private Player player; private Spot start; private Spot end; private Piece pieceMoved; private Piece pieceKilled; private boolean castlingMove = false; public Move(Player player, Spot start, Spot end) { this.player = player; this.start = start; this.end = end; this.pieceMoved = start.getPiece(); } public boolean isCastlingMove() { return this.castlingMove; } public void setCastlingMove(boolean castlingMove) { this.castlingMove = castlingMove; } }
public enum GameStatus { ACTIVE, BLACK_WIN, WHITE_WIN, FORFEIT, STALEMATE, RESIGNATION }
游戏:代表国际象棋游戏:
public class Game { private Player[] players; private Board board; private Player currentTurn; private GameStatus status; private List
movesPlayed; private void initialize(Player p1, Player p2) { players[0] = p1; players[1] = p2; board.resetBoard(); if (p1.isWhiteSide()) { this.currentTurn = p1; } else { this.currentTurn = p2; } movesPlayed.clear(); } public boolean isEnd() { return this.getStatus() != GameStatus.ACTIVE; } public boolean getStatus() { return this.status; } public void setStatus(GameStatus status) { this.status = status; } public boolean playerMove(Player player, int startX, int startY, int endX, int endY) { Spot startBox = board.getBox(startX, startY); Spot endBox = board.getBox(startY, endY); Move move = new Move(player, startBox, endBox); return this.makeMove(move, player); } private boolean makeMove(Move move, Player player) { Piece sourcePiece = move.getStart().getPiece(); if (sourcePiece == null) { return false; } // valid player if (player != currentTurn) { return false; } if (sourcePiece.isWhite() != player.isWhiteSide()) { return false; } // valid move? if (!sourcePiece.canMove(board, move.getStart(), move.getEnd())) { return false; } // kill? Piece destPiece = move.getStart().getPiece(); if (destPiece != null) { destPiece.setKilled(true); move.setPieceKilled(destPiece); } // castling? if (sourcePiece != null && sourcePiece instanceof King && sourcePiece.isCastlingMove()) { move.setCastlingMove(true); } // store the move movesPlayed.add(move); // move piece from the stat box to end box move.getEnd().setPiece(move.getStart().getPiece()); move.getStart.setPiece(null); if (destPiece != null && destPiece instanceof King) { if (player.isWhiteSide()) { this.setStatus(GameStatus.WHITE_WIN); } else { this.setStatus(GameStatus.BLACK_WIN); } } // set the current turn to the other player if (this.currentTurn == players[0]) { this.currentTurn = players[1]; } else { this.currentTurn = players[0]; } return true; } } 参考: http://massivetechinterview.blogspot.com/2015/07/design-chess-game-using-oo-principles.html