diff --git a/Day 43, 45, 46 (chess application design)/Chess.class b/Day 43, 45, 46 (chess application design)/Chess.class deleted file mode 100644 index 3fffbee..0000000 Binary files a/Day 43, 45, 46 (chess application design)/Chess.class and /dev/null differ diff --git a/Day 43, 45, 46 (chess application design)/GameState.class b/Day 43, 45, 46 (chess application design)/GameState.class deleted file mode 100644 index d46ce43..0000000 Binary files a/Day 43, 45, 46 (chess application design)/GameState.class and /dev/null differ diff --git a/Day 43, 45, 46 (chess application design)/Square.class b/Day 43, 45, 46 (chess application design)/Square.class deleted file mode 100644 index 6f73094..0000000 Binary files a/Day 43, 45, 46 (chess application design)/Square.class and /dev/null differ diff --git a/Day 43-51 (chess application)/Chess.class b/Day 43-51 (chess application)/Chess.class new file mode 100644 index 0000000..6171333 Binary files /dev/null and b/Day 43-51 (chess application)/Chess.class differ diff --git a/Day 43, 45, 46 (chess application design)/Chess.java b/Day 43-51 (chess application)/Chess.java similarity index 82% rename from Day 43, 45, 46 (chess application design)/Chess.java rename to Day 43-51 (chess application)/Chess.java index 77784a8..7db784c 100644 --- a/Day 43, 45, 46 (chess application design)/Chess.java +++ b/Day 43-51 (chess application)/Chess.java @@ -14,6 +14,12 @@ import javafx.scene.input.*; import javafx.scene.image.*; import javafx.geometry.*; +//TODO: +// Prevent moving into check +// Add castling +// Add en passant +// Give feedback for check, checkmate, and stalemate. + //Main class and GUI public class Chess extends Application { @@ -27,6 +33,7 @@ public class Chess extends Application { private GraphicsContext graphics; private TextArea moveHistoryTextArea; + private Label feedback; //Load images private static final Image W_ROOK = new Image("img/w_rook_png_shadow_128px.png"); @@ -71,14 +78,20 @@ public class Chess extends Application { hb.setAlignment(Pos.CENTER); root.getChildren().add(hb); + //Add a label for feedback + feedback = new Label(""); + HBox hb2 = new HBox(20, feedback); + hb2.setAlignment(Pos.CENTER); + root.getChildren().add(hb2); + //Set up buttons Button undo = new Button("Undo"); Button reset = new Button("Reset"); Button aiMove = new Button("AI move"); - HBox h = new HBox(20, undo, reset, aiMove); - h.setAlignment(Pos.CENTER); - h.setPadding(new Insets(10,10,10,10)); - root.getChildren().add(h); + HBox hb3 = new HBox(20, undo, reset, aiMove); + hb3.setAlignment(Pos.CENTER); + hb3.setPadding(new Insets(10,10,10,10)); + root.getChildren().add(hb3); //Set up empty move history, game history, notation history. gameStateHistory = new ArrayList(); @@ -107,10 +120,25 @@ public class Chess extends Application { } private void updateScreen() { + //Draw the board for(int x = 0; x < 8; x++) { for(int y = 0; y < 8; y++) { graphics.setFill((x + y) % 2 == 0 ? Color.BURLYWOOD : Color.FORESTGREEN); graphics.fillRect(50*x, 50*y, 50, 50); + } + } + + //Show the last move made in red + if (!moveHistory.isEmpty()) { + graphics.setFill(new Color(1, 0, 0, .6)); + Move m = moveHistory.get(moveHistory.size() - 1); + graphics.fillRect(50*m.getSourceCol(), 50*m.getSourceRow(), 50, 50); + graphics.fillRect(50*m.getDestCol(), 50*m.getDestRow(), 50, 50); + } + + //Draw the pieces + for(int x = 0; x < 8; x++) { + for(int y = 0; y < 8; y++) { Square s = board().getSquare(x, y); if ( s.getType() == Square.PAWN && s.isWhite()) graphics.drawImage(W_PAWN, 50*x, 50*y, 50, 50); if ( s.getType() == Square.PAWN && !s.isWhite()) graphics.drawImage(B_PAWN, 50*x, 50*y, 50, 50); @@ -124,8 +152,18 @@ public class Chess extends Application { if ( s.getType() == Square.QUEEN && !s.isWhite()) graphics.drawImage(B_QUEEN, 50*x, 50*y, 50, 50); if ( s.getType() == Square.KING && s.isWhite()) graphics.drawImage(W_KING, 50*x, 50*y, 50, 50); if ( s.getType() == Square.KING && !s.isWhite()) graphics.drawImage(B_KING, 50*x, 50*y, 50, 50); + } } + + //Highlight the selected square (if any) in yellow + if (clickRow != null) { + graphics.setFill(new Color(1, 1, 0, .5)); + graphics.fillRect(50*clickCol, 50*clickRow, 50, 50); + } + + //Update feedback + feedback.setText(board().getFeedback()); } private GameState board() { @@ -134,8 +172,6 @@ public class Chess extends Application { //Reset to the intial game position. public void reset(ActionEvent e) { - System.out.println(board().getAllPossibleMoves()); - //Clear out all the histories gameStateHistory = new ArrayList(); gameStateHistory.add(new GameState()); //Set up the initial board @@ -173,6 +209,8 @@ public class Chess extends Application { //Refresh the board updateScreen(); + + writeMoveHistoryForIndex(moveNotationHistory.size()-1); } //For the human moving @@ -195,7 +233,6 @@ public class Chess extends Application { //Undo button for the most recent move public void undo(ActionEvent e) { - //Pop those 3 history object things and update the GUI. if (gameStateHistory.size() <= 1) return; //can't pop the initial state. //Pop those 3 history object things and update the GUI. @@ -203,7 +240,22 @@ public class Chess extends Application { moveHistory.remove(moveHistory.size() - 1); moveNotationHistory.remove(moveNotationHistory.size() - 1); clickRow = clickCol = null; + refreshMoveHistoryDisplay(); updateScreen(); } + private void refreshMoveHistoryDisplay() { + moveHistoryTextArea.setText(""); + for(int i = 0; i < moveHistory.size(); i++) { + writeMoveHistoryForIndex(i); + } + } + + private void writeMoveHistoryForIndex(int ply) { + GameState g = gameStateHistory.get(ply); + Move m = moveHistory.get(ply); + if (g.isWhitesTurn()) moveHistoryTextArea.appendText("\n" + (ply/2+1) +". "+m); + else moveHistoryTextArea.appendText(" " +m); + } + } \ No newline at end of file diff --git a/Day 43-51 (chess application)/GameState.class b/Day 43-51 (chess application)/GameState.class new file mode 100644 index 0000000..3191571 Binary files /dev/null and b/Day 43-51 (chess application)/GameState.class differ diff --git a/Day 43, 45, 46 (chess application design)/GameState.java b/Day 43-51 (chess application)/GameState.java similarity index 81% rename from Day 43, 45, 46 (chess application design)/GameState.java rename to Day 43-51 (chess application)/GameState.java index 41b255b..c14b0d7 100644 --- a/Day 43, 45, 46 (chess application design)/GameState.java +++ b/Day 43-51 (chess application)/GameState.java @@ -47,6 +47,14 @@ public class GameState { boardSquares[move.getDestIndex()] = new Square(boardSquares[move.getSourceIndex()]); boardSquares[move.getSourceIndex()] = new Square(Square.EMPTY); + //Queening (no underpromotion for now) + if ((move.getDestRow() == 0 || move.getDestRow() == 7) && boardSquares[move.getDestIndex()].getType() == Square.PAWN) { + boolean w = boardSquares[move.getDestIndex()].isWhite(); + boardSquares[move.getDestIndex()] = new Square(Square.QUEEN, w); //Make that pawn a queen + } + + boardSquares[move.getDestIndex()].setHasMoved(); //For knowledge about moving pawns two squares and castling. + } @@ -71,37 +79,50 @@ public class GameState { for(int index = 0; index < boardSquares.length; index++) { int type = boardSquares[index].getType(); boolean w = boardSquares[index].isWhite(); + boolean pieceMoved = boardSquares[index].isMoved(); if (type == Square.OUT_OF_BOUNDS) continue; if (type == Square.EMPTY) continue; //For each square, find all possible places that piece can move to. - if (type == Square.KING) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, false)); - if (type == Square.QUEEN) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, true)); - if (type == Square.BISHOP) moves.addAll(findAllMovesFor(index, new int[] {13,-13,11,-11}, true)); - if (type == Square.ROOK) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12}, true)); - if (type == Square.KNIGHT) moves.addAll(findAllMovesFor(index, new int[] {10,14,23,25,-10,-14,-23,-25}, false)); - if (type == Square.PAWN && w) moves.addAll(findAllMovesFor(index, new int[] {12}, false)); - if (type == Square.PAWN && !w) moves.addAll(findAllMovesFor(index, new int[] {-12}, false)); + if (type == Square.KING) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, 1, true, true)); + if (type == Square.QUEEN) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12,13,-13,11,-11}, 99, true, true)); + if (type == Square.BISHOP) moves.addAll(findAllMovesFor(index, new int[] {13,-13,11,-11}, 99, true, true)); + if (type == Square.ROOK) moves.addAll(findAllMovesFor(index, new int[] {1,-1,12,-12}, 99, true, true)); + if (type == Square.KNIGHT) moves.addAll(findAllMovesFor(index, new int[] {10,14,23,25,-10,-14,-23,-25}, 1, true, true)); + + //white + if (type == Square.PAWN && w && pieceMoved) moves.addAll(findAllMovesFor(index, new int[] {12}, 1, true, false)); + if (type == Square.PAWN && w && !pieceMoved) moves.addAll(findAllMovesFor(index, new int[] {12}, 2, true, false)); + if (type == Square.PAWN && w) moves.addAll(findAllMovesFor(index, new int[] {11, 13}, 1, false, true)); + + //black + if (type == Square.PAWN && !w && pieceMoved) moves.addAll(findAllMovesFor(index, new int[] {-12}, 1, true, false)); + if (type == Square.PAWN && !w && !pieceMoved) moves.addAll(findAllMovesFor(index, new int[] {-12}, 2, true, false)); + if (type == Square.PAWN && !w) moves.addAll(findAllMovesFor(index, new int[] {-11, -13}, 1, false, true)); } return moves; } - private ArrayList findAllMovesFor(int index, int[] directions, boolean canMoveMultipleSquares) { + ///movementDistance is the number of times that piece can move in the given directions. + private ArrayList findAllMovesFor(int index, int[] directions, int movementDistance, boolean canMove, boolean canCapture) { ArrayList moves = new ArrayList(); if (boardSquares[index].isWhite() != isWhitesTurn) return moves; //don't move other person's pieces! //loop through the directions, see if they work - return the resulting arraylist. for(int dir : directions) { int destIndex = index; + int numMoves = movementDistance; do { destIndex += dir; int type = boardSquares[destIndex].getType(); if (type == Square.OUT_OF_BOUNDS) break; - if (type == Square.EMPTY || boardSquares[destIndex].isWhite() != isWhitesTurn) { + if (type == Square.EMPTY && canMove || + type != Square.EMPTY && type != Square.OUT_OF_BOUNDS && boardSquares[destIndex].isWhite() != isWhitesTurn && canCapture) { moves.add(new Move(index, destIndex)); } - } while(boardSquares[destIndex].getType() == Square.EMPTY && canMoveMultipleSquares); + numMoves--; + } while(boardSquares[destIndex].getType() == Square.EMPTY && numMoves > 0); } return moves; @@ -111,8 +132,8 @@ public class GameState { return isWhitesTurn; } - // returns something like "checkmate", "stalemate", etc. + // TODO: should also include information regarding check, checkmate, and stalemate. public String getFeedback() { - return null; + return isWhitesTurn ? "White's turn" : "Black's turn"; } } diff --git a/Day 43, 45, 46 (chess application design)/Move.class b/Day 43-51 (chess application)/Move.class similarity index 100% rename from Day 43, 45, 46 (chess application design)/Move.class rename to Day 43-51 (chess application)/Move.class diff --git a/Day 43, 45, 46 (chess application design)/Move.java b/Day 43-51 (chess application)/Move.java similarity index 100% rename from Day 43, 45, 46 (chess application design)/Move.java rename to Day 43-51 (chess application)/Move.java diff --git a/Day 43-51 (chess application)/Square.class b/Day 43-51 (chess application)/Square.class new file mode 100644 index 0000000..8af1829 Binary files /dev/null and b/Day 43-51 (chess application)/Square.class differ diff --git a/Day 43, 45, 46 (chess application design)/Square.java b/Day 43-51 (chess application)/Square.java similarity index 64% rename from Day 43, 45, 46 (chess application design)/Square.java rename to Day 43-51 (chess application)/Square.java index 28ca1f1..b72e5ab 100644 --- a/Day 43, 45, 46 (chess application design)/Square.java +++ b/Day 43-51 (chess application)/Square.java @@ -12,6 +12,8 @@ public class Square { private int type; //one of the 8 constants above. private boolean isWhite; + private boolean hasMoved; + private boolean isEnPassantSquare; //was jumped over by a pawn on the previous move. //en passant boolean flag (for the square that would be "captured") //boolean Knowledge of whether or not this piece moved yet (for castling) @@ -20,6 +22,8 @@ public class Square { public Square(Square s) { type = s.type; isWhite = s.isWhite; + hasMoved = s.hasMoved; + isEnPassantSquare = s.isEnPassantSquare; } public Square(int type) { @@ -29,6 +33,29 @@ public class Square { public Square(int type, boolean isWhite) { this.type = type; this.isWhite = isWhite; + hasMoved = false; + isEnPassantSquare = false; + } + + public void clearEnPassant() { + isEnPassantSquare = false; + } + + public boolean isEnPassantSquare() { + return isEnPassantSquare; + } + + public void setEnPassantSquare(boolean whiteMovedPawnTwo) { + isEnPassantSquare = true; + isWhite = whiteMovedPawnTwo; + } + + public void setHasMoved() { + hasMoved = true; + } + + public boolean isMoved() { + return hasMoved; } //Positive values for white, negative for black, blank square is 0. diff --git a/Day 43, 45, 46 (chess application design)/chess program design.txt b/Day 43-51 (chess application)/chess program design.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/chess program design.txt rename to Day 43-51 (chess application)/chess program design.txt diff --git a/Day 43, 45, 46 (chess application design)/control structure notes.txt b/Day 43-51 (chess application)/control structure notes.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/control structure notes.txt rename to Day 43-51 (chess application)/control structure notes.txt diff --git a/Day 43, 45, 46 (chess application design)/defensive programming.txt b/Day 43-51 (chess application)/defensive programming.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/defensive programming.txt rename to Day 43-51 (chess application)/defensive programming.txt diff --git a/Day 43, 45, 46 (chess application design)/img/Image license copyright notice.txt b/Day 43-51 (chess application)/img/Image license copyright notice.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/Image license copyright notice.txt rename to Day 43-51 (chess application)/img/Image license copyright notice.txt diff --git a/Day 43, 45, 46 (chess application design)/img/JohnPablok Cburnett Chess Zip.zip b/Day 43-51 (chess application)/img/JohnPablok Cburnett Chess Zip.zip similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/JohnPablok Cburnett Chess Zip.zip rename to Day 43-51 (chess application)/img/JohnPablok Cburnett Chess Zip.zip diff --git a/Day 43, 45, 46 (chess application design)/img/b_bishop_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_bishop_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_bishop_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_bishop_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/b_king_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_king_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_king_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_king_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/b_knight_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_knight_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_knight_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_knight_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/b_pawn_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_pawn_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_pawn_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_pawn_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/b_queen_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_queen_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_queen_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_queen_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/b_rook_png_shadow_128px.png b/Day 43-51 (chess application)/img/b_rook_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/b_rook_png_shadow_128px.png rename to Day 43-51 (chess application)/img/b_rook_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/square brown dark_png_shadow_128px.png b/Day 43-51 (chess application)/img/square brown dark_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/square brown dark_png_shadow_128px.png rename to Day 43-51 (chess application)/img/square brown dark_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/square brown light_png_shadow_128px.png b/Day 43-51 (chess application)/img/square brown light_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/square brown light_png_shadow_128px.png rename to Day 43-51 (chess application)/img/square brown light_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/square gray dark _png_shadow_128px.png b/Day 43-51 (chess application)/img/square gray dark _png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/square gray dark _png_shadow_128px.png rename to Day 43-51 (chess application)/img/square gray dark _png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/square gray light _png_shadow_128px.png b/Day 43-51 (chess application)/img/square gray light _png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/square gray light _png_shadow_128px.png rename to Day 43-51 (chess application)/img/square gray light _png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_bishop_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_bishop_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_bishop_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_bishop_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_king_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_king_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_king_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_king_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_knight_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_knight_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_knight_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_knight_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_pawn_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_pawn_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_pawn_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_pawn_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_queen_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_queen_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_queen_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_queen_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/img/w_rook_png_shadow_128px.png b/Day 43-51 (chess application)/img/w_rook_png_shadow_128px.png similarity index 100% rename from Day 43, 45, 46 (chess application design)/img/w_rook_png_shadow_128px.png rename to Day 43-51 (chess application)/img/w_rook_png_shadow_128px.png diff --git a/Day 43, 45, 46 (chess application design)/refactoring Move.txt b/Day 43-51 (chess application)/refactoring Move.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/refactoring Move.txt rename to Day 43-51 (chess application)/refactoring Move.txt diff --git a/Day 43, 45, 46 (chess application design)/requirements and spec.txt b/Day 43-51 (chess application)/requirements and spec.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/requirements and spec.txt rename to Day 43-51 (chess application)/requirements and spec.txt diff --git a/Day 43, 45, 46 (chess application design)/writing good methods.txt b/Day 43-51 (chess application)/writing good methods.txt similarity index 100% rename from Day 43, 45, 46 (chess application design)/writing good methods.txt rename to Day 43-51 (chess application)/writing good methods.txt