diff --git a/src/controller/Game.java b/src/controller/Game.java index b761969..8e5a462 100755 --- a/src/controller/Game.java +++ b/src/controller/Game.java @@ -3,32 +3,115 @@ 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; public class Game { private Board board; private Color current_turn; + private GamePanel panel; + + + public Game(Board board) { + this.board = board; + current_turn = Color.BLACK; + } public void movePiece(Move move) { - board.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); + } + } + + public void switchTurn() { + this.current_turn = this.current_turn == Color.BLACK ? + Color.WHITE : Color.BLACK; } 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; + } ArrayList moves = board.generateMoves(board.getPiece(source)); ArrayList jumps = board.generateJumpMoves(board.getPiece(source)); ArrayList allMoves = new ArrayList(moves); - if (allMoves.isEmpty()) - System.out.println("No available 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 void setGamePanel(GamePanel panel) { + this.panel = panel; + } - public Game(Color start) { - this.board = new Board(); - current_turn = start; + public Color getCurrentTurn() { + return current_turn; } } diff --git a/src/model/Board.java b/src/model/Board.java index 46629e7..fbb5ceb 100755 --- a/src/model/Board.java +++ b/src/model/Board.java @@ -14,6 +14,8 @@ public class Board { // Board properties and representation private final int BOARD_SIZE = 8; private Piece[][] representation; + + private Piece lastPieceMoved; // Move properties private int movesSinceCapture; @@ -24,7 +26,7 @@ public Board() { representation = new Piece[BOARD_SIZE][BOARD_SIZE]; movesSinceCapture = 0; init(); - + lastPieceMoved = null; } /** @@ -40,6 +42,7 @@ public Board(Board other) { } } movesSinceCapture = other.getMovesSinceCapture(); + lastPieceMoved = other.getLastPieceMoved(); } public boolean isValidSquare(Location location) { @@ -146,6 +149,8 @@ public void move(Move move) { 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; } /** @@ -159,6 +164,11 @@ public void jump(Move jump) { 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; } /** @@ -230,6 +240,42 @@ public ArrayList generateFrontier(Color color) { return from_jumps; } + public ArrayList generateJumpMoveFrontier(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]); + frontier.addAll(jump_moves); + } + } + } + return frontier; + } + + public ArrayList generateMoveMoveFrontier(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]); + frontier.addAll(moves); + } + } + } + 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 */ @@ -296,6 +342,10 @@ public Piece[][] getRepresentation() { public int getMovesSinceCapture() { return this.movesSinceCapture; + } + + public Piece getLastPieceMoved() { + return this.lastPieceMoved; } } diff --git a/src/model/Location.java b/src/model/Location.java index 70db62a..1192e4f 100644 --- a/src/model/Location.java +++ b/src/model/Location.java @@ -22,4 +22,9 @@ public Location(Location other) { public boolean equals(Location other) { return this.row == other.row && this.column == other.column; } + + @Override + public String toString() { + return "(" + this.row + ", " + this.column + ")"; + } } diff --git a/src/model/Move.java b/src/model/Move.java index ccfe1d8..5e288bf 100644 --- a/src/model/Move.java +++ b/src/model/Move.java @@ -9,5 +9,15 @@ public Move(Location source, Location destination) { this.destination = destination; } + public boolean isJump() { + return Math.abs(source.column - destination.column) == 2 + && Math.abs(source.row - destination.row) == 2; + } + + @Override + public String toString() { + return "From (" + this.source.row + ", " + this.source.column + ")" + + " to (" + this.destination.row + ", " + this.destination.column + ")"; + } } diff --git a/src/model/Piece.java b/src/model/Piece.java index e38315d..2705ec8 100755 --- a/src/model/Piece.java +++ b/src/model/Piece.java @@ -48,4 +48,9 @@ public boolean equals(Piece other) { this.location.equals(other.getLocation()) && this.type == other.getType(); } + + @Override + public String toString() { + return "Piece(" + this.color + ", " + this.location + ", " + this.type + ")"; + } } diff --git a/src/test/GUITest.java b/src/test/GameTest.java similarity index 60% rename from src/test/GUITest.java rename to src/test/GameTest.java index f51d371..cd2219c 100644 --- a/src/test/GUITest.java +++ b/src/test/GameTest.java @@ -1,13 +1,15 @@ package test; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import controller.Game; +import model.Board; import model.Color; import view.CheckersWindow; -public class GUITest { +public class GameTest { public static void main(String[] args) { @@ -29,7 +31,26 @@ public static void main(String[] args) { catch (IllegalAccessException e) { // handle exception } - CheckersWindow window = new CheckersWindow(new Game(Color.WHITE)); - window.open(); + Board board = new Board(); + + final Game game = new Game(board); + + SwingUtilities.invokeLater(new Runnable() { + @Override + 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 index 421aeba..856e4c3 100644 --- a/src/view/Checker.java +++ b/src/view/Checker.java @@ -1,6 +1,7 @@ package view; import java.awt.*; + import javax.swing.*; /** @@ -12,9 +13,9 @@ public class Checker extends JPanel { /* The color of the checker */ - private Color color; + public final model.Color color; - public Checker(Color color) { + public Checker(model.Color color) { super(); this.color = color; initChecker(); @@ -50,7 +51,12 @@ protected void paintComponent(Graphics g) { /* Set the graphics object's color to the checker's color * and paint an oval which represents the checker. */ - g2.setColor(color); + 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 */ diff --git a/src/view/CheckersCanvas.java b/src/view/CheckersCanvas.java index c0b61e0..393ea3d 100644 --- a/src/view/CheckersCanvas.java +++ b/src/view/CheckersCanvas.java @@ -1,6 +1,5 @@ package view; -import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridLayout; @@ -8,6 +7,7 @@ import javax.swing.JPanel; import model.Location; +import model.Color; /** * Represents the canvas on which the checkers board is drawn. @@ -46,13 +46,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(Color.BLACK, new Location(i, j*2)); + Square blackSquare = new Square(java.awt.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 Color(150, 0, 0), new Location(i, j*2 + 1)); + Square whiteSquare = new Square(new java.awt.Color(150, 0, 0), new Location(i, j*2 + 1)); board[i][j*2 + 1] = whiteSquare; whiteSquare.addMouseListener(boardListener); this.add(whiteSquare); @@ -60,13 +60,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 Color(150, 0, 0), new Location(i, j*2)); + Square whiteSquare = new Square(new java.awt.Color(150, 0, 0), new Location(i, j*2)); board[i][j*2] = whiteSquare; whiteSquare.addMouseListener(boardListener); this.add(whiteSquare); /* Create a black square */ - Square blackSquare = new Square(Color.BLACK, new Location(i, j*2 + 1)); + Square blackSquare = new Square(java.awt.Color.BLACK, new Location(i, j*2 + 1)); board[i][j*2 + 1] = blackSquare; blackSquare.addMouseListener(boardListener); this.add(blackSquare); @@ -78,8 +78,8 @@ 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(new Color(0xB1B2B3)); - Checker blackChecker = new Checker(new Color(89, 89, 89)); + Checker whiteChecker = new Checker(Color.WHITE); + Checker blackChecker = new Checker(Color.BLACK); board[BOARD_DIM - 1 - row][2*col+ (row % 2)].setPiece(whiteChecker); board[row][2*col + (BOARD_DIM - 1 - row) %2] .setPiece(blackChecker); @@ -106,9 +106,21 @@ public void invalidateAllSquares() { } public void moveChecker(Location source, Location destination) { + if (board[source.row][source.column].hasPiece()) { + System.out.println("Has piece"); + } board[destination.row][destination.column].setPiece(board[source.row] [source.column].getPiece()); board[source.row][source.column].setPiece(null); + this.revalidate(); + this.repaint(); } + + public void removeChecker(Location location) { + board[location.row][location.column].removePiece(); + board[location.row][location.column].setPiece(null); + this.revalidate(); + this.repaint(); + } } diff --git a/src/view/CheckersWindow.java b/src/view/CheckersWindow.java index 9a89393..ec64f69 100644 --- a/src/view/CheckersWindow.java +++ b/src/view/CheckersWindow.java @@ -100,6 +100,7 @@ private void createMenuBar() { */ private void initGamePanel(Game game) { this.gamePanel = new GamePanel(game, gameListener); + game.setGamePanel(this.gamePanel); this.getContentPane().add(this.gamePanel); this.gameListener.setGamePanel(gamePanel); } diff --git a/src/view/GameEventListener.java b/src/view/GameEventListener.java index 7d6cbec..056de2c 100644 --- a/src/view/GameEventListener.java +++ b/src/view/GameEventListener.java @@ -33,7 +33,7 @@ public void mouseExited(MouseEvent e) {} @Override public void mousePressed(MouseEvent e) { Square square = (Square) e.getComponent(); - if(square.hasPiece()) { + if(square.hasPiece() && gamePanel.isTurn(square.getPiece().color)) { gamePanel.dehighlightAllSquares(); gamePanel.setMoveSource(square); if (square.isSelected()) @@ -57,7 +57,6 @@ 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 7068706..6c4c100 100644 --- a/src/view/GamePanel.java +++ b/src/view/GamePanel.java @@ -8,6 +8,7 @@ import javax.swing.JPanel; import controller.Game; +import model.Color; import model.Location; import model.Move; @@ -29,6 +30,7 @@ public class GamePanel extends JPanel { private Square moveDestination; private Square moveSource; + public GamePanel(Game game, GameEventListener gameListener) { super(new GridBagLayout()); @@ -116,14 +118,37 @@ public void dehighlightAllSquares() { canvas.invalidateAllSquares(); } + public void moveSelectedPiece() { - game.movePiece(new Move(moveSource.getCellLocation(), moveDestination.getCellLocation())); + Move theMove = new Move(moveSource.getCellLocation(), moveDestination.getCellLocation()); + game.movePiece(theMove); canvas.moveChecker(moveSource.getCellLocation(), moveDestination.getCellLocation()); dehighlightAllSquares(); 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 void moveArbitraryPiece(Move move) { + canvas.moveChecker(move.source, move.destination); + } + + public boolean isTurn(Color color) { + return color == game.getCurrentTurn(); } - } diff --git a/src/view/Square.java b/src/view/Square.java index b51112b..785ca8f 100644 --- a/src/view/Square.java +++ b/src/view/Square.java @@ -78,9 +78,16 @@ public void setPiece(Checker piece) { if (piece != null) { this.add(piece); piece.addMouseListener(this); - this.validate(); - } + } + this.validate(); + this.repaint(); + } + + public void removePiece() { + + this.remove(this.piece); } + /** * {@link Square#selected}