From 5bd6db4b06b19239e9d3d48121d14cd23015c08d Mon Sep 17 00:00:00 2001 From: djib Date: Sat, 7 Jan 2006 16:34:40 +0000 Subject: [PATCH] This is a first version where it is possible to play in console. Rules are not implemented and program crashes when moving a piece that does not exit or when trying to capture our own pieces... --- TODO | 3 +- src/suicideChess/Board.java | 61 ++++++++-- src/suicideChess/Move.java | 83 +++++++++++-- src/suicideChess/Piece.java | 59 +++++++-- src/suicideChess/Square.java | 10 ++ src/suicideChess/SuicideChess.java | 2 + src/tests/TestMoves.java | 184 ++++++++++++++++++++++------- 7 files changed, 327 insertions(+), 75 deletions(-) diff --git a/TODO b/TODO index b884925..50879bc 100644 --- a/TODO +++ b/TODO @@ -1,2 +1 @@ -Create a variable called SECURITY. -If SECURITY = false then many test that are 'a priori' useless are not done. \ No newline at end of file +Capture is not implemented in Move.class \ No newline at end of file diff --git a/src/suicideChess/Board.java b/src/suicideChess/Board.java index d58db8c..f29016a 100644 --- a/src/suicideChess/Board.java +++ b/src/suicideChess/Board.java @@ -1,5 +1,7 @@ package suicideChess; +import suicideChess.Square.NotAValidSquare; + /** * @author djib * @@ -58,11 +60,47 @@ public class Board { /*************** * CONSTRUCTOR * + * @throws NotAValidSquare ***************/ - public Board() { + public Board() throws NotAValidSquare { bitBoards = new long[NB_OF_BITBOARDS]; + addPiece(new Square("a1"),new Piece(Piece.WHITE_ROOK)); + addPiece(new Square("b1"),new Piece(Piece.WHITE_KNIGHT)); + addPiece(new Square("c1"),new Piece(Piece.WHITE_BISHOP)); + addPiece(new Square("d1"),new Piece(Piece.WHITE_QUEEN)); + addPiece(new Square("e1"),new Piece(Piece.WHITE_KING)); + addPiece(new Square("f1"),new Piece(Piece.WHITE_BISHOP)); + addPiece(new Square("g1"),new Piece(Piece.WHITE_KNIGHT)); + addPiece(new Square("h1"),new Piece(Piece.WHITE_ROOK)); + + addPiece(new Square("a2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("b2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("c2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("d2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("e2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("f2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("g2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("h2"),new Piece(Piece.WHITE_PAWN)); + addPiece(new Square("a8"),new Piece(Piece.BLACK_ROOK)); + addPiece(new Square("b8"),new Piece(Piece.BLACK_KNIGHT)); + addPiece(new Square("c8"),new Piece(Piece.BLACK_BISHOP)); + addPiece(new Square("d8"),new Piece(Piece.BLACK_QUEEN)); + addPiece(new Square("e8"),new Piece(Piece.BLACK_KING)); + addPiece(new Square("f8"),new Piece(Piece.BLACK_BISHOP)); + addPiece(new Square("g8"),new Piece(Piece.BLACK_KNIGHT)); + addPiece(new Square("h8"),new Piece(Piece.BLACK_ROOK)); + + addPiece(new Square("a7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("b7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("c7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("d7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("e7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("f7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("g7"),new Piece(Piece.BLACK_PAWN)); + addPiece(new Square("h7"),new Piece(Piece.BLACK_PAWN)); + } @@ -70,15 +108,24 @@ public class Board { * METHODS * ***********/ - private long getBitBoard(int bitboard_number) { + public void doMove(Move move) throws NoPieceOnSquare { + if (move.isCaptureMove()) { + removePiece(move.toSquare(), move.getCapturedPiece()); + } + removePiece(move.fromSquare(), move.getMovingPiece()); + if (move.isPromotionMove()) { + addPiece(move.toSquare(), move.getPromotionPiece()); + } else { + addPiece(move.toSquare(), move.getMovingPiece()); + } + } + + +/* private long getBitBoard(int bitboard_number) { return bitBoards[bitboard_number]; } - +*/ - private void updateBitBoards(String move) { - //TODO - } - private int squareToBitBoardSquare(Square square) { //converts a square ("e2") to a BitboardSquare ( diff --git a/src/suicideChess/Move.java b/src/suicideChess/Move.java index 21f9eb0..d6ecc46 100644 --- a/src/suicideChess/Move.java +++ b/src/suicideChess/Move.java @@ -19,10 +19,15 @@ public class Move { ********/ //integers + private Piece movingPiece; + private Square fromSquare; private Square toSquare; - private String promotionPiece; + private Piece promotionPiece; private boolean isPromotion; + + private boolean isCapture; + private Piece capturePiece; public class NotAValidMoveException extends Exception { /** @@ -38,23 +43,49 @@ public class Move { ***************/ //The string is of type e2e4 (4 chars), b7b8q (5 chars) for promotions - public Move(String move) throws NotAValidMoveException, NotAValidSquare { + + //non capture move + public Move(String move, Piece pieceToMove) throws NotAValidMoveException, NotAValidSquare { + movingPiece = pieceToMove; isPromotion = false; - promotionPiece = ""; + isCapture = false; + switch (move.length()) { case 5: isPromotion = true; - promotionPiece = move.substring(4,5); + promotionPiece = new Piece(move.toCharArray()[4], movingPiece.getColor()); //no break statement here on purpose case 4: fromSquare = new Square(move.substring(0,2)); - toSquare = new Square(move.substring(2,4)); + toSquare = new Square(move.substring(2,4)); break; default: throw new NotAValidMoveException("Invalid Move: "+move); } } + //capture move + public Move(String move, Piece pieceToMove, Piece pieceToCapture) throws NotAValidMoveException, NotAValidSquare { + movingPiece = pieceToMove; + isPromotion = false; + isCapture = true; + capturePiece = pieceToCapture; + + switch (move.length()) { + case 5: + isPromotion = true; + promotionPiece = new Piece(move.toCharArray()[4], movingPiece.getColor()); + //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); + } + } + + /*********** @@ -70,26 +101,52 @@ public class Move { public boolean isPromotionMove() { return isPromotion; } - public String getPromotionPiece() { - return promotionPiece; + public Piece getPromotionPiece() { + if (isPromotion) { + return promotionPiece; + } else { + return new Piece(Piece.NONE); + } } + public Piece getMovingPiece() { + return movingPiece; + } + + public boolean isCaptureMove() { + return isCapture; + } + + public Piece getCapturedPiece() { + return capturePiece; + } + + public String toString() { + return fromSquare.toString()+toSquare+promotionPiece; + } + + + /**************************************** + * I do not use those functions anymore * + **************************************** + public void setFromSquare(Square square) { fromSquare = square; } public void setToSquare(Square square) { toSquare = square; } - public void setIsPromotionMove(String piece) { - if (promotionPiece.length()==0) { + public void setPromotionMove(String piece) { + if (piece.length()==0) { isPromotion=false; } else { isPromotion=true; - promotionPiece=piece; + promotionPiece=new Piece(piece); } } - - public String toString() { - return fromSquare.toString()+toSquare+promotionPiece; + public void setMovingPiece(Piece piece) { + movingPiece = piece; } + + */ } diff --git a/src/suicideChess/Piece.java b/src/suicideChess/Piece.java index d13cab0..994a2e6 100644 --- a/src/suicideChess/Piece.java +++ b/src/suicideChess/Piece.java @@ -23,24 +23,31 @@ public class Piece { * Take really good care if you want to change those values * Class BitBoard makes intensive use of those */ + public static final int NONE=-1; //Contants used to detect color 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_PAWN = 2; - public static final int BLACK_PAWN = 3; - public static final int WHITE_KING = 4; - public static final int BLACK_KING = 5; - public static final int WHITE_QUEEN = 6; - public static final int BLACK_QUEEN = 7; - public static final int WHITE_BISHOP = 8; - public static final int BLACK_BISHOP = 9; - public static final int WHITE_KNIGHT = 10; - public static final int BLACK_KNIGHT = 11; - public static final int WHITE_ROOK = 12; - public static final int BLACK_ROOK = 13; + public static final int PAWN = 2; + public static final int WHITE_PAWN = PAWN + WHITE; + public static final int BLACK_PAWN = PAWN + BLACK; + public static final int KING = 4; + public static final int WHITE_KING = KING + WHITE; + public static final int BLACK_KING = KING + BLACK; + public static final int QUEEN = 6; + public static final int WHITE_QUEEN = QUEEN + WHITE; + public static final int BLACK_QUEEN = QUEEN + BLACK; + public static final int BISHOP = 8; + public static final int WHITE_BISHOP = BISHOP + WHITE; + public static final int BLACK_BISHOP = BISHOP + BLACK; + public static final int KNIGHT = 10; + public static final int WHITE_KNIGHT = KNIGHT + WHITE; + public static final int BLACK_KNIGHT = KNIGHT + BLACK; + public static final int ROOK = 12; + public static final int WHITE_ROOK = ROOK + WHITE; + public static final int BLACK_ROOK = ROOK + BLACK; //Constants used for promotion (as used in the xboard protocol) @@ -49,12 +56,14 @@ public class Piece { public static final char BISHOP_CHAR='b'; public static final char KNIGHT_CHAR='n'; public static final char ROOK_CHAR='r'; + //may be useful + public static final char PAWN_CHAR='p'; /**************** * PRIVATE DATA * ****************/ - private static int pieceNumber; + private int pieceNumber; /*************** * CONSTRUCTOR * @@ -64,6 +73,30 @@ public class Piece { pieceNumber = piece; } + public Piece(char piece, int color) { + pieceNumber = NONE; + switch (piece) { + case PAWN_CHAR: + pieceNumber = PAWN + color; + break; + case KING_CHAR: + pieceNumber = KING + color; + break; + case QUEEN_CHAR: + pieceNumber = QUEEN + color; + break; + case BISHOP_CHAR: + pieceNumber = BISHOP + color; + break; + case KNIGHT_CHAR: + pieceNumber = KNIGHT + color; + break; + case ROOK_CHAR: + pieceNumber = ROOK + color; + break; + } + } + /*********** * METHODS * ***********/ diff --git a/src/suicideChess/Square.java b/src/suicideChess/Square.java index 7274d3e..ea61dc6 100644 --- a/src/suicideChess/Square.java +++ b/src/suicideChess/Square.java @@ -33,6 +33,16 @@ public class Square { file = Character.toLowerCase(square.toCharArray()[0]); fileNb = ((int)file) - ((int)'a') + 1; rank = Integer.parseInt(square.substring(1,2)); + + //perform extra check ? + if (SuicideChess.SQUARE_CHECK_INVALID) { + if (fileNb<1 || fileNb>Board.NB_OF_FILES) { + throw new NotAValidSquare(square); + } + if (rank<1 || rank>Board.NB_OF_RANKS) { + throw new NotAValidSquare(square); + } + } } public char getFile() { diff --git a/src/suicideChess/SuicideChess.java b/src/suicideChess/SuicideChess.java index 10be4fb..1045862 100644 --- a/src/suicideChess/SuicideChess.java +++ b/src/suicideChess/SuicideChess.java @@ -21,6 +21,8 @@ public class SuicideChess { */ //does BitBoard.class removePiece function checks if removing piece is legal ? public static final boolean BITBOARD_REMOVEPIECE_CHECK_REMOVE = true; + //does Square.class checks if the strings are valid (is "z9" a valid square ? + public static final boolean SQUARE_CHECK_INVALID = true; diff --git a/src/tests/TestMoves.java b/src/tests/TestMoves.java index 390da70..ef2fd4e 100644 --- a/src/tests/TestMoves.java +++ b/src/tests/TestMoves.java @@ -5,6 +5,7 @@ import java.io.InputStreamReader; import suicideChess.*; import suicideChess.Board.NoPieceOnSquare; +import suicideChess.Move.NotAValidMoveException; import suicideChess.Square.NotAValidSquare; /** @@ -22,55 +23,94 @@ public class TestMoves { public static void main(String[] args) { BufferedReader moveInput = new BufferedReader(new InputStreamReader(System.in)); - BitBoardTest bitboard = new BitBoardTest(); - - while (true) { - try { - /** - * Test of Move and Square class - */ - //String move = moveInput.readLine(); - //(new MoveTest(move)).display(); - //System.out.println((new BitBoard().squareToBitboardSquare(new Square(move)))); - //new SquareTest(move).display(); - //System.out.println(new Square(move)); - - /** - * Test of the add function in class BitBoard - */ - - String whereToAdd = moveInput.readLine(); - if (whereToAdd.startsWith("rm ")) { - bitboard.rm(new Square(whereToAdd.substring(3)), new Piece(Piece.BLACK_PAWN)); - } else { - bitboard.add(new Square(whereToAdd), new Piece(Piece.BLACK_PAWN)); - } - bitboard.display(Piece.BLACK_PAWN); - - } catch (Exception err) { - System.out.println(err); - break; - } + try { + BitBoardTest bitboard = new BitBoardTest(); + bitboard.display(); + + int playerColor = Piece.WHITE; + + while (true) { + try { + /** + * Test of Move and Square class + */ + //String move = moveInput.readLine(); + //(new MoveTest(move)).display(); + //System.out.println((new BitBoard().squareToBitboardSquare(new Square(move)))); + //new SquareTest(move).display(); + //System.out.println(new Square(move)); + + + /** + * Test of the moves + * Moves must be displayed in the following form : + * PieceLetter move(4lettes) PieceCaptureCode(2digits) + * example p e4d5 p + * + * Not very convenient but it is for test purposes :-P + */ + + String whatMove= moveInput.readLine(); + MoveTest theMove; + Piece movePiece = new Piece(whatMove.toCharArray()[0],playerColor); + if (whatMove.length()==6) { + theMove = new MoveTest(whatMove.substring(2,6),movePiece); + } else { + Piece capturePiece; + if (playerColor==Piece.WHITE) { + capturePiece = new Piece(whatMove.toCharArray()[7],Piece.BLACK); + theMove = new MoveTest(whatMove.substring(2,6),movePiece,capturePiece); + } else { + capturePiece = new Piece(whatMove.toCharArray()[7],Piece.WHITE); + theMove = new MoveTest(whatMove.substring(2,6),movePiece,capturePiece); + } + } + theMove.display(); + bitboard.doMove(theMove); + bitboard.display(); + + if (playerColor == Piece.WHITE) { + playerColor = Piece.BLACK; + } else { + playerColor = Piece.WHITE; + } + + + } catch (Exception err) { + System.out.println(err); + break; + } + } + } catch (NotAValidSquare e) { + e.printStackTrace(); } } } class MoveTest extends Move { - public MoveTest(String move) throws NotAValidMoveException, NotAValidSquare { - super(move); + public MoveTest(String move, Piece pieceToMove) throws NotAValidMoveException, NotAValidSquare { + super(move, pieceToMove); } + public MoveTest(String move, Piece pieceToMove, Piece pieceToCapture) throws NotAValidMoveException, NotAValidSquare { + super(move, pieceToMove, pieceToCapture); + } + public void display() { System.out.println(" "); - System.out.println("==== Move ===="); + 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() : "No Promotion")); - System.out.println("==============="); + System.out.println((isPromotionMove() ? "Promotion: "+getPromotionPiece() : "No Promotion")); + System.out.println((isCaptureMove() ? "Capture: "+getCapturedPiece().getPieceNumber() : "No Capture")); + System.out.println("=============="); System.out.println(" "); System.out.println(" "); } } + +/* class SquareTest extends Square { public SquareTest(String square) throws NotAValidSquare { super(square); @@ -87,27 +127,91 @@ class SquareTest extends Square { } } +*/ + class BitBoardTest extends Board { - public void display(int whatToDisplay) { + public BitBoardTest() throws NotAValidSquare { + super(); + } + + 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 ((bitBoards[whatToDisplay] & mask)==0) { - display+=" | "; - } else { - display+="1 | "; - } + + 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 boolean displayPiece(int whatToDisplay, long mask) { + if ((bitBoards[whatToDisplay] & mask)==0) { + return false; + } else { + return true; + } + } + /* public void add (Square square, Piece piece) { addPiece(square, piece); } public void rm (Square square, Piece piece) throws NoPieceOnSquare { removePiece(square, piece); } + */ + } \ No newline at end of file