diff --git a/src/controller/Game.java b/src/controller/Game.java index 8e5a462..88e67ad 100755 --- a/src/controller/Game.java +++ b/src/controller/Game.java @@ -1,117 +1,96 @@ package controller; -import java.io.Console; import java.util.ArrayList; -import view.GamePanel; import model.Board; import model.Color; import model.Location; import model.Move; -import model.Piece; +import view.GamePanel; public class Game { private Board board; - private Color current_turn; - private GamePanel panel; + private GamePanel gamePanel; + private boolean inJumpSequence; public Game(Board board) { this.board = board; - current_turn = Color.BLACK; + this.inJumpSequence = false; } - public void movePiece(Move move) { - if (move.isJump()) { - board.jump(move); - panel.removePiece(new Location((move.destination.row - + move.source.row)/2, - (move.source.column - + move.destination.column) / 2)); - } else { - board.move(move); + /* Either the server or the user will request a move */ + public void requestMove(Move move) { + board.movePiece(move); + gamePanel.movePiece(move); + + /* If this is the first jump of the jump sequence */ + if (move.isJump() && !inJumpSequence) inJumpSequence = true; + + /* If the piece that jumped has no more jumps */ + if (move.isJump() && getAvailableMoves(move.destination).isEmpty()) + inJumpSequence = false; + + /* If the game is not in the middle of a jump sequence, move the thunk */ + if (!inJumpSequence) { + + Move thunkMove = getThunkMove(); + board.movePiece(thunkMove); + gamePanel.movePiece(thunkMove); + + if (thunkMove.isJump()) inJumpSequence = true; + + while (inJumpSequence) { + thunkMove = getThunkMove(); + if (thunkMove != null) { + board.movePiece(thunkMove); + gamePanel.movePiece(thunkMove); + } else { + inJumpSequence = false; + } + } } + } - public void switchTurn() { - this.current_turn = this.current_turn == Color.BLACK ? - Color.WHITE : Color.BLACK; + public Move getThunkMove() { + ArrayList availableMoves; + + if (inJumpSequence) { + availableMoves = + board.generateJumpMovesForPiece(board.getLastPieceMoved()); + } else { + availableMoves = board.generateAllMoves(GameConstants.THUNK_COLOR); + } + + if (!availableMoves.isEmpty()) { + /* Just take the first move we see */ + Move moveChoice = availableMoves.get(0); + return moveChoice; + } else { + return null; + } } + public ArrayList getAvailableMoves(Location source) { - Piece moved = board.getLastPieceMoved(); - if (moved != null && moved.color == current_turn) { - // player just jumped - ArrayList jumpset = board.generateJumpMoves(moved); - if (jumpset.isEmpty()) { - switchTurn(); - } - return jumpset; + if (inJumpSequence) { + return board.generateJumpMovesForPiece(board.getPiece(source)); + } else { + return board.generateMovesForPiece(board.getPiece(source)); } - ArrayList moves = board.generateMoves(board.getPiece(source)); - ArrayList jumps = board.generateJumpMoves(board.getPiece(source)); - ArrayList allMoves = new ArrayList(moves); - allMoves.addAll(jumps); - return allMoves; } - public void playVsThunk() { - Color USER_COLOR = Color.BLACK; - Color THUNK_COLOR = Color.WHITE; - while (true) { - try { - Thread.sleep(200); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if (this.board.getMovesSinceCapture() > 50) break; - if (this.current_turn == THUNK_COLOR) { - Piece moved = this.board.getLastPieceMoved(); - if (moved.color == THUNK_COLOR) { - // thunk just jumped - ArrayList jumpset = board.generateJumpMoves(moved); - if (jumpset.isEmpty()) { - switchTurn(); - continue; - } - Move jump = jumpset.get(0); - movePiece(jump); - panel.moveArbitraryPiece(jump); - } - else { - ArrayList moveset = board.generateAllPossibleMoves(THUNK_COLOR); - if (moveset.isEmpty()) { - System.out.println("Thunk is out of moves."); - break; - } - Move theMove = moveset.get(0); - movePiece(theMove); - panel.moveArbitraryPiece(theMove); - - if(!theMove.isJump()) { - switchTurn(); - } - } - } - if (this.current_turn == USER_COLOR) { - //ArrayList moveset = board.generateAllPossibleMoves(USER_COLOR); - //if (moveset.isEmpty()) break; - } - - //board.print(); - } - Color winner = current_turn == Color.BLACK ? Color.WHITE : Color.BLACK; - System.out.println("THE WINNER IS " + winner.toString()); + public ArrayList getAllAvailableJumpMoves(Color player) { + return board.generateAllJumpMoves(player); } - public void setGamePanel(GamePanel panel) { - this.panel = panel; + this.gamePanel = panel; } - public Color getCurrentTurn() { - return current_turn; + public boolean isInJumpSequence() { + return inJumpSequence; } } diff --git a/src/controller/GameConstants.java b/src/controller/GameConstants.java new file mode 100644 index 0000000..8896a9b --- /dev/null +++ b/src/controller/GameConstants.java @@ -0,0 +1,10 @@ +package controller; + +import model.Color; + +public class GameConstants { + public static final int USER_MODE = 0; + public static final int SERVER_MODE = 0; + public static final Color THUNK_COLOR = Color.WHITE; + public static final Color USER_COLOR = Color.BLACK; +} diff --git a/src/model/Board.java b/src/model/Board.java index fbb5ceb..2dd4ab9 100755 --- a/src/model/Board.java +++ b/src/model/Board.java @@ -12,7 +12,7 @@ */ public class Board { // Board properties and representation - private final int BOARD_SIZE = 8; + private static final int BOARD_SIZE = 8; private Piece[][] representation; private Piece lastPieceMoved; @@ -45,11 +45,6 @@ public Board(Board other) { lastPieceMoved = other.getLastPieceMoved(); } - public boolean isValidSquare(Location location) { - return 0 <= location.row && location.row < BOARD_SIZE && - 0 <= location.column && location.column < BOARD_SIZE; - } - /** * Initialize the board putting checker pieces in their starting locations */ @@ -79,12 +74,107 @@ public boolean equals(Board other) { return true; } + public void movePiece(Move move) { + int sourceRow = move.source.row; + int sourceCol = move.source.column; + int destRow = move.destination.row; + int destCol = move.destination.column; + + if (move.isJump()) { + int monkeyRow = (destRow + sourceRow)/2; + int monkeyCol = (destCol + sourceCol)/2; + + /* Remove the piece being jumped ("monkey in the middle") */ + representation[monkeyRow][monkeyCol] = null; + } + + /* Place the piece in the destination cell */ + representation[destRow][destCol] = representation[sourceRow][sourceCol]; + + /* Remove from the source cell */ + representation[sourceRow][sourceCol] = null; + + /* Update the piece's location */ + representation[destRow][destCol].setLocation(new Location(destRow, destCol)); + + Piece moved = representation[destRow][destCol]; + + if (canPromote(moved)) { + moved.promote(); + } + + /* Update the last piece that was moved */ + this.lastPieceMoved = moved; + } + + /** + * Generates the frontier. + * @param color The color of pieces to generate the frontier for. + * @return A list of possible "next moves" in the form of boards. + */ + public ArrayList generateFrontier(Color color) { + ArrayList from_jumps = generateFrontierFromJumps(color); + if(from_jumps.isEmpty()) { + return generateFrontierFromRegularMoves(color); + } + return from_jumps; + } + + /** + * Generates the frontier for movement for all pieces. + * @param color + * @return + */ + public ArrayList generateFrontierFromRegularMoves(Color color) { + ArrayList frontier = new ArrayList(); + for (int i = 0; i < BOARD_SIZE; ++i) { + for (int j = 0; j < BOARD_SIZE; ++j) { + Piece p = this.representation[i][j]; + if(null != p && p.getColor() == color) { + ArrayList moves = generateRegularMovesForPiece(this.representation[i][j]); + for (Move move : moves) { + Board board = new Board(this); + board.movePiece(move); + frontier.add(board); + } + } + } + } + return frontier; + } + + public ArrayList generateFrontierFromJumps(Color color) { + ArrayList frontier = new ArrayList(); + for (int i = 0; i < BOARD_SIZE; ++i) { + for (int j = 0; j < BOARD_SIZE; ++j) { + Piece p = this.representation[i][j]; + if (null != p && p.getColor() == color) { + ArrayList jump_moves = generateJumpMovesForPiece(this.representation[i][j]); + for (Move jump : jump_moves) { + Board board = new Board(this); + board.movePiece(jump); + frontier.add(board); + } + } + } + } + return frontier; + } + + public ArrayList generateMovesForPiece(Piece p) { + ArrayList jumps = generateJumpMovesForPiece(p); + if (jumps.isEmpty()) { + return generateRegularMovesForPiece(p); + } + return jumps; + } + /** * Generates the Move set for a particular piece. * @param p * @return */ - public ArrayList generateMoves(Piece p) { + public ArrayList generateRegularMovesForPiece(Piece p) { ArrayList avail_moves = new ArrayList(); int row = p.getLocation().row; int col = p.getLocation().column; @@ -120,63 +210,12 @@ public ArrayList generateMoves(Piece p) { return avail_moves; } - /** - * Generates the frontier for movement for all pieces. - * @param color - * @return - */ - public ArrayList generateMoveFrontier(Color color) { - ArrayList frontier = new ArrayList(); - for (int i = 0; i < BOARD_SIZE; ++i) { - for (int j = 0; j < BOARD_SIZE; ++j) { - Piece p = this.representation[i][j]; - if(null != p && p.getColor() == color) { - ArrayList moves = generateMoves(this.representation[i][j]); - for (Move move : moves) { - Board board = new Board(this); - board.move(move); - frontier.add(board); - } - } - } - } - return frontier; - } - - public void move(Move move) { - representation[move.destination.row][move.destination.column] - = representation[move.source.row][move.source.column]; - representation[move.source.row][move.source.column] = null; - representation[move.destination.row][move.destination.column] - .setLocation(new Location(move.destination.row, move.destination.column)); - Piece moved = representation[move.destination.row][move.destination.column]; - this.lastPieceMoved = moved; - } - - /** - * Move the jumper and erase the jumpee. - * @param jump - */ - public void jump(Move jump) { - representation - [(jump.destination.row + jump.source.row)/2] - [(jump.destination.column + jump.source.column)/2] = null; // monkey - representation[jump.destination.row][jump.destination.column] = - representation[jump.source.row][jump.source.column]; - representation[jump.source.row][jump.source.column] = null; - representation[jump.destination.row][jump.destination.column] - .setLocation(new Location(jump.destination.row, jump.destination.column)); - - Piece moved = representation[jump.destination.row][jump.destination.column]; - this.lastPieceMoved = moved; - } - /** * Returns the possible jumps a piece can take. * @param color * @return */ - public ArrayList generateJumpMoves(Piece p) { + public ArrayList generateJumpMovesForPiece(Piece p) { ArrayList jumps = new ArrayList(); int row = p.getLocation().row, col = p.getLocation().column; @@ -208,45 +247,22 @@ public ArrayList generateJumpMoves(Piece p) { } return jumps; } - - public ArrayList generateJumpFrontier(Color color) { - ArrayList frontier = new ArrayList(); - for (int i = 0; i < BOARD_SIZE; ++i) { - for (int j = 0; j < BOARD_SIZE; ++j) { - Piece p = this.representation[i][j]; - if (null != p && p.getColor() == color) { - ArrayList jump_moves = generateJumpMoves(this.representation[i][j]); - for (Move jump : jump_moves) { - Board board = new Board(this); - board.move(jump); - frontier.add(board); - } - } - } - } - return frontier; - } - - /** - * Generates the frontier. - * @param color The color of pieces to generate the frontier for. - * @return A list of possible "next moves" in the form of boards. - */ - public ArrayList generateFrontier(Color color) { - ArrayList from_jumps = generateJumpFrontier(color); - if(from_jumps.isEmpty()) { - return generateMoveFrontier(color); + + public ArrayList generateAllMoves(Color color) { + ArrayList jumps = generateAllJumpMoves(color); + if (jumps.isEmpty()) { + return generateAllRegularMoves(color); } - return from_jumps; + return jumps; } - - public ArrayList generateJumpMoveFrontier(Color color) { + + public ArrayList generateAllJumpMoves(Color color) { ArrayList frontier = new ArrayList(); for (int i = 0; i < BOARD_SIZE; ++i) { for (int j = 0; j < BOARD_SIZE; ++j) { Piece p = this.representation[i][j]; if (null != p && p.getColor() == color) { - ArrayList jump_moves = generateJumpMoves(this.representation[i][j]); + ArrayList jump_moves = generateJumpMovesForPiece(this.representation[i][j]); frontier.addAll(jump_moves); } } @@ -254,13 +270,13 @@ public ArrayList generateJumpMoveFrontier(Color color) { return frontier; } - public ArrayList generateMoveMoveFrontier(Color color) { + public ArrayList generateAllRegularMoves(Color color) { ArrayList frontier = new ArrayList(); for (int i = 0; i < BOARD_SIZE; ++i) { for (int j = 0; j < BOARD_SIZE; ++j) { Piece p = this.representation[i][j]; if(null != p && p.getColor() == color) { - ArrayList moves = generateMoves(this.representation[i][j]); + ArrayList moves = generateRegularMovesForPiece(this.representation[i][j]); frontier.addAll(moves); } } @@ -268,14 +284,6 @@ public ArrayList generateMoveMoveFrontier(Color color) { return frontier; } - public ArrayList generateAllPossibleMoves(Color color) { - ArrayList from_jumps = generateJumpMoveFrontier(color); - if (from_jumps.isEmpty()) { - return generateMoveMoveFrontier(color); - } - return from_jumps; - } - /** * Print the current board representation */ @@ -301,6 +309,11 @@ else if (representation[row][col].getColor() == Color.BLACK) { } } + public boolean isValidSquare(Location location) { + return 0 <= location.row && location.row < BOARD_SIZE && + 0 <= location.column && location.column < BOARD_SIZE; + } + /** * Determines whether a move is a valid jump. * @param move @@ -331,6 +344,14 @@ public boolean isOccupied(Location location) { return representation[location.row][location.column] != null; } + public boolean canPromote(Piece p) { + int row = p.getLocation().row; + + return p.getType() != Type.KING && + ((row == 0 && p.getColor() == Color.WHITE) || + (row == BOARD_SIZE - 1 && p.getColor() == Color.BLACK)); + } + public Piece getPiece(Location location) { return representation[location.row][location.column]; } diff --git a/src/test/GameTest.java b/src/test/GameTest.java index cd2219c..fffe6c2 100644 --- a/src/test/GameTest.java +++ b/src/test/GameTest.java @@ -40,15 +40,6 @@ public static void main(String[] args) { public void run() { CheckersWindow window = new CheckersWindow(game); window.open(); - - new Thread(new Runnable() { - - @Override - public void run() { - game.playVsThunk(); - } - - }).start();; } }); diff --git a/src/view/Checker.java b/src/view/Checker.java deleted file mode 100644 index 856e4c3..0000000 --- a/src/view/Checker.java +++ /dev/null @@ -1,66 +0,0 @@ -package view; - -import java.awt.*; - -import javax.swing.*; - -/** - * Represents a graphical checkers piece on the checkers canvas. - * @author john - * - */ -@SuppressWarnings("serial") -public class Checker extends JPanel { - - /* The color of the checker */ - public final model.Color color; - - public Checker(model.Color color) { - super(); - this.color = color; - initChecker(); - } - - /** - * Initializes the properties of the Checker as a JButton - */ - private void initChecker() { - this.setFocusable(false); - this.setOpaque(false); - this.setEnabled(false); - } - - /** - * Overrides the JButton's painComponent method to paint a circle which - * represents the checkers piece. - */ - @Override - protected void paintComponent(Graphics g) { - /* Cast to a 2D graphics object */ - Graphics2D g2 = (Graphics2D) g; - - /* Add some hints from rendering */ - RenderingHints hints = new RenderingHints(null); - hints.put(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - hints.put(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - hints.put(RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_QUALITY); - g2.setRenderingHints(hints); - - /* Set the graphics object's color to the checker's color - * and paint an oval which represents the checker. */ - if (this.color == model.Color.WHITE) { - g2.setColor(new Color(0xB1B2B3)); - } - if (this.color == model.Color.BLACK) { - g2.setColor(new Color(89, 89, 89)); - } - g2.fillOval(5, 5, getSize().width-10,getSize().height-10); - - /* Make a call to the super classes painComponent method */ - super.paintComponent(g2); - } - -} diff --git a/src/view/CheckersCanvas.java b/src/view/CheckersCanvas.java index 393ea3d..24100ec 100644 --- a/src/view/CheckersCanvas.java +++ b/src/view/CheckersCanvas.java @@ -7,6 +7,7 @@ import javax.swing.JPanel; import model.Location; +import model.Move; import model.Color; /** @@ -46,13 +47,13 @@ private void initSquares(GameEventListener boardListener) { if (i % 2 != 0) { for (int j = 0; j < BOARD_DIM/2; ++j) { /* Create a black square */ - Square blackSquare = new Square(java.awt.Color.BLACK, new Location(i, j*2)); + Square blackSquare = new Square(Color.BLACK, new Location(i, j*2)); board[i][j*2] = blackSquare; blackSquare.addMouseListener(boardListener); this.add(blackSquare); /* Create a white square */ - Square whiteSquare = new Square(new java.awt.Color(150, 0, 0), new Location(i, j*2 + 1)); + Square whiteSquare = new Square(Color.WHITE, new Location(i, j*2 + 1)); board[i][j*2 + 1] = whiteSquare; whiteSquare.addMouseListener(boardListener); this.add(whiteSquare); @@ -60,13 +61,13 @@ private void initSquares(GameEventListener boardListener) { } else { for (int j = 0; j < BOARD_DIM/2; ++j) { /* Create a white square */ - Square whiteSquare = new Square(new java.awt.Color(150, 0, 0), new Location(i, j*2)); + Square whiteSquare = new Square(Color.WHITE, new Location(i, j*2)); board[i][j*2] = whiteSquare; whiteSquare.addMouseListener(boardListener); this.add(whiteSquare); /* Create a black square */ - Square blackSquare = new Square(java.awt.Color.BLACK, new Location(i, j*2 + 1)); + Square blackSquare = new Square(Color.BLACK, new Location(i, j*2 + 1)); board[i][j*2 + 1] = blackSquare; blackSquare.addMouseListener(boardListener); this.add(blackSquare); @@ -78,11 +79,9 @@ private void initSquares(GameEventListener boardListener) { private void initCheckers() { for (int row = 0; row < BOARD_DIM / 2 - 1; ++row) { for (int col = 0; col < BOARD_DIM / 2; ++col) { - Checker whiteChecker = new Checker(Color.WHITE); - Checker blackChecker = new Checker(Color.BLACK); - board[BOARD_DIM - 1 - row][2*col+ (row % 2)].setPiece(whiteChecker); + board[BOARD_DIM - 1 - row][2*col+ (row % 2)].placePiece(Color.WHITE); board[row][2*col + (BOARD_DIM - 1 - row) %2] - .setPiece(blackChecker); + .placePiece(Color.BLACK); } } } @@ -105,22 +104,21 @@ public void invalidateAllSquares() { } } - public void moveChecker(Location source, Location destination) { - if (board[source.row][source.column].hasPiece()) { - System.out.println("Has piece"); + public void removePiece(Location location) { + board[location.row][location.column].removePiece(); + } + + public void movePiece(Move move) { + if (board[move.source.row][move.source.column].isKing()) { + board[move.source.row][move.source.column].setKing(false); + board[move.destination.row][move.destination.column].setKing(true); } - board[destination.row][destination.column].setPiece(board[source.row] - [source.column].getPiece()); - board[source.row][source.column].setPiece(null); - this.revalidate(); + Color color = board[move.source.row][move.source.column].removePiece(); + board[move.destination.row][move.destination.column].placePiece(color); this.repaint(); - } - public void removeChecker(Location location) { - board[location.row][location.column].removePiece(); - board[location.row][location.column].setPiece(null); - this.revalidate(); - this.repaint(); + public Square getSquare(Location location) { + return board[location.row][location.column]; } } diff --git a/src/view/GameEventListener.java b/src/view/GameEventListener.java index 056de2c..02141eb 100644 --- a/src/view/GameEventListener.java +++ b/src/view/GameEventListener.java @@ -9,6 +9,8 @@ import javax.swing.JOptionPane; +import controller.GameConstants; + /** * Represents an object which listens for any events which occur in the UI * @author john @@ -33,14 +35,18 @@ public void mouseExited(MouseEvent e) {} @Override public void mousePressed(MouseEvent e) { Square square = (Square) e.getComponent(); - if(square.hasPiece() && gamePanel.isTurn(square.getPiece().color)) { - gamePanel.dehighlightAllSquares(); + if (square.hasPiece() && !gamePanel.isInJumpSequence() + && square.getPieceColor() == GameConstants.USER_COLOR + && (!gamePanel.isForceJump() || square.hasPiece() + && square.isValid())) { + gamePanel.dehighlightValidDestinations(); gamePanel.setMoveSource(square); if (square.isSelected()) gamePanel.highlightValidDestinations(square.getCellLocation()); gamePanel.updateMoveMessage(); } else if (square.isValid()) { gamePanel.setMoveDestination(square); + gamePanel.moveSelectedPiece(); gamePanel.updateMoveMessage(); } @@ -54,9 +60,7 @@ public void keyPressed(KeyEvent arg0) {} @Override public void keyReleased(KeyEvent e) { - if(e.getKeyCode() == KeyEvent.VK_ENTER && gamePanel.moveReady()) { - gamePanel.moveSelectedPiece(); - } + } @Override diff --git a/src/view/GamePanel.java b/src/view/GamePanel.java index 6c4c100..8c0831b 100644 --- a/src/view/GamePanel.java +++ b/src/view/GamePanel.java @@ -8,9 +8,12 @@ import javax.swing.JPanel; import controller.Game; +import controller.GameConstants; import model.Color; import model.Location; import model.Move; +import model.Piece; +import model.Type; /** * Represents the panel which will hold all of the graphical @@ -114,41 +117,83 @@ public void highlightValidDestinations(Location source) { } } - public void dehighlightAllSquares() { + public void dehighlightValidDestinations() { canvas.invalidateAllSquares(); } + public void movePiece(Move move) { + if (move.isJump()) { + int monkeyRow = (move.destination.row + move.source.row)/2; + int monkeyCol = (move.destination.column + move.source.column)/2; + + /* Remove the piece being jumped ("monkey in the middle") */ + canvas.removePiece(new Location(monkeyRow, monkeyCol)); + } + + canvas.movePiece(move); + + if (canPromote(canvas.getSquare(move.destination))) { + canvas.getSquare(move.destination).promotePiece(); + } + } + public void moveSelectedPiece() { - Move theMove = new Move(moveSource.getCellLocation(), moveDestination.getCellLocation()); - game.movePiece(theMove); - canvas.moveChecker(moveSource.getCellLocation(), moveDestination.getCellLocation()); - dehighlightAllSquares(); + /* Create the move */ + Move move = new Move(moveSource.getCellLocation(), moveDestination.getCellLocation()); + + /* Request the move */ + game.requestMove(move); + + /* Get rid of valid destination options */ + dehighlightValidDestinations(); + + /* If the user just jumped and the game is still in a jump sequence */ + /* Select the same piece again */ + if (move.isJump() && game.isInJumpSequence()) { + moveDestination.setSelected(true); + highlightValidDestinations(moveDestination.getCellLocation()); + moveSource = moveDestination; + moveDestination = null; + } else { + /* Reset the move choices */ + resetMove(); + } + + /* See if any jump moves are available */ + ArrayList jumpMoves = + game.getAllAvailableJumpMoves(GameConstants.USER_COLOR); + + if (!jumpMoves.isEmpty()) { + for (Move jump : jumpMoves) { + canvas.highlightAndValidateSquare(jump.source); + } + } + + } + + public void resetMove() { moveSource.setSelected(false); moveDestination.setSelected(false); moveSource = null; moveDestination = null; - if(!theMove.isJump()) { - game.switchTurn(); - } else { - Location monkeyLoc = new Location((theMove.destination.row - + theMove.source.row)/2, - (theMove.source.column - + theMove.destination.column) / 2); - System.out.println(monkeyLoc); - removePiece(monkeyLoc); - } } - public void removePiece(Location location ) { - canvas.removeChecker(location); + public boolean canPromote(Square square) { + int row = square.getCellLocation().row; + + return !square.isKing() && + ((row == 0 && square.getPieceColor() == Color.WHITE) || + (row == CheckersCanvas.BOARD_DIM - 1 && + square.getPieceColor() == Color.BLACK)); } - public void moveArbitraryPiece(Move move) { - canvas.moveChecker(move.source, move.destination); + + public boolean isInJumpSequence() { + return game.isInJumpSequence(); } - public boolean isTurn(Color color) { - return color == game.getCurrentTurn(); + public boolean isForceJump() { + return !game.getAllAvailableJumpMoves(GameConstants.USER_COLOR).isEmpty(); } } diff --git a/src/view/Square.java b/src/view/Square.java index 785ca8f..b2eecd9 100644 --- a/src/view/Square.java +++ b/src/view/Square.java @@ -1,8 +1,14 @@ package view; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import model.Color; import model.Location; /** @@ -12,17 +18,17 @@ * */ @SuppressWarnings("serial") -public class Square extends JPanel implements MouseListener { +public class Square extends JPanel { /** * The {@link Location} (row, col) of the square on the board. */ private final Location location; - /** - * The {@link Checker} object contained in this square. Null if there is none. - */ - private Checker piece; + private boolean hasPiece; + + private Color pieceColor; + /** * A boolean value representing whether the square is selected for movement. @@ -30,6 +36,8 @@ public class Square extends JPanel implements MouseListener { private boolean selected; private boolean valid; + + private boolean king; /** @@ -41,6 +49,8 @@ public Square(Color color, Location location) { super(); this.location = location; this.selected = false; + this.king = false; + this.valid = false; initSquare(color); } @@ -50,8 +60,11 @@ public Square(Color color, Location location) { * @param color A {@link Color} object representing the square's color. */ private void initSquare(Color color) { - this.setBackground(color); - this.setLayout(new BorderLayout()); + if (color == Color.BLACK) { + this.setBackground(java.awt.Color.BLACK); + } else if (color == Color.WHITE) { + this.setBackground(new java.awt.Color(150, 0, 0)); + } } @@ -62,32 +75,6 @@ public Location getCellLocation() { return location; } - /** - * {@link Square#piece} - */ - public Checker getPiece() { - return piece; - } - - /** - * Adds the given piece to the square's panel. - * @param piece A {@link Checker} object to place in the square. - */ - public void setPiece(Checker piece) { - this.piece = piece; - if (piece != null) { - this.add(piece); - piece.addMouseListener(this); - } - this.validate(); - this.repaint(); - } - - public void removePiece() { - - this.remove(this.piece); - } - /** * {@link Square#selected} @@ -103,9 +90,9 @@ public boolean isSelected() { */ public void setSelected(boolean val) { if (val) { - this.setBorder(BorderFactory.createLineBorder(Color.GREEN)); + this.setBorder(BorderFactory.createLineBorder(java.awt.Color.GREEN)); } else if (valid){ - this.setBorder(BorderFactory.createLineBorder(Color.YELLOW)); + this.setBorder(BorderFactory.createLineBorder(java.awt.Color.YELLOW)); } else { this.setBorder(null); } @@ -126,39 +113,95 @@ public boolean isValid() { * false otherwise. */ public boolean hasPiece() { - return this.piece != null; + return hasPiece; } - - @Override - public void mousePressed(MouseEvent e) { - /* Send the event to the lister of the square (GameEventListener) */ - MouseEvent newE = new MouseEvent(this, e.getID(), e.getWhen(), e.getModifiers(), - e.getClickCount(), e.getX(), e.getY(), e.isPopupTrigger()); - this.dispatchEvent(newE); + + public void promotePiece() { + System.out.println("Kinged"); + this.king = true; + } + + public boolean isKing() { + return king; } - @Override - public void mouseClicked(MouseEvent arg0) {} - @Override - public void mouseEntered(MouseEvent arg0) {} + public void highlight() { + this.setBorder(BorderFactory.createLineBorder(java.awt.Color.YELLOW)); - @Override - public void mouseExited(MouseEvent arg0) {} + } + /** + * Overrides the paintComponent method to paint a circle which + * represents the checkers piece. + */ @Override - public void mouseReleased(MouseEvent arg0) {} + protected void paintComponent(Graphics g) { + + /* Cast to a 2D graphics object */ + Graphics2D g2 = (Graphics2D) g; + /* Make a call to the super classes painComponent method */ + super.paintComponent(g2); + if (hasPiece) { + /* Add some hints from rendering */ + RenderingHints hints = new RenderingHints(null); + hints.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + hints.put(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); + hints.put(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + g2.setRenderingHints(hints); + + /* Set the graphics object's color to the checker's color + * and paint an oval which represents the checker. */ + if (this.pieceColor == Color.WHITE) { + g2.setColor(new java.awt.Color(0xB1B2B3)); + g2.fillOval(5, 5, getSize().width-10,getSize().height-10); + g2.setColor(java.awt.Color.BLACK); + if (king) { + g2.setFont(new Font("Courier", Font.PLAIN, 24)); + g2.drawString("KING", this.getWidth()/2 - 26, this.getHeight()/2 + 6); + } + } else if (this.pieceColor == Color.BLACK) { + g2.setColor(new java.awt.Color(89, 89, 89)); + g2.fillOval(5, 5, getSize().width-10,getSize().height-10); + g2.setColor(java.awt.Color.WHITE); + if (king) { + g2.setFont(new Font("Courier", Font.PLAIN, 24)); + g2.drawString("KING", this.getWidth()/2 - 26, this.getHeight()/2 + 6); + } + } + + } + } + public void dehighlight() { + this.setBorder(null); - public void highlight() { - this.setBorder(BorderFactory.createLineBorder(Color.YELLOW)); + } + public Color getPieceColor() { + return pieceColor; } - public void dehighlight() { - this.setBorder(null); + public void placePiece(Color color) { + this.hasPiece = true; + this.pieceColor = color; + } + + public Color removePiece() { + this.hasPiece = false; + Color color = this.pieceColor; + this.pieceColor = null; + this.king = false; + return color; + } + + public void setKing(boolean king) { + this.king = king; }