From aa7bb032efbbb2d66685934bf25a9eef05941af7 Mon Sep 17 00:00:00 2001 From: Alex Wang Date: Thu, 17 Dec 2020 14:53:12 -0500 Subject: [PATCH] formatting --- src/main/java/domain/Logic/Game.java | 397 +++++++++---------- src/main/java/domain/UserInterface/UI.java | 4 +- target/classes/domain/Logic/Game.class | Bin 14444 -> 13116 bytes target/classes/domain/UserInterface/UI.class | Bin 3451 -> 3506 bytes 4 files changed, 193 insertions(+), 208 deletions(-) diff --git a/src/main/java/domain/Logic/Game.java b/src/main/java/domain/Logic/Game.java index 57c1ee2..ce8bd74 100644 --- a/src/main/java/domain/Logic/Game.java +++ b/src/main/java/domain/Logic/Game.java @@ -1,27 +1,23 @@ package domain.Logic; - /* CRUD CLI Chess game -implemenet checkmate detection to automatically end game +*** TODO implemenet checkmate detection to automatically end game + */ + import java.util.ArrayList; -import java.util.EnumMap; import java.util.List; -import java.util.Map; import domain.Logic.Color.ColorType; -/* - castling - does it go thru threatened square - get rid of unused lists -*/ import domain.Pieces.Pawn; import domain.Pieces.Piece; import domain.Pieces.PieceType; import domain.Pieces.Queen; public class Game { + public boolean over = false; private Board board; @@ -30,24 +26,14 @@ public class Game { private List previousMoves; - private Map> pieceskilled; - - private List whiteCapturedBlack; - - private List blackCapturedWhite; - private int current; private static Game g = new Game(); private Game() { - board = new Board(); previousMoves = new ArrayList<>(); currentplayer = ColorType.White; - pieceskilled = new EnumMap<>(ColorType.class); - whiteCapturedBlack = new ArrayList<>(); - blackCapturedWhite = new ArrayList<>(); current = 0; } @@ -63,10 +49,10 @@ public boolean isCheckMate() { return over; } - //Starting point of each move, returns true only if the move was valid and executed + // Starting point of each move, returns true only if the move was valid and executed + + public boolean tryMove(int startx, int starty, int endx, int endy) { - public boolean tryMove(int startx, int starty, int endx, int endy) { - if (!inBounds(startx, starty) || !inBounds(endx, endy)) return false; @@ -77,17 +63,17 @@ public boolean tryMove(int startx, int starty, int endx, int endy) { Piece startPiece = start.getPiece(); Piece killedPiece = end.getPiece(); - //to avoid null pointer - if (startPiece == null) { + // to avoid null pointer + if (startPiece == null) { Errors.noSuchPieceExists(start); return false; } if (isPawn(startPiece)) { - return checkPawnMove(start, end, startPiece, killedPiece); //handles enpasssant and promotion + return checkPawnMove(start, end, startPiece, killedPiece); // handles enpasssant and promotion } - if (checkValidCastling(start, end)) { + if (checkValidCastling(start, end)) { castlePieces(start, end); return true; } @@ -100,83 +86,68 @@ else if (checkSoundMove(start, end, startPiece, killedPiece)) { return false; } - private boolean checkSoundMove(Square start, Square end, Piece startPiece, Piece killedPiece) { - - if (start.equals(end)) { - Errors.displayNoMovement(); + private boolean checkPawnMove(Square start, Square end, Piece pawn, Piece killedPiece) { + if (!checkSoundMove(start, end, pawn, killedPiece)) return false; - } - boolean test = isOwnedPiece(startPiece); - - if (!test) { - System.out.println("You do not own " + startPiece.getReadablePiece() + " at " + start.getCoord() + " silly"); - return false; + if (getPrevMove() != null && isEnPassant(getPrevMove(), start.getCoord(), end.getCoord(), pawn)) { + System.out.println("You just got enpassanted cuhhhhhhh at " + end.getCoord()); + executeMove(start, end, pawn, killedPiece); + return true; } - test = moveMakesCheck(start, end) && startPiece.getType() != PieceType.KING; // does the move cause the current player to get in check - //buggy, checking - if (test) { - System.out.println("Cannot move " + startPiece.getReadablePiece() + " at " + start.getCoord() - + " as you are in check"); - return false; - } else if (moveMakesCheck(start, end)) { // not sure if best practice to have my checkout detection with this, - // could be just a bad king move - over = true; + if (isValidPromotion(pawn, start, end)) { // checks if it is promotion move, could offer better signifers bc + // just executing move says a queen made promotion + pawn = new Queen(pawn.getColor()); + executeMove(start, end, pawn, null); + return true; } - test = isFriendlyFire(startPiece, killedPiece); + Pawn pPawn = (Pawn) pawn; + boolean test = pPawn.validOrNah(start.getCoord(), end.getCoord(), killedPiece) && checkPiecesPath( + pawn.getPiecePath(start.getCoord(), end.getCoord()), start.getCoord(), end.getCoord()); if (test) { - System.out.println("Cannot take your own piece silly"); + executeMove(start, end, pawn, killedPiece); // passes + return true; + } else { + System.out.println("Illegal pawn manuever at " + start.getCoord()); return false; } - - return true; } - private boolean moveMakesCheck(Square start, Square end) { - Piece temp = end.getPiece(); - end.setPiece(start.getPiece()); - start.killPiece(); - boolean causedCheck = false; - Pair kingXY = getKingPos(board.getBoard()); + private boolean isEnPassant(Move prevMove, Pair start, Pair end, Piece pawn) { + Piece opponentPiece = prevMove.getPieceMoved(); - if (isPieceBeingAttkd(kingXY)) { - causedCheck = true; - } - start.setPiece(end.getPiece()); // reset it back into place - end.setPiece(temp); + if (checkEnPassantCond(prevMove, opponentPiece, pawn)) + return false; - return causedCheck; - } + if (opponentPiece.getColor() == ColorType.Black && prevMove.getEndingPair().getY() == start.getY()) { // white + // captures + // black + // en + // passant + return end.getY() + 1 == prevMove.getEndingPair().getY() && end.getX() == prevMove.getEndingPair().getX(); + } - private boolean isPieceBeingAttkd(Pair endXY){ - Square[][] bd = board.getBoard(); - for (int rank = 0; rank < bd.length; rank++) { - for (int file = 0; file < bd.length; file++) { - Square sq = bd[rank][file]; - if (sq.hasPiece()) { - Piece pieceHere = sq.getPiece(); - Pair startXY = sq.getCoord(); - if (pieceHasValidRoute(pieceHere, startXY, endXY)) - return true; - } - } + if (opponentPiece.getColor() == ColorType.White && prevMove.getEndingPair().getY() == start.getY()) { // black + // captures + // white + return end.getY() - 1 == prevMove.getEndingPair().getY() && end.getX() == prevMove.getEndingPair().getX(); } + return false; } - /* - will return false, when it is an owned piece, the attacking move is invalid, and when there are obstructions in the then validated path - */ - private boolean pieceHasValidRoute(Piece startPiece, Pair startXY, Pair kingXY) { + private boolean checkEnPassantCond(Move prevMove, Piece opponentPiece, Piece pawn) { // sees if it satisfies basic + // prereqs + + return !(!isPawn(opponentPiece) || prevMove.getEndingPair().getY() != 3 || prevMove.getEndingPair().getY() != 6 + || opponentPiece.getColor() == pawn.getColor()); - return !isOwnedPiece(startPiece) && startPiece.validOrNah(startXY, kingXY) - && checkPiecesPath(startPiece.getPiecePath(startXY, kingXY), startXY, kingXY); } - private boolean isValidPromotion(Piece pawn, Square start, Square end) { //not working for left captures + private boolean isValidPromotion(Piece pawn, Square start, Square end) { // not working for left captures Pair startXY = start.getCoord(); Pair endXY = end.getCoord(); if (startXY.getX() == endXY.getX() && end.hasPiece()) @@ -197,6 +168,62 @@ private boolean atEndOfBoard(Piece pawn, Pair endXY) { return false; } + private boolean checkStandardMove(Square start, Square end, Piece startPiece, Piece killedPiece) { + boolean testPieceValidMove = !isPawn(startPiece) && startPiece.validOrNah(start.getCoord(), end.getCoord()); + + boolean testPiecePath = checkPiecesPath(startPiece.getPiecePath(start.getCoord(), end.getCoord()), + start.getCoord(), end.getCoord()); + + if (testPieceValidMove && testPiecePath) { + executeMove(start, end, startPiece, killedPiece); + } else if (!testPiecePath) { + // raise cannot hop over piece at xy + return false; + } else { + Errors.pieceBreakRules(start, startPiece); + return false; + } + + return true; + } + + private boolean checkSoundMove(Square start, Square end, Piece startPiece, Piece killedPiece) { + + if (start.equals(end)) { + Errors.displayNoMovement(); + return false; + } + + boolean test = isOwnedPiece(startPiece); + + if (!test) { + System.out + .println("You do not own " + startPiece.getReadablePiece() + " at " + start.getCoord() + " silly"); + return false; + } + + test = moveMakesCheck(start, end) && startPiece.getType() != PieceType.KING; // does the move cause the current + // player to get in check + // buggy, checking + if (test) { + System.out.println("Cannot move " + startPiece.getReadablePiece() + " at " + start.getCoord() + + " as you are in check"); + return false; + } else if (moveMakesCheck(start, end)) { // not sure if best practice to have my checkout detection with this, + // could be just a bad king move + over = true; + } + + test = isFriendlyFire(startPiece, killedPiece); + + if (test) { + System.out.println("Cannot take your own piece silly"); + return false; + } + + return true; + } + private boolean checkValidCastling(Square kingSQ, Square rookSQ) { if (!kingSQ.hasPiece() || !rookSQ.hasPiece()) { return false; @@ -218,22 +245,34 @@ private boolean checkValidCastling(Square kingSQ, Square rookSQ) { return false; } - if(kingIsThreatened(rookSQ.getCoord(), kingSQ.getCoord())){ + if (kingIsThreatened(rookSQ.getCoord(), kingSQ.getCoord())) { return false; } - return king.getType() == PieceType.KING && rook.getType() == PieceType.ROOK; + return king.getType() == PieceType.KING && rook.getType() == PieceType.ROOK; + } + + // check if the square matches any squares in the move list already + private boolean hasPieceMoved(Square sq) { + + for (Move moves : previousMoves) { + if (moves.getStartingPair().equals(sq.getCoord()) || moves.getEndingPair().equals(sq.getCoord())) { + return true; + } + } + return false; } // private boolean kingIsThreatened(Pair rookXY, Pair kingXY) { int length = Math.abs(rookXY.getX() - kingXY.getX()); - int minpos = Math.min(rookXY.getX(), kingXY.getX()); //start at leftmost pos + int minpos = Math.min(rookXY.getX(), kingXY.getX()); // start at leftmost pos - //see if a square on the kings horiz move can be reached - for (int i = 0; i < length; i++) { - Pair currentXY = new Pair(minpos + i, kingXY.getY()); - if(isPieceBeingAttkd(currentXY)) return true; + // see if a square on the kings horiz move can be reached + for (int i = 0; i < length; i++) { + Pair currentXY = new Pair(minpos + i, kingXY.getY()); + if (isPieceBeingAttkd(currentXY)) + return true; } return false; } @@ -249,7 +288,7 @@ private void castlePieces(Square kingSQ, Square rookSQ) { addMove(kingSQ, board.getBoard()[0][6], king, null); addMove(rookSQ, board.getBoard()[0][5], rook, null); } - if (rookSQ.getCoord().getX() == 0 && rookSQ.getCoord().getY() == 7) { //queen side white + if (rookSQ.getCoord().getX() == 0 && rookSQ.getCoord().getY() == 7) { // queen side white addMove(kingSQ, board.getBoard()[7][2], king, null); addMove(rookSQ, board.getBoard()[7][3], rook, null); } @@ -272,97 +311,64 @@ private void executeMove(Square start, Square end, Piece startPiece, Piece kille private void addMove(Square start, Square end, Piece startPiece, Piece killedPiece) { if (killedPiece != null) { // if the subsequent move has captured a piece checkIfKing(killedPiece); // refactor both into better and more useful methods - addKilledPiece(killedPiece); - } - previousMoves.add(new Move(start, end, startPiece, killedPiece)); // killedPiece could be null, - } - private boolean hasPieceMoved(Square sq) { // check if the square matches any squares in the move list already - - for (Move moves : previousMoves) { - if (moves.getStartingPair().equals(sq.getCoord()) || moves.getEndingPair().equals(sq.getCoord())) { - return true; - } } - return false; + previousMoves.add(new Move(start, end, startPiece, killedPiece)); // killedPiece could be null, } - /* - should put execute moves elsewhere, repititous - */ - private boolean checkPawnMove(Square start, Square end, Piece pawn, Piece killedPiece) { - if(!checkSoundMove(start, end, pawn, killedPiece)) return false; - - if (getPrevMove() != null && isEnPassant(getPrevMove(), start.getCoord(), end.getCoord(), pawn)) { - System.out.println("You just got enpassanted cuhhhhhhh at " + end.getCoord()); - executeMove(start, end, pawn, killedPiece); - return true; - } + private boolean moveMakesCheck(Square start, Square end) { + Piece temp = end.getPiece(); + end.setPiece(start.getPiece()); + start.killPiece(); + boolean causedCheck = false; + Pair kingXY = getKingPos(board.getBoard()); - if (isValidPromotion(pawn, start, end)) { // checks if it is promotion move, could offer better signifers bc just executing move says a queen made promotion - pawn = new Queen(pawn.getColor()); - executeMove(start, end, pawn, null); - return true; + if (isPieceBeingAttkd(kingXY)) { + causedCheck = true; } + start.setPiece(end.getPiece()); // reset it back into place + end.setPiece(temp); - Pawn pPawn = (Pawn) pawn; - boolean test = pPawn.validOrNah(start.getCoord(), end.getCoord(), killedPiece) && - checkPiecesPath(pawn.getPiecePath(start.getCoord(), end.getCoord()), start.getCoord(), end.getCoord()); - - if (test) { - executeMove(start, end, pawn, killedPiece); // passes - return true; - } else { - System.out.println("Illegal pawn manuever at " + start.getCoord()); - return false; - } + return causedCheck; } - private boolean isEnPassant(Move prevMove, Pair start, Pair end, Piece pawn) { - Piece opponentPiece = prevMove.getPieceMoved(); - - if (checkEnPassantCond(prevMove, opponentPiece, pawn)) - return false; + private Pair getKingPos(Square[][] bd) { - if (opponentPiece.getColor() == ColorType.Black && prevMove.getEndingPair().getY() == start.getY()) { // white captures black en passant - return end.getY() + 1 == prevMove.getEndingPair().getY() && end.getX() == prevMove.getEndingPair().getX(); + for (int rank = 0; rank < bd.length; rank++) { + for (int file = 0; file < bd[rank].length; file++) { + Piece temp = bd[rank][file].getPiece(); + if (temp != null && temp.getColor() == currentplayer && temp.getType() == PieceType.KING) { + return bd[rank][file].getCoord(); + } + } } + return null; + } - if (opponentPiece.getColor() == ColorType.White && prevMove.getEndingPair().getY() == start.getY()) { // black captures white - return end.getY() - 1 == prevMove.getEndingPair().getY() && end.getX() == prevMove.getEndingPair().getX(); + private boolean isPieceBeingAttkd(Pair endXY) { + Square[][] bd = board.getBoard(); + for (int rank = 0; rank < bd.length; rank++) { + for (int file = 0; file < bd.length; file++) { + Square sq = bd[rank][file]; + if (sq.hasPiece()) { + Piece pieceHere = sq.getPiece(); + Pair startXY = sq.getCoord(); + if (pieceHasValidRoute(pieceHere, startXY, endXY)) + return true; + } + } } - return false; } - private boolean checkEnPassantCond(Move prevMove, Piece opponentPiece, Piece pawn) { // sees if it satisfies basic prereqs - - return !(!isPawn(opponentPiece) || prevMove.getEndingPair().getY() != 3 - || prevMove.getEndingPair().getY() != 6 || opponentPiece.getColor() == pawn.getColor()); - - } - - private boolean isPawn(Piece startPiece) { - return startPiece.getType() == PieceType.PAWN; - } - - private boolean checkStandardMove(Square start, Square end, Piece startPiece, Piece killedPiece) { - boolean testPieceValidMove = !isPawn(startPiece) && startPiece.validOrNah(start.getCoord(), end.getCoord()); - - boolean testPiecePath = checkPiecesPath(startPiece.getPiecePath(start.getCoord(), end.getCoord()), - start.getCoord(), end.getCoord()); - - if (testPieceValidMove && testPiecePath) { - executeMove(start, end, startPiece, killedPiece); - } else if (!testPiecePath) { - // raise cannot hop over piece at xy - return false; - } else { - Errors.pieceBreakRules(start, startPiece); - return false; - } + /* + * will return false, when it is an owned piece, the attacking move is invalid, + * and when there are obstructions in the then validated path + */ + private boolean pieceHasValidRoute(Piece startPiece, Pair startXY, Pair kingXY) { - return true; + return !isOwnedPiece(startPiece) && startPiece.validOrNah(startXY, kingXY) + && checkPiecesPath(startPiece.getPiecePath(startXY, kingXY), startXY, kingXY); } private boolean isOwnedPiece(Piece startPiece) { @@ -379,49 +385,36 @@ private boolean inBounds(int x, int y) { return x >= 0 && x < 8 && y >= 0 && y < 8; } - private boolean checkPiecesPath(List path, Pair startXY, Pair endXY) { + private boolean checkPiecesPath(List path, Pair startXY, Pair endXY) { Square[][] bd = board.getBoard(); Piece startPiece = bd[startXY.getY()][startXY.getX()].getPiece(); for (Pair pair : path) { - if (squareIsOccupied(bd, pair, startXY, endXY)) { + if (squareIsOccupied(bd, pair, startXY, endXY)) { Errors.pathIsBlocked(startPiece, bd[pair.getY()][pair.getX()].getPiece(), pair); return false; - } + } } return true; } - private boolean squareIsOccupied(Square[][] bd, Pair pair, Pair startXY, Pair endXY){ - - //Ignore the start and ending position of the path - irrelevant to the validity of the path - return bd[pair.getY()][pair.getX()].hasPiece() && (!pair.equals(startXY)) && (!pair.equals(endXY)); - } - - private Pair getKingPos(Square[][] bd) { + private boolean squareIsOccupied(Square[][] bd, Pair pair, Pair startXY, Pair endXY) { + // Ignore the start and ending position of the path - irrelevant to the validity + // of the path - for (int rank = 0; rank < bd.length; rank++) { - for (int file = 0; file < bd[rank].length; file++) { - Piece temp = bd[rank][file].getPiece(); - if (temp != null && temp.getColor() == currentplayer && temp.getType() == PieceType.KING) { - return bd[rank][file].getCoord(); - } - } - } - return null; + return bd[pair.getY()][pair.getX()].hasPiece() && + !pair.equals(startXY) && !pair.equals(endXY); } - private void addKilledPiece(Piece killedPiece) { // - if (killedPiece.getColor() == ColorType.White) { - blackCapturedWhite.add(killedPiece); - pieceskilled.putIfAbsent(ColorType.White, blackCapturedWhite); - return; + private void switchCurrentPlayer() { + if (currentplayer.equals(ColorType.White)) { + currentplayer = ColorType.Black; + } else { + currentplayer = ColorType.White; } - whiteCapturedBlack.add(killedPiece); - pieceskilled.putIfAbsent(ColorType.Black, whiteCapturedBlack); } - public List getMoves() { // previousMoves is storing twice + public List getMoves() { previousMoves.stream().distinct().forEach(move -> { System.out.println(move); }); @@ -455,13 +448,8 @@ private void checkIfKing(Piece killed) { over = true; } - private void showScore() { /* - * to do ---- has logic errors - */ - for (List p : pieceskilled.values()) { - int score = 39 - p.stream().mapToInt(Piece::getValue).sum(); - System.out.println("'s score: " + score); - } + private boolean isPawn(Piece startPiece) { + return startPiece.getType() == PieceType.PAWN; } public ColorType getTurn() { @@ -469,17 +457,9 @@ public ColorType getTurn() { } public void printBoard() { - //System.out.println("\t Black"); + // System.out.println("\t Black"); board.showBoard(); - //bSystem.out.println("\t White"); - } - - private void switchCurrentPlayer() { - if (currentplayer.equals(ColorType.White)) { - currentplayer = ColorType.Black; - } else { - currentplayer = ColorType.White; - } + // bSystem.out.println("\t White"); } /* @@ -496,5 +476,10 @@ private void switchCurrentPlayer() { * rank++){ //left if(!bd[x][y+rank].hasPiece()) possibleKingPos.add(new * Pair(x-1, y+rank)); } return false; //get current King moves, } */ + /* + * private void showScore() { for (List p : pieceskilled.values()) { int + * score = 39 - p.stream().mapToInt(Piece::getValue).sum(); + * System.out.println("'s score: " + score); } } to do ---- has logic errors + */ } diff --git a/src/main/java/domain/UserInterface/UI.java b/src/main/java/domain/UserInterface/UI.java index 0536949..db30ab6 100644 --- a/src/main/java/domain/UserInterface/UI.java +++ b/src/main/java/domain/UserInterface/UI.java @@ -21,7 +21,7 @@ public UI(Game game, BufferedReader in) { } public void showGreeting() { - System.out.println("Welcome to chess! Let's begin"); + System.out.println("Welcome to chess! \nLowercase letters is black, and uppercase is white. \nLet's begin"); game.startGame(); } @@ -38,7 +38,7 @@ private boolean isInputValid(String input) { public void getMoves() throws IOException { while (!game.isCheckMate()) { try { - System.out.print(game.getTurn() + "'s turn, "); + System.out.print(game.getTurn() + " to move, "); System.out.println("enter the square you wish to move from."); String input1 = sc.readLine(); diff --git a/target/classes/domain/Logic/Game.class b/target/classes/domain/Logic/Game.class index fddc8e3f339ee4a193ea89cb543c483bddc0dc3c..767b29d06b628ca4147a7454f81e828a01fc66e8 100644 GIT binary patch literal 13116 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 diff --git a/target/classes/domain/UserInterface/UI.class b/target/classes/domain/UserInterface/UI.class index 24ebc1f2726b0abe04925b1429b1a870fcf32c78..272eff388d184c5a3a67710a02ac5e7feac3a282 100644 GIT binary patch delta 101 zcmew@wMlwI1EXhfcxp~^er~ElNxnjIMrv`fq5_vsetBw9a$<3+LQZN)NorBCLT0f- xQchxWwvIw#UW!6#K><`AC|;hCS(2)!z_ocYBNG!R7s#C4{Ib-|bD8gP0surOBToPT delta 46 zcmdla{ab271Ea8Pcxp~^er~ElNxnjIMrv`fqQd5rj7&@%oa)62C8b4qo3Ak6;{*VH CK@boC