diff --git a/TODO b/TODO index 50879bc..80c75d7 100644 --- a/TODO +++ b/TODO @@ -1 +1,3 @@ -Capture is not implemented in Move.class \ No newline at end of file +Have a look at all the checks that are done. +Add constants for useless ones. + diff --git a/src/suicideChess/Board.java b/src/suicideChess/Board.java index f29016a..b415e28 100644 --- a/src/suicideChess/Board.java +++ b/src/suicideChess/Board.java @@ -104,9 +104,9 @@ public class Board { } - /*********** - * METHODS * - ***********/ + /****************** + * PUBLIC METHODS * + ******************/ public void doMove(Move move) throws NoPieceOnSquare { if (move.isCaptureMove()) { @@ -119,7 +119,100 @@ public class Board { addPiece(move.toSquare(), move.getMovingPiece()); } } + + //this function searchs for what piece is on a square + public Piece getPiece(Square onSquare) { + //if there is a corresponding white piece. + if (!isEmpty(onSquare, new Piece(Piece.WHITE_PIECES))) { + //for every white piece bitboard, look for the piece + for (int piece = Piece.WHITE_PAWN; piece <= Piece.WHITE_ROOK; piece += 2) { + if(!isEmpty(onSquare, new Piece(piece))) { + return new Piece(piece); + } + } + } else if (!isEmpty(onSquare, new Piece(Piece.BLACK_PIECES))) { + //for every white piece bitboard, look for the piece + for (int piece = Piece.BLACK_PAWN; piece <= Piece.BLACK_ROOK; piece += 2) { + if(!isEmpty(onSquare, new Piece(piece))) { + return new Piece(piece); + } + } + } + //if no piece found + return new Piece(Piece.NONE); + } + + //this function can be used to display the board + public void display(){ + for (int file = NB_OF_FILES; file >= 1; file--) { + System.out.println("+---+---+---+---+---+---+---+---+"); + String display = "| "; + for (int rank=1; rank <= NB_OF_RANKS; rank++) { + boolean displayedSomething = false; + long mask = mapSquaresToBits[rank-1+(file-1)*NB_OF_RANKS]; + + if (displayPiece(Piece.BLACK_PAWN,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.PAWN_CHAR)+" | "; + } + if (displayPiece(Piece.BLACK_QUEEN,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.QUEEN_CHAR)+" | "; + } + if (displayPiece(Piece.BLACK_KING,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.KING_CHAR)+" | "; + } + if (displayPiece(Piece.BLACK_KNIGHT,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.KNIGHT_CHAR)+" | "; + } + if (displayPiece(Piece.BLACK_ROOK,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.ROOK_CHAR)+" | "; + } + if (displayPiece(Piece.BLACK_BISHOP,mask)) { + displayedSomething=true; + display+=Character.toUpperCase(Piece.BISHOP_CHAR)+" | "; + } + if (displayPiece(Piece.WHITE_PAWN,mask)) { + displayedSomething=true; + display+=Piece.PAWN_CHAR+" | "; + } + if (displayPiece(Piece.WHITE_QUEEN,mask)) { + displayedSomething=true; + display+=Piece.QUEEN_CHAR+" | "; + } + if (displayPiece(Piece.WHITE_KING,mask)) { + displayedSomething=true; + display+=Piece.KING_CHAR+" | "; + } + if (displayPiece(Piece.WHITE_KNIGHT,mask)) { + displayedSomething=true; + display+=Piece.KNIGHT_CHAR+" | "; + } + if (displayPiece(Piece.WHITE_ROOK,mask)) { + displayedSomething=true; + display+=Piece.ROOK_CHAR+" | "; + } + if (displayPiece(Piece.WHITE_BISHOP,mask)) { + displayedSomething=true; + display+=Piece.BISHOP_CHAR+" | "; + } + if (!displayedSomething) + display+=" | "; + } + System.out.println(display); + } + System.out.println("+---+---+---+---+---+---+---+---+"); + } + + + /******************* + * PRIVATE METHODS * + *******************/ + /* private long getBitBoard(int bitboard_number) { return bitBoards[bitboard_number]; @@ -151,7 +244,7 @@ public class Board { //remove Piece to corresponding bitboard. if (SuicideChess.BITBOARD_REMOVEPIECE_CHECK_REMOVE) { - if (checkIsNotEmpty(square, piece)) { + if (!isEmpty(square, piece)) { bitBoards[piece.getPieceNumber()] ^= mapSquaresToBits[squareToBitBoardSquare(square)]; } else { throw new NoPieceOnSquare("Square: "+square + "; Piece: " + piece.getPieceNumber()); @@ -164,12 +257,21 @@ public class Board { } //checks if a square is empty for a certain piece - private boolean checkIsNotEmpty(Square square, Piece piece) { + private boolean isEmpty(Square square, Piece piece) { long mask = mapSquaresToBits[squareToBitBoardSquare(square)]; if ((bitBoards[piece.getPieceNumber()] & mask) == 0) { + return true; + } else { + return false; + } + } + + private boolean displayPiece(int whatToDisplay, long mask) { + if ((bitBoards[whatToDisplay] & mask)==0) { return false; } else { - return true; + return true; } } + } \ No newline at end of file diff --git a/src/suicideChess/Move.java b/src/suicideChess/Move.java index d6ecc46..c3114d1 100644 --- a/src/suicideChess/Move.java +++ b/src/suicideChess/Move.java @@ -43,7 +43,40 @@ public class Move { ***************/ //The string is of type e2e4 (4 chars), b7b8q (5 chars) for promotions + public Move(String move, Board board) throws NotAValidMoveException, NotAValidSquare { + isPromotion = false; + + switch (move.length()) { + case 5: + isPromotion = true; + //no break statement here on purpose + case 4: + fromSquare = new Square(move.substring(0,2)); + toSquare = new Square(move.substring(2,4)); + break; + default: + throw new NotAValidMoveException("Invalid Move: "+move); + } + + movingPiece = board.getPiece(fromSquare()); + capturePiece = board.getPiece(toSquare()); + + if (capturePiece.getPieceNumber()!=Piece.NONE) { + isCapture = true; + } else { + isCapture = false; + } + + if (isPromotion) { + promotionPiece = new Piece(move.toCharArray()[4], movingPiece.getColor()); + } + } + + /********************************************* + * Those two constructors are no longer used * + *********************************************/ + /* //non capture move public Move(String move, Piece pieceToMove) throws NotAValidMoveException, NotAValidSquare { movingPiece = pieceToMove; @@ -85,7 +118,7 @@ public class Move { } } - + */ /*********** @@ -125,6 +158,20 @@ public class Move { return fromSquare.toString()+toSquare+promotionPiece; } + //Used for debugging mainly + public void display() { + System.out.println(" "); + System.out.println("==== Move ===="); + System.out.println("Move: "+getMovingPiece().getPieceNumber()); + System.out.println("From square:"+fromSquare()); + System.out.println("To square: "+toSquare()); + System.out.println((isPromotionMove() ? "Promotion: "+getPromotionPiece().getPieceNumber() : "No Promotion")); + System.out.println((isCaptureMove() ? "Capture: "+getCapturedPiece().getPieceNumber() : "No Capture")); + System.out.println("=============="); + System.out.println(" "); + System.out.println(" "); + } + /**************************************** * I do not use those functions anymore * diff --git a/src/suicideChess/Piece.java b/src/suicideChess/Piece.java index 994a2e6..2890006 100644 --- a/src/suicideChess/Piece.java +++ b/src/suicideChess/Piece.java @@ -28,8 +28,8 @@ public class Piece { public static final int WHITE=0; public static final int BLACK=1; //Constants used in the board representation - public static final int WHITE_PIECE = WHITE; - public static final int BLACK_PIECE = BLACK; + public static final int WHITE_PIECES = WHITE; + public static final int BLACK_PIECES = BLACK; public static final int PAWN = 2; public static final int WHITE_PAWN = PAWN + WHITE; public static final int BLACK_PAWN = PAWN + BLACK; diff --git a/src/suicideChess/SuicideChess.java b/src/suicideChess/SuicideChess.java index 1045862..f4480d9 100644 --- a/src/suicideChess/SuicideChess.java +++ b/src/suicideChess/SuicideChess.java @@ -1,6 +1,10 @@ package suicideChess; -import tests.TestMoves; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import suicideChess.Move.NotAValidMoveException; +import suicideChess.Square.NotAValidSquare; /** * @author djib @@ -24,13 +28,61 @@ public class SuicideChess { //does Square.class checks if the strings are valid (is "z9" a valid square ? public static final boolean SQUARE_CHECK_INVALID = true; - + public static final int MAIN_VERSION_NUMBER = 0; + public static final int REVISION_NUMBER = 15; /***************** * MAIN FUNCTION * *****************/ public static void main(String[] args) { - TestMoves.main(args); + System.out.println("Welcome to SuicideChess v"+MAIN_VERSION_NUMBER+"."+REVISION_NUMBER+"!"); + BufferedReader moveInput = new BufferedReader(new InputStreamReader(System.in)); + + try { + Board bitboard = new Board(); + bitboard.display(); + + /*int playerColor = Piece.WHITE; + System.out.println("White: ");*/ + + while (true) { + try { + String whatMove= moveInput.readLine(); + + if (whatMove.startsWith("quit")) { + System.out.println("Goodbye!"); + break; + } + + Move theMove = new Move(whatMove, bitboard); + + theMove.display(); + bitboard.doMove(theMove); + bitboard.display(); + + /*if (playerColor == Piece.WHITE) { + playerColor = Piece.BLACK; + System.out.println("Black: "); + } else { + playerColor = Piece.WHITE; + System.out.println("White: "); + }*/ + + + } catch (NotAValidMoveException err) { + System.out.println(err); + continue; + } catch (NotAValidSquare err) { + System.out.println(err); + continue; + } catch (Exception err) { + System.out.println(err); + break; + } + } + } catch (NotAValidSquare e) { + e.printStackTrace(); + } } } diff --git a/src/tests/TestMoves.java b/src/tests/TestMoves.java index c2f2998..26abed9 100644 --- a/src/tests/TestMoves.java +++ b/src/tests/TestMoves.java @@ -4,7 +4,6 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import suicideChess.*; -import suicideChess.Board.NoPieceOnSquare; import suicideChess.Move.NotAValidMoveException; import suicideChess.Square.NotAValidSquare; @@ -27,7 +26,8 @@ public class TestMoves { BitBoardTest bitboard = new BitBoardTest(); bitboard.display(); - int playerColor = Piece.WHITE; + /*int playerColor = Piece.WHITE; + System.out.println("White: ");*/ while (true) { try { @@ -51,6 +51,13 @@ public class TestMoves { */ String whatMove= moveInput.readLine(); + + if (whatMove.startsWith("quit")) { + System.out.println("Goodbye!"); + break; + } + + /* MoveTest theMove; Piece movePiece = new Piece(whatMove.toCharArray()[0],playerColor); if (whatMove.length()==6) { @@ -76,20 +83,32 @@ public class TestMoves { theMove = new MoveTest(whatMove.substring(2,7),movePiece,capturePiece); } } + */ + + MoveTest theMove = new MoveTest(whatMove, bitboard); + theMove.display(); bitboard.doMove(theMove); bitboard.display(); - if (playerColor == Piece.WHITE) { + /*if (playerColor == Piece.WHITE) { playerColor = Piece.BLACK; + System.out.println("Black: "); } else { playerColor = Piece.WHITE; - } + System.out.println("White: "); + }*/ + - - } catch (Exception err) { + } catch (NotAValidMoveException err) { System.out.println(err); - break; + continue; + } catch (NotAValidSquare err) { + System.out.println(err); + continue; + } catch (Exception err) { + System.out.println(err); + break; } } } catch (NotAValidSquare e) { @@ -99,6 +118,10 @@ public class TestMoves { } class MoveTest extends Move { + public MoveTest(String move, Board board) throws NotAValidMoveException, NotAValidSquare { + super(move, board); + } + public MoveTest(String move, Piece pieceToMove) throws NotAValidMoveException, NotAValidSquare { super(move, pieceToMove); } @@ -112,7 +135,7 @@ class MoveTest extends Move { System.out.println("Move: "+getMovingPiece().getPieceNumber()); System.out.println("From square:"+fromSquare()); System.out.println("To square: "+toSquare()); - System.out.println((isPromotionMove() ? "Promotion: "+getPromotionPiece() : "No Promotion")); + System.out.println((isPromotionMove() ? "Promotion: "+getPromotionPiece().getPieceNumber() : "No Promotion")); System.out.println((isCaptureMove() ? "Capture: "+getCapturedPiece().getPieceNumber() : "No Capture")); System.out.println("=============="); System.out.println(" ");