Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save IbrahimAyed1/5cacb725035561cb9e6c804f553f3ad8 to your computer and use it in GitHub Desktop.

Select an option

Save IbrahimAyed1/5cacb725035561cb9e6c804f553f3ad8 to your computer and use it in GitHub Desktop.
<component name="ProjectDictionaryState">
<dictionary name="ibrahim">
<words>
<w>polymorphicly</w>
</words>
</dictionary>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinCommonCompilerArguments">
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
</component>
</project>
<component name="libraryTable">
<library name="gdx-setup">
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/gdx-setup.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
<component name="libraryTable">
<library name="guava-18.0">
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/OOP Project/BlackWidow-Chess-master/lib/guava-18.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ClientPropertiesManager">
<properties class="javax.swing.AbstractButton">
<property name="hideActionText" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JComponent">
<property name="html.disable" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JEditorPane">
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
<property name="charset" class="java.lang.String" />
</properties>
<properties class="javax.swing.JList">
<property name="List.isFileList" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JPasswordField">
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JSlider">
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
<property name="JSlider.isFilled" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTable">
<property name="Table.isFileList" class="java.lang.Boolean" />
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JToolBar">
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTree">
<property name="JTree.lineStyle" class="java.lang.String" />
</properties>
<properties class="javax.swing.text.JTextComponent">
<property name="caretAspectRatio" class="java.lang.Double" />
<property name="caretWidth" class="java.lang.Integer" />
</properties>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Chess.iml" filepath="$PROJECT_DIR$/Chess.iml" />
</modules>
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="guava-18.0" level="project" />
<orderEntry type="library" name="gdx-setup" level="project" />
</component>
</module>
package com.chess.engine;
import com.chess.engine.player.BlackPlayer;
import com.chess.engine.player.Player;
import com.chess.engine.player.WhitePlayer;
/**
* Created by ibrahim on 4/25/17.
*/
public enum Alliance {
WHITE {
@Override
public int getDirection() {
return -1;
}
@Override
public boolean isBlack() {
return false;
}
@Override
public boolean isWhite() {
return true;
}
@Override
public Player choosePlayer(final WhitePlayer whitePlayer,final BlackPlayer blackPlayer) {
return whitePlayer;
}
},
BLACK {
@Override
public int getDirection() {
return 1;
}
@Override
public boolean isBlack() {
return true;
}
@Override
public boolean isWhite() {
return false;
}
@Override
public Player choosePlayer(final WhitePlayer whitePlayer,final BlackPlayer blackPlayer) {
return blackPlayer;
}
};
public abstract int getDirection();
public abstract boolean isBlack();
public abstract boolean isWhite();
public abstract Player choosePlayer(WhitePlayer whitePlayer, BlackPlayer blackPlayer);
}
package com.chess.engine.board;
import com.chess.engine.Alliance;
import com.chess.engine.pieces.*;
import com.chess.engine.player.BlackPlayer;
import com.chess.engine.player.Player;
import com.chess.engine.player.WhitePlayer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.*;
/**
* Created by ibrahim on 4/25/17.
*/
public class Board {
//We will make a collection of tiles
//Here we will use lists , because you can NOT have an IMMUTABLE array in java , but you CAN have IMMUTABLE list.
private final List<Tile> gameBoard;
private final Collection<Piece> whitePieces;
private final Collection<Piece> blackPieces;
private final WhitePlayer whitePlayer;
private final BlackPlayer blackPlayer;
private final Player currentPlayer;
public Board(final Builder builder) {
this.gameBoard = createGameBoard(builder);
this.whitePieces = calculateActivePieces(this.gameBoard,Alliance.WHITE);
this.blackPieces = calculateActivePieces(this.gameBoard,Alliance.BLACK);
final Collection<Moves> whiteStanderedLegalMoves=calculateLegalMoves(this.whitePieces);
final Collection<Moves> blackStanderedLegalMoves=calculateLegalMoves(this.blackPieces);
this.whitePlayer = new WhitePlayer(this,whiteStanderedLegalMoves,blackStanderedLegalMoves);
this.blackPlayer = new BlackPlayer(this,whiteStanderedLegalMoves,blackStanderedLegalMoves);
this.currentPlayer = builder.nextMoveMaker.choosePlayer(this.whitePlayer,this.blackPlayer);
}//Constructor end
@Override
public String toString(){
//This will determine what board looks like when it's turn into string
final StringBuilder builder = new StringBuilder();
for (int i=0;i < BoardUtils.NUM_TILES;i++){
final String tileTest = this.gameBoard.get(i).toString();
builder.append(String.format("%3s",tileTest));
if( (i+1) % BoardUtils.NUM_TILES_PER_ROW == 0 ){
builder.append("\n");
}
}//for loop ends here
return builder.toString();
} //string builder ends here
public Player whitePlayer(){
return this.whitePlayer;
}
public Player blackPlayer(){
return this.blackPlayer;
}
public Player currentPlayer(){
return this.currentPlayer;
}
public Collection<Piece> getBlackPieces(){
return this.blackPieces;
}
public Collection<Piece> getWhitePieces(){
return this.whitePieces;
}
private Collection<Moves> calculateLegalMoves(final Collection<Piece> pieces) {
final List<Moves>legalMoves = new ArrayList<>();
for (final Piece piece : pieces){
legalMoves.addAll(piece.calculateLegalMoves(this)); //Legal moves is like a container that contains all the legal moves
}//End of for
return ImmutableList.copyOf(legalMoves);
}//end of calculating legal moves method
private static Collection<Piece> calculateActivePieces(final List<Tile> gameBoard,final Alliance alliance) {
final List<Piece> activePieces = new ArrayList<>();
for(final Tile tile : gameBoard){
if(tile.isTileOccupied()){
final Piece piece=tile.getPiece();
if(piece.getPieceAlliance() == alliance){
activePieces.add(piece);
}//end if
}//end if
}//end for
return ImmutableList.copyOf(activePieces);
}//end method calculate active pieces
public Tile getTile(final int tileCoordinate) {
return gameBoard.get(tileCoordinate);
}//Tile object
//Now we will make a method that makes list of tiles numbered form 0 to 63 that'll represent the chess board , we gonna see that in the for loop later
//that we will go through ,
// what we gonna see is that in that loop we go through and we get from the config wherever we set our config to associate we're going to map a piece onto tile ID
//Then when we call create tile
public static List<Tile> createGameBoard(final Builder builder){
final Tile[] tiles = new Tile[BoardUtils.NUM_TILES]; //THIS WILL BUILD ARRAY OF 64 TILES
for (int i=0;i<BoardUtils.NUM_TILES;i++){
//Then when we call create tile here ,we're going to associate a piece to a tile for it
//يعني انا بقوم جايب المنطقة مثلا رقم 4 و اقوم مخصصها للملك او عن طريق ID خاص بيه
tiles[i]=Tile.createTile(i,builder.boardConfig.get(i));
//It'll bring ID's of the pieces from the lower method as we know ! , but if there was not any pieces?
//So it'll bring NULL
/*
backing to the condition " public static Tile createTile(final int tileCoordinate,final Piece piece){
return piece != null ? new OccupiedTile(tileCoordinate,piece) : EMPTY_TILES_CACHE.get(tileCoordinate); "
in the Tile class , if the tile is not occupied ,create an empty tile from that we retrieve from the tile cache
*/
}//end of for loop
return ImmutableList.copyOf(tiles);
}//List of tiles "Creating game board" end
public static Board createStanderedBoard(){
//here we'll create the initial position for a chess board "مكان كل قطعة"
final Builder builder = new Builder();
// Black Layout
builder.setPiece(new Rook(Alliance.BLACK, 0));
builder.setPiece(new Knight(Alliance.BLACK, 1));
builder.setPiece(new Bishop(Alliance.BLACK, 2));
builder.setPiece(new Queen(Alliance.BLACK, 3));
builder.setPiece(new King(Alliance.BLACK, 4));
builder.setPiece(new Bishop(Alliance.BLACK, 5));
builder.setPiece(new Knight(Alliance.BLACK, 6));
builder.setPiece(new Rook(Alliance.BLACK, 7));
builder.setPiece(new Pawn(Alliance.BLACK, 8));
builder.setPiece(new Pawn(Alliance.BLACK, 9));
builder.setPiece(new Pawn(Alliance.BLACK, 10));
builder.setPiece(new Pawn(Alliance.BLACK, 11));
builder.setPiece(new Pawn(Alliance.BLACK, 12));
builder.setPiece(new Pawn(Alliance.BLACK, 13));
builder.setPiece(new Pawn(Alliance.BLACK, 14));
builder.setPiece(new Pawn(Alliance.BLACK, 15));
// White Layout
builder.setPiece(new Pawn(Alliance.WHITE, 48));
builder.setPiece(new Pawn(Alliance.WHITE, 49));
builder.setPiece(new Pawn(Alliance.WHITE, 50));
builder.setPiece(new Pawn(Alliance.WHITE, 51));
builder.setPiece(new Pawn(Alliance.WHITE, 52));
builder.setPiece(new Pawn(Alliance.WHITE, 53));
builder.setPiece(new Pawn(Alliance.WHITE, 54));
builder.setPiece(new Pawn(Alliance.WHITE, 55));
builder.setPiece(new Rook(Alliance.WHITE, 56));
builder.setPiece(new Knight(Alliance.WHITE, 57));
builder.setPiece(new Bishop(Alliance.WHITE, 58));
builder.setPiece(new Queen(Alliance.WHITE, 59));
builder.setPiece(new King(Alliance.WHITE, 60));
builder.setPiece(new Bishop(Alliance.WHITE, 61));
builder.setPiece(new Knight(Alliance.WHITE, 62));
builder.setPiece(new Rook(Alliance.WHITE, 63));
//white to move
builder.setMoveMaker(Alliance.WHITE);
//build the board
return builder.build();
}//Standeredbuilder method end
/*==============================================================*/
//Iterable is a build in function in GUAVA Library
/*=============================================================*/
public Iterable<Moves> getAllLegalMoves() {
return Iterables.unmodifiableIterable(Iterables.concat(this.whitePlayer.getLegalMoves(),
this.blackPlayer.getLegalMoves()));
}
public static class Builder{
HashMap boardConfig;
Alliance nextMoveMaker;
Pawn enPassantPawn;
public Builder(){
this.boardConfig = new HashMap<>(33,1.0f);
}//End of constructor
//Next methods are setting some property and return that builder back
public Builder setPiece(final Piece piece){
this.boardConfig.put(piece.getPiecePosition(),piece);
return this;
}
public Builder setMoveMaker(final Alliance nextMoveMaker){
this.nextMoveMaker = nextMoveMaker;
return this;
}
public Board build(){
return new Board(this);
}
public void setEnPassantPawn(Pawn enPassantPawn) {
this.enPassantPawn = enPassantPawn;
}
}//End of builder class
}//End of board class
package com.chess.engine.board;
import java.util.List;
/**
* Created by ibrahim on 4/26/17.
*/
public class BoardUtils {
public static final boolean[] FIRST_COLUMN = initColumn(0);
public static final boolean[] SECOND_COLUMN =initColumn(1);
public static final boolean[] THIRD_COLUMN = initColumn(2);
public static final boolean[] FOURTH_COLUMN = initColumn(3);
public static final boolean[] FIFTH_COLUMN = initColumn(4);
public static final boolean[] SIXTH_COLUMN = initColumn(5);
public static final boolean[] SEVENTH_COLUMN =initColumn(6);
public static final boolean[] EIGHTH_COLUMN =initColumn(7);
public static final boolean[] EIGHTH_RANK = initRow(0);
public static final boolean[] SEVENTH_RANK =initRow(8);
public static final boolean[] SIXTH_RANK = initRow(16);
public static final boolean[] FIFTH_RANK = initRow(24);
public static final boolean[] FOURTH_RANK = initRow(32);
public static final boolean[] THIRD_RANK = initRow(40);
public static final boolean[] SECOND_RANK =initRow(48);
public static final boolean[] FIRST_RANK = initRow(56);
public static final int NUM_TILES=64;
public static final int NUM_TILES_PER_ROW=8;
private BoardUtils(){
throw new RuntimeException("You Can't Instantiate me !");
} //Constructor end
//Initialization method
private static boolean[] initColumn(int columnNumber) {
final boolean[] column = new boolean[NUM_TILES];
do {
column[columnNumber]=true;
columnNumber+=NUM_TILES_PER_ROW;
} while (columnNumber < NUM_TILES);
return column;
} //End of the initColumn method.
private static boolean[] initRow(int rowNumber) {
final boolean[] row = new boolean[NUM_TILES];
do{
row[rowNumber] = true;
rowNumber++;
}while (rowNumber % NUM_TILES_PER_ROW !=0);
return row;
}
public static boolean isValidTileCoordinate(int coordinate) {
return coordinate >=0 && coordinate < NUM_TILES;
} //Validation method end
}
package com.chess.engine.board;
import com.chess.engine.pieces.Pawn;
import com.chess.engine.pieces.Piece;
import com.chess.engine.pieces.Rook;
import static com.chess.engine.board.Board.*;
/**
* Created by ibrahim on 4/25/17.
*/
public abstract class Moves {
final Board board;
final Piece movedPieces;
final int destinationCandidate;
public static final Moves NULL_MOVE = new NullMove();
private Moves(final Board board,
final Piece movedPieces,
final int destinationCandidate) {
this.board = board;
this.movedPieces = movedPieces;
this.destinationCandidate = destinationCandidate;
}
//============= SubClasses & Methods =================//
@Override
public int hashCode(){
final int prime=31;
int result=1;
result = prime * result +this.destinationCandidate;
result = prime * result + this.movedPieces.hashCode();
return result;
}
@Override
public boolean equals(final Object other){
if(this == other) {
return true;
}
if(!(other instanceof Moves)){
return false;
}
final Moves otherMove = (Moves) other;
return getDestinationCoordinate() == otherMove.getDestinationCoordinate() &&
getMovedPieces().equals(otherMove.getMovedPieces());
}
public int getCurrentCoordinate() {
return this.getMovedPieces().getPiecePosition();
}
public int getDestinationCoordinate() {
return this.destinationCandidate;
}
public Piece getMovedPieces() {
return this.movedPieces;
}
public boolean isAttack(){
return false;
}
public boolean isCastelingMove(){
return false;
}
public Piece getAttackedPiece(){
return null;
}
public Board execute() {
final Builder builder = new Builder(); //1- we use board builder , to materialize a board to execute
for (final Piece piece : this.board.currentPlayer().getActivePieces()) {
//2- check that pieces that have not moved and place it again in it's places without making any changes
if (!this.movedPieces.equals(piece)) {
builder.setPiece(piece); // here we go through and set all of thepieces on the new out pound board
}
}
//3-we are going to do the same thing for blacks
for (final Piece piece : this.board.currentPlayer().getOpponent().getActivePieces()) {
builder.setPiece(piece);
}
builder.setPiece(this.movedPieces.movePiece(this)); //4- we are setting the piece for the moved piece and MOVE THE MOVED PIECE
builder.setMoveMaker(this.board.currentPlayer().getOpponent().getAlliance()); //5-set the move maker to the opponentd
return builder.build();
}
public static final class MajorMove extends Moves {
public MajorMove(final Board board, final Piece movedPieces, final int destinationCandidator) {
super(board, movedPieces, destinationCandidator);
}
}
public static class AttackMove extends Moves {
final Piece attackedPiece;
public AttackMove(final Board board,
final Piece movedPieces,
final int destinationCandidate,
final Piece AttackedPiece) {
super(board, movedPieces, destinationCandidate);
this.attackedPiece = AttackedPiece;
}
@Override
public int hashCode(){
return this.attackedPiece.hashCode() + super.hashCode();
}
@Override
public boolean equals(final Object other){
if(this == other){
return true;
}
if(!(other instanceof AttackMove)){
return false;
}
final AttackMove otherAttackMove = (AttackMove) other;
return super.equals(otherAttackMove) && getAttackedPiece().equals(otherAttackMove.getAttackedPiece());
}
@Override
public Board execute() {
return null;
}
@Override
public boolean isAttack() {
return false;
}
@Override
public Piece getAttackedPiece() {
return this.attackedPiece;
}
}//End of attack move calss
public static final class PawnMove extends Moves {
public PawnMove(final Board board,
final Piece movedPieces,
final int destinationCandidate) {
super(board, movedPieces, destinationCandidate);
}
}
public static class PawnAttackMove extends AttackMove {
public PawnAttackMove(final Board board,
final Piece movedPieces,
final int destinationCandidate,
final Piece AttackedPiece) {
super(board, movedPieces, destinationCandidate, AttackedPiece);
}
}
public static final class PawnEnPassantAttackMove extends AttackMove {
public PawnEnPassantAttackMove(final Board board,
final Piece movedPieces,
final int destinationCandidate,
final Piece AttackedPiece) {
super(board, movedPieces, destinationCandidate, AttackedPiece);
}
}
public static final class PawnJump extends Moves {
public PawnJump(final Board board,
final Piece movedPieces,
final int destinationCandidate) {
super(board, movedPieces, destinationCandidate);
}
@Override
public Board execute(){
final Builder builder = new Builder();
for (final Piece piece : this.board.currentPlayer().getActivePieces()){
if(!(this.movedPieces.equals(piece))){
builder.setPiece(piece);
}
}
for (final Piece piece:this.board.currentPlayer().getOpponent().getActivePieces()){
builder.setPiece(piece);
}
final Pawn movedPawn = (Pawn) this.movedPieces.movePiece(this);
builder.setPiece(movedPawn);
builder.setEnPassantPawn(movedPawn);
builder.setMoveMaker(this.board.currentPlayer().getOpponent().getAlliance());
return builder.build();
}
}
static abstract class CastleMove extends Moves {
//TODO : Read more about castle move on Wikipedia
protected final Rook castleRook;
protected final int castleRookStart;
protected final int castleRookDestination;
public CastleMove(final Board board,
final Piece movedPieces,
final int destinationCandidator,
final Rook castleRook,
final int castleRookDestination,
final int castleRookStart) {
super(board, movedPieces, destinationCandidator);
this.castleRook = castleRook;
this.castleRookDestination=castleRookDestination;
this.castleRookStart=castleRookStart;
}
public Rook getCastleRook(){
return this.castleRook;
}
@Override
public boolean isCastelingMove(){
return true;
}
@Override
public Board execute(){
final Builder builder = new Builder();
for (final Piece piece : this.board.currentPlayer().getActivePieces()){
//This loop meaning : if the piece that we're setting on the board is not the moved piece & is not the castle rook ,then set the piece
if(!(this.movedPieces.equals(piece)) && !this.castleRook.equals(piece)){
builder.setPiece(piece);
}
}
for (final Piece piece:this.board.currentPlayer().getOpponent().getActivePieces()){
builder.setPiece(piece);
}
//HERE : Move the king to it's desitnaiotn location and we moved the Rook with 2nd and 3rd statement
// and made an new rook and set it on castle side
builder.setPiece(this.movedPieces.movePiece(this));
builder.setPiece(new Rook(this.castleRook.getPieceAlliance(),this.castleRookDestination));
builder.setMoveMaker(this.board.currentPlayer().getOpponent().getAlliance());
return builder.build();
}
}//CstleMove class end
public static final class KingSideCastleMove extends CastleMove {
public KingSideCastleMove(final Board board,
final Piece movedPieces,
final int destinationCandidate,
final Rook castleRook,
final int castleRookDestination,
final int castleRookStart) {
super(board, movedPieces, destinationCandidate,castleRook,castleRookDestination,castleRookStart);
}
@Override
public String toString(){
return "O-O";
}
}
public static final class QueenSideCastleMove extends CastleMove {
public QueenSideCastleMove(final Board board,
final Piece movedPieces,
final int destinationCandidate,
final Rook castleRook,
final int castleRookDestination,
final int castleRookStart) {
super(board, movedPieces, destinationCandidate,castleRook,castleRookDestination,castleRookStart);
}
public String toString(){
return "O-O-O";
}
}
public static final class NullMove extends Moves {
public NullMove() {
super(null, null, -1);
}
@Override
public Board execute() {
throw new RuntimeException("Can't execute this null move");
}
}
public static class MoveFactory {
private MoveFactory() {
throw new RuntimeException("Not instantiatable!");
}
public static Moves createMove(final Board board,
final int currentCoordinate,
final int destinationCoordinate) {
for (final Moves move : board.getAllLegalMoves()) {
if (move.getCurrentCoordinate() == currentCoordinate &&
move.getDestinationCoordinate() == destinationCoordinate) {
return move;
}
}
return NULL_MOVE;
}
}
}///Class end
/**
* Created by ibrahim on 4/25/17.
*/
package com.chess.engine.board;
import com.chess.engine.pieces.Piece;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
public abstract class Tile {
//It's will be set on the construction time ->final , it can only be accessed by its subclasses ->protected
protected final int tileCoordinate;
//Empty tile map constructor , and we made it private because we don't want anybody to change it later
//to use the empty tile map you MUST have the guava library on your pc
private static final Map<Integer,EmptyTile> EMPTY_TILES_CACHE = createAllPossibleEmptyTiles();
private static Map<Integer,EmptyTile> createAllPossibleEmptyTiles(){
final Map<Integer,EmptyTile>emptyTileMap = new HashMap<>();
for(int i=0;i<BoardUtils.NUM_TILES;i++){
emptyTileMap.put(i,new EmptyTile(i));
}
return ImmutableMap.copyOf(emptyTileMap);
/*
Immutable time map is part of guava library which is 3rd party library provided by google
i want an immutable map ,a map
to understand mutable and immutable class you can check Effective Java book .
*/
}
public static Tile createTile(final int tileCoordinate,final Object piece){
return piece != null ? new OccupiedTile(tileCoordinate, (Piece) piece) : EMPTY_TILES_CACHE.get(tileCoordinate);
/*
the only method that anyone's going to be allowed to use on my class to create a tile
is going to be discrete tile .
and they ever won an empty tile they're going to get one of the cached empty tiles
Otherwise, they're going to create a new occupied tile
we could cash all possible occupied tiles
*/
} //End of my method for creating or getting cached tile
//My Coordinator constructor
private Tile(final int tileCoordinate){
this.tileCoordinate = tileCoordinate;
}
//Abstract boolean method for checking is the tile occupied or not!
public abstract boolean isTileOccupied();
public abstract Piece getPiece();
public int getTileCoordinate(){
return this.tileCoordinate;
}
//Empty tile class
public static final class EmptyTile extends Tile{
private EmptyTile(final int coordinate){
super(coordinate);
} //End of the Constructor
@Override
public String toString(){
return "-";
//if the tile is empty it will return " - "
}
@Override
public boolean isTileOccupied(){
return false;
} //End of boolean method TileOccupied
@Override
public Piece getPiece(){
return null;
} //End of the Piece getPiece method.
}
/*
======================================================================
If you are coding after me, i was thinking about coordinating out tile,Then
i'll find my way to draw and get some piece of art :"D
*/
//Otherwise , if the tile is not empty but occupied !..
public static final class OccupiedTile extends Tile{
private final Piece pieceOnTile; //Object of Piece class
//Constructor for occupied tile will take the coordinate and the piece
private OccupiedTile(int tileCoordinate,final Piece pieceOnTile){
super(tileCoordinate); //super class constructor will establish the tile coordinate
this.pieceOnTile=pieceOnTile; // pieceOnTile will be equal the pieceOnTile that passed form the constructor
} //end of OccupiedTile Constructor
@Override
public String toString(){
return getPiece().getPieceAlliance().isBlack() ? getPiece().toString().toLowerCase() :
getPiece().toString();
//if the tile is occupied it'll print it out
//#Black pieces will be shown up in UPERCASE , #White pieces will be in lower case
}
@Override
public boolean isTileOccupied(){
return true;
}//end of the boolean method isTileOccupied
@Override
public Piece getPiece(){
return this.pieceOnTile;
} //End of getting my piece
}
}
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
/**
* Created by ibrahim on 4/28/17.
*/
public class Bishop extends Piece {
private final static int[] CANDIDATE_MOVE_VECTOR_COORDINATE = {-9 , -7 , 7 , 9};
public Bishop( final Alliance pieceAlliance,final int piecePosition) {
super(PieceType.BISHOP,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(final Board board) {
final List<Moves> legalMoves = new ArrayList<>();
for (final int candidateCoordinateOffset:CANDIDATE_MOVE_VECTOR_COORDINATE){
int candidateDestinationCoordinate = this.piecePosition;
while (BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)){
if(isFirstColumnExclusion(candidateDestinationCoordinate,candidateCoordinateOffset) ||
isEighthColumnExclusion(candidateDestinationCoordinate,candidateCoordinateOffset))
{
break;
}
candidateDestinationCoordinate += candidateCoordinateOffset;
if(BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)) {
final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate); //We can say it's lyk an next destination where the piece will go on
if(!candidateDestinationTile.isTileOccupied()){
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
} //End of if condition
else {
final Piece pieceAtDestination=candidateDestinationTile.getPiece();
final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance(); //The Alliance of the piece
if(this.pieceAlliance != pieceAlliance) {
legalMoves.add(new AttackMove(board,this,candidateDestinationCoordinate,pieceAtDestination));
} //The current piece "knight" Alliance != the piece alliance of the piece that's at our destination
break; //This means the tile is occupied then we will keep going on , if it's done we will stop doing that
}//if it's occupied
}
}
}
return ImmutableList.copyOf(legalMoves);
}
@Override
public Bishop movePiece(Moves move) {
return new Bishop(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.BISHOP.toString();
}
private static boolean isFirstColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.FIRST_COLUMN[currentPosition] && (candidateOffset ==-1);
}//End of the method
private static boolean isEighthColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.EIGHTH_COLUMN[currentPosition] && (candidateOffset ==1);
}//End of the method
}
/*
You Can check the Knight's class to understand this code too.
*/
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
/**
* Created by ibrahim on 4/30/17.
*/
public class King extends Piece {
private final static int[] CANDIDATE_MOVE_COORDINATE = {-9,-8,-7,-1,1,7,8,9};
public King(final Alliance pieceAlliance,final int piecePosition) {
super(PieceType.KING,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(Board board) {
final List<Moves> legalMoves = new ArrayList<>();
for (final int currentCandidateOffset:CANDIDATE_MOVE_COORDINATE){
final int candidateDestinationCoordinate = this.piecePosition+currentCandidateOffset;
if(isFirstColumnExclusion(this.piecePosition,currentCandidateOffset) ||
isEighthColumnExclusion(this.piecePosition,currentCandidateOffset)) {
continue;
}
if(BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)){
final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate);
if(!candidateDestinationTile.isTileOccupied()){
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
} //End of if condition
else {
final Piece pieceAtDestination=candidateDestinationTile.getPiece();
final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance(); //The Alliance of the piece
if(this.pieceAlliance != pieceAlliance) {
legalMoves.add(new AttackMove(board,this,candidateDestinationCoordinate,pieceAtDestination));
} //The current piece "knight" Alliance != the piece alliance of the piece that's at our destination
}//if it's occupied
}//If condition end
}//End of the for loop
return ImmutableList.copyOf(legalMoves);
}//Override end
@Override
public King movePiece(Moves move) {
return new King(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.KING.toString();
}
private static boolean isFirstColumnExclusion(final int currentPosition,final int candidateOffset){
/* We need a way to capture all the tile coordinates , the correspond to give a column or a raw */
return BoardUtils.FIRST_COLUMN[currentPosition] && (candidateOffset == -9 || candidateOffset == -1
|| candidateOffset == 7);
}
private static boolean isEighthColumnExclusion(final int currentPosition,final int candidateOffset){
return BoardUtils.EIGHTH_COLUMN[currentPosition] && (candidateOffset == 9 || candidateOffset ==-7 || candidateOffset ==1);
}
}//Class end
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
//Beginning of the knight class
public class Knight extends Piece {
private final static int[] CANDIDATE_MOVE_CORDINATES = { -17,-15,-10,-6,6,10,15,17}; //Fixed candidate destinations for the knight
public Knight( Alliance pieceAlliance, int piecePosition) {
super(PieceType.KNIGHT,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(final Board board) {
final List<Moves> legalMoves= new ArrayList<>();
for (final int currentCandidateOffset:CANDIDATE_MOVE_CORDINATES){
/* ====================How This Code Works ? ===========================================================
We say that the candidate destination coordinate is my current position plus the current canidate ,
then if that is a valid tile and noneOccupied then we gonna add sort of non-attacking legal move,
Otherwise if it's occupied ,then we get the alliance of the piece that is occupying the tile
and if the alliance of that piece is not equal to this current knights alliance then we going to
add an attacking move,
After we built those all up we're going to return all of those legal moves
"You can read the most bottom comment to understand it better ..
====================================================================================================
*/
final int candidateDestinationCoordinate = this.piecePosition + currentCandidateOffset;
if(BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)) {
if(isFirstColumnExclusion(this.piecePosition,currentCandidateOffset) ||
isSecondColumnExclusion(this.piecePosition,currentCandidateOffset) ||
isSeventhColumnExclusion(this.piecePosition,currentCandidateOffset) ||
isEighthColumnExclusion(this.piecePosition,currentCandidateOffset)) {
continue;
}
final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate); //We can say it's lyk an next destination where the piece will go on
if(!candidateDestinationTile.isTileOccupied()){
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
} //End of if condition
else {
final Piece pieceAtDestination=candidateDestinationTile.getPiece();
final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance(); //The Alliance of the piece
if(this.pieceAlliance != pieceAlliance) {
legalMoves.add(new AttackMove(board,this,candidateDestinationCoordinate,pieceAtDestination));
} //The current piece "knight" Alliance != the piece alliance of the piece that's at our destination
}//if it's occupied
}
} //End of for loop
return ImmutableList.copyOf(legalMoves);
} //End of method
@Override
public Knight movePiece(Moves move) {
return new Knight(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.KNIGHT.toString();
}
private static boolean isFirstColumnExclusion(final int currentPosition,final int candidateOffset){
/* We need a way to capture all the tile coordiantes , the corespond to give a column or a raw */
return BoardUtils.FIRST_COLUMN[currentPosition] && (candidateOffset == -17 || candidateOffset == -10
|| candidateOffset == 6 || candidateOffset ==15);
}
private static boolean isSecondColumnExclusion(final int currentPosition,final int candidateOffset){
return BoardUtils.SECOND_COLUMN[currentPosition] && (candidateOffset == -10 || candidateOffset ==6);
}
private static boolean isSeventhColumnExclusion(final int currentPosition,final int candidateOffset){
return BoardUtils.SEVENTH_COLUMN[currentPosition] && (candidateOffset == -6 || candidateOffset ==10);
}
private static boolean isEighthColumnExclusion(final int currentPosition,final int candidateOffset){
return BoardUtils.EIGHTH_COLUMN[currentPosition] && (candidateOffset == -15 || candidateOffset ==-6
||candidateOffset==10 || candidateOffset==17);
}
}
/*
===============================Algorithm of code :"D ==============================
You can google it easier :"D !..
===================================================================================
===================================================================================
we will loop through candidate offsets "CANDIDATE_MOVE_CORDINATES" , and we want to
go ahead and apply the offset to the current position
"if that position is valid on tile" -> then we will check if it's occupied or not
if it's not occupied -> we will make non-attacking move !
else -> we will end it's occupying by and enemy piece by making an attacking move
===================================================================================
*/
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
/**
* Created by ibrahim on 4/30/17.
*/
public class Pawn extends Piece {
private final static int[] CANDIDATE_MOVE_COORDINATE = {8,16,7,9};
public Pawn(final Alliance pieceAlliance, final int piecePosition) {
super(PieceType.PAWN,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(final Board board) {
final List<Moves> legalMoves = new ArrayList<>();
for (final int currentCandidateOffset:CANDIDATE_MOVE_COORDINATE){
final int candidateDestinationCoordinate = this.piecePosition + (this.pieceAlliance.getDirection()*currentCandidateOffset); //For blacks it'll apply 8 , for whites will apply -8
if (BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)){
continue;
}//End of if condition
if (currentCandidateOffset==8 && !board.getTile(candidateDestinationCoordinate).isTileOccupied()) //If the tile is not occupied then i'll try to make a jump or an regular move
{
//TODO we will be back soon to this condition.
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
}
//The first else if statement describes the first pawn jump
else if (currentCandidateOffset == 16 && this.isFirstMove() && (BoardUtils.SEVENTH_RANK[this.piecePosition] && this.getPieceAlliance().isBlack())
||(BoardUtils.SECOND_RANK[this.piecePosition] && this.getPieceAlliance().isWhite())) {
final int behindCandidateDestinationCoordinate = this.piecePosition +(this.getPieceAlliance().getDirection()*8);
if(!board.getTile(behindCandidateDestinationCoordinate).isTileOccupied() && !board.getTile(candidateDestinationCoordinate).isTileOccupied()) {
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
}//End of if statement
} //end of else if
else if (currentCandidateOffset == 7 &&
!(BoardUtils.EIGHTH_COLUMN[this.piecePosition] && this.pieceAlliance.isWhite() ||
BoardUtils.FIRST_COLUMN[this.piecePosition] && this.pieceAlliance.isBlack()))
/*When you are in the eighth column & you are white then the 7 rule does'nt work , because you'll be in the same row , so you need extra 2 - so you'll use 9 rule- steps to attack
To understand this more you can see a tile and a pawn in 1st or 8th column , if he's black or white how can he attack another piece from another alliance
I think by this way you gonna understand it well.
*/
{
if(board.getTile(candidateDestinationCoordinate).isTileOccupied()) {
final Piece pieceOnCandidate =board.getTile(candidateDestinationCoordinate).getPiece();
if(this.pieceAlliance != pieceOnCandidate.getPieceAlliance()) {
//TODO "There is more work here".
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
}//End of if statement
}//End of bigger if statement
}//End of else if
else if (currentCandidateOffset == 9 &&
!(BoardUtils.FIRST_COLUMN[this.piecePosition] && this.pieceAlliance.isWhite() ||
BoardUtils.EIGHTH_COLUMN[this.piecePosition] && this.pieceAlliance.isBlack())){
if(board.getTile(candidateDestinationCoordinate).isTileOccupied()) {
final Piece pieceOnCandidate =board.getTile(candidateDestinationCoordinate).getPiece();
if(this.pieceAlliance != pieceOnCandidate.getPieceAlliance()) {
//TODO "There is more work here".
legalMoves.add(new MajorMove(board,this,candidateDestinationCoordinate));
}//End of if statement
}//End of bigger if statement
}//End of else if statement
}//End of the for loop
return ImmutableList.copyOf(legalMoves);
}//End of the overriding
@Override
public Pawn movePiece(Moves move) {
return new Pawn(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.PAWN.toString();
}
}//End of the class
/**
* Created by ibrahim on 4/25/17.
*/
package com.chess.engine.pieces;
//List of imports
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.Moves;
import java.util.Collection;
//My Class
public abstract class Piece {
protected final PieceType pieceType;
protected final int piecePosition; //Every piece has it own position
protected final Alliance pieceAlliance; //i have whites and blacks , so i should have alliance
protected final boolean isFirstMove;
private final int cachedHashCode;
Piece(final PieceType pieceType,
final int piecePosition ,
final Alliance pieceAlliance) {
this.pieceType=pieceType;
this.pieceAlliance= pieceAlliance;
this.piecePosition= piecePosition;
this.cachedHashCode=computeHashCode();
this.isFirstMove = false;
} //End of constructor
@Override
public boolean equals(final Object other){
if(this == other){
return true;
}
if(!(other instanceof Piece)){
return false;
}
final Piece otherPiece = (Piece) other;
return piecePosition == otherPiece.piecePosition && pieceType == otherPiece.pieceType &&
pieceAlliance == otherPiece.pieceAlliance && isFirstMove == otherPiece.isFirstMove;
}
@Override
public int hashCode(){
return this.cachedHashCode;
}
private int computeHashCode() {
int result = pieceType.hashCode();
result = 31 * result + pieceAlliance.hashCode();
result = 31 * result + piecePosition;
result = 31 * result + (isFirstMove ? 1 : 0);
return result;
}
public PieceType getPieceType(){
return this.pieceType;
}
public int getPiecePosition(){
return this.piecePosition;
}
public Alliance getPieceAlliance() {
return this.pieceAlliance;
}//Piece alliance method end
//public Alliance pieceAlliance() { return this.pieceAlliance; }
public boolean isFirstMove(){
return this.isFirstMove;
}//End of isFristMove method
//Every piece will be extend of this method , and override the calculate move.
public abstract Collection<Moves> calculateLegalMoves(final Board board); //method for calculating legal moves
public abstract Piece movePiece(Moves move);
public enum PieceType{
PAWN("P") {
@Override
public boolean isKing() {
return false;
}
@Override
public boolean isRook() {
return false;
}
},
KNIGHT("N") {
@Override
public boolean isKing() {
return false;
}
@Override
public boolean isRook() {
return false;
}
},
BISHOP("B") {
@Override
public boolean isKing() {
return false;
}
@Override
public boolean isRook() {
return false;
}
},
ROOK("R") {
@Override
public boolean isKing() {
return false;
}
@Override
public boolean isRook() {
return true;
}
},
QUEEN("Q") {
@Override
public boolean isKing() {
return false;
}
@Override
public boolean isRook() {
return false;
}
},
KING("K") {
@Override
public boolean isKing() {
return true;
}
@Override
public boolean isRook() {
return false;
}
};
private String pieceName;
PieceType(final String pieceName) {
this.pieceName = pieceName;
}//Piece name method end
@Override
public String toString(){
return this.pieceName;
}
public abstract boolean isKing();
public abstract boolean isRook();
}//end of the enum
} //End of the Piece class
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Created by ibrahim on 4/28/17.
*/
public class Queen extends Piece{
private final static int[] CANDIDATE_MOVE_VECTOR_COORDINATE = {-9,-8,-7, -1, 1,7,8,9};
public Queen( Alliance pieceAlliance, int piecePosition) {
super(PieceType.QUEEN,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(final Board board) {
final List<Moves> legalMoves = new ArrayList<>();
for (final int candidateCoordinateOffset:CANDIDATE_MOVE_VECTOR_COORDINATE){
int candidateDestinationCoordinate = this.piecePosition;
while (BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)){
if(isFirstColumnExclusion(candidateDestinationCoordinate,candidateCoordinateOffset) ||
isEighthColumnExclusion(candidateDestinationCoordinate,candidateCoordinateOffset))
{
break;
}
candidateDestinationCoordinate += candidateCoordinateOffset;
if(BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)) {
final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate); //We can say it's lyk an next destination where the piece will go on
if(!candidateDestinationTile.isTileOccupied()){
legalMoves.add(new Moves.MajorMove(board,this,candidateDestinationCoordinate));
} //End of if condition
else {
final Piece pieceAtDestination=candidateDestinationTile.getPiece();
final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance(); //The Alliance of the piece
if(this.pieceAlliance != pieceAlliance) {
legalMoves.add(new Moves.AttackMove(board,this,candidateDestinationCoordinate,pieceAtDestination));
} //The current piece "knight" Alliance != the piece alliance of the piece that's at our destination
break; //This means the tile is occupied then we will keep going on , if it's done we will stop doing that
}//if it's occupied
}
}
}
return ImmutableList.copyOf(legalMoves);
}
@Override
public Queen movePiece(Moves move) {
return new Queen(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.QUEEN.toString();
}
private static boolean isFirstColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.FIRST_COLUMN[currentPosition] && (candidateOffset == -9 || candidateOffset == -1 ||
candidateOffset == 7);
}//End of the method
private static boolean isEighthColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.EIGHTH_COLUMN[currentPosition] && (candidateOffset == 9 || candidateOffset == 1||
candidateOffset == -7);
}//End of the method}
}
package com.chess.engine.pieces;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Created by ibrahim on 4/28/17.
*/
public class Rook extends Piece {
private final static int[] CANDIDATE_MOVE_VECTOR_COORDINATE = {-8, -1, 1, 8};
public Rook(Alliance pieceAlliance
,int piecePosition) {
super(PieceType.ROOK,piecePosition, pieceAlliance);
}
@Override
public Collection<Moves> calculateLegalMoves(final Board board) {
final List<Moves> legalMoves = new ArrayList<>();
for (final int candidateCoordinateOffset : CANDIDATE_MOVE_VECTOR_COORDINATE) {
int candidateDestinationCoordinate = this.piecePosition;
while (BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)) {
if (isFirstColumnExclusion(candidateDestinationCoordinate, candidateCoordinateOffset) ||
isEighthColumnExclusion(candidateDestinationCoordinate, candidateCoordinateOffset)) {
break;
}
candidateDestinationCoordinate += candidateCoordinateOffset;
if (BoardUtils.isValidTileCoordinate(candidateDestinationCoordinate)) {
final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate); //We can say it's lyk an next destination where the piece will go on
if (!candidateDestinationTile.isTileOccupied()) {
legalMoves.add(new Moves.MajorMove(board, this, candidateDestinationCoordinate));
} //End of if condition
else {
final Piece pieceAtDestination = candidateDestinationTile.getPiece();
final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance(); //The Alliance of the piece
if (this.pieceAlliance != pieceAlliance) {
legalMoves.add(new Moves.AttackMove(board, this, candidateDestinationCoordinate, pieceAtDestination));
} //The current piece "knight" Alliance != the piece alliance of the piece that's at our destination
break; //This means the tile is occupied then we will keep going on , if it's done we will stop doing that
}//if it's occupied
}
}
}
return ImmutableList.copyOf(legalMoves);
}
@Override
public Rook movePiece(Moves move) {
return new Rook(move.getMovedPieces().getPieceAlliance(),move.getDestinationCoordinate());
}
@Override
public String toString(){
return PieceType.ROOK.toString();
}
private static boolean isFirstColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.FIRST_COLUMN[currentPosition] && (candidateOffset == -9 || candidateOffset == 7);
}//End of the method
private static boolean isEighthColumnExclusion(final int currentPosition, final int candidateOffset) {
return BoardUtils.EIGHTH_COLUMN[currentPosition] && (candidateOffset == 9 || candidateOffset == -7);
}//End of the method}
}
package com.chess.engine.player;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.chess.engine.pieces.Piece;
import com.chess.engine.pieces.Rook;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
/**
* Created by ibrahim on 5/1/17.
*/
public class BlackPlayer extends Player{
public BlackPlayer(final Board board,
final Collection<Moves> whiteStanderedLegalMoves,
final Collection<Moves> blackStanderedLegalMoves) {
super(board,blackStanderedLegalMoves,whiteStanderedLegalMoves);
}
@Override
public Collection<Piece> getActivePieces() {
return this.board.getBlackPieces();
}
@Override
public Alliance getAlliance() {
return Alliance.BLACK;
}
@Override
public Player getOpponent() {
return this.board.whitePlayer();
}
@Override
protected Collection<Moves> calculateKingCastles(final Collection<Moves> playerLegals,
final Collection<Moves> opponentsLegals) {
final List<Moves> KingCastles = new ArrayList<>();
if(this.playerKing.isFirstMove() && !this.isInCheck()){
//Black King Side Castle
if(!this.board.getTile(5).isTileOccupied() && !this.board.getTile(6).isTileOccupied()){
final Tile rookTile = this.board.getTile(7);
if(rookTile.isTileOccupied() && rookTile.getPiece().isFirstMove()){
if(Player.calculateAttacksOnTile(5,opponentsLegals).isEmpty() &&
Player.calculateAttacksOnTile(6,opponentsLegals).isEmpty() &&
rookTile.getPiece().getPieceType().isRook()){
KingCastles.add(new KingSideCastleMove(this.board,
this.playerKing,
6,
(Rook)rookTile.getPiece(),
rookTile.getTileCoordinate(),
5));
}//one more if
}//end if
}//end if
//Black Queen Side Castle
if(!this.board.getTile(1).isTileOccupied() &&
!this.board.getTile(2).isTileOccupied() &&
!this.board.getTile(3).isTileOccupied()){
final Tile rookTile = this.board.getTile(0);
if(rookTile.isTileOccupied() && rookTile.getPiece().isFirstMove() &&
Player.calculateAttacksOnTile(2,opponentsLegals).isEmpty() &&
Player.calculateAttacksOnTile(3,opponentsLegals).isEmpty() &&
rookTile.getPiece().getPieceType().isRook()){
KingCastles.add(new QueenSideCastleMove(this.board,
this.playerKing,
2,
(Rook)rookTile.getPiece(),
rookTile.getTileCoordinate(),
3));
}
}
}//end if
return ImmutableList.copyOf(KingCastles);
}
}
package com.chess.engine.player;
/**
* Created by ibrahim on 5/1/17.
*/
public enum MoveStatus {
DONE{
@Override
boolean isDone(){
return true;
}
},
ILLEGAL_MOVE{
@Override
boolean isDone(){
return false;
}
},
LEAVES_PLAYER_IN_CHECK{
@Override
boolean isDone(){
return false;
}
};
abstract boolean isDone();
}
package com.chess.engine.player;
import com.chess.engine.board.Board;
import com.chess.engine.board.Moves;
/**
* Created by ibrahim on 5/1/17.
*/
public class MoveTransition {
//The transition board , the board that you going to make a transion to after making a move
private final Board transitionBoard;
private final Moves move;
private final MoveStatus moveStatus; //it'll tell us weather we are able to do the move or not
public MoveTransition(final Board transitionBoard,
final Moves move,
final MoveStatus moveStatus){
this.moveStatus=moveStatus;
this.move=move;
this.transitionBoard=transitionBoard;
}
public MoveStatus getMoveStatus(){
return this.moveStatus;
}
}
package com.chess.engine.player;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.Moves;
import com.chess.engine.pieces.King;
import com.chess.engine.pieces.Piece;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Created by ibrahim on 5/1/17.
*/
public abstract class Player {
protected final Board board;
protected final King playerKing;
protected final Collection<Moves> legalMoves;
private final boolean isInCheck;
protected Player(final Board board,
final Collection<Moves> legalMoves,
final Collection<Moves> opponentMoves) {
//
this.board =board;
this.playerKing = establishKing();
this.legalMoves = ImmutableList.copyOf(Iterables.concat(legalMoves,calculateKingCastles(legalMoves,opponentMoves)));
this.isInCheck = !Player.calculateAttacksOnTile(this.playerKing.getPiecePosition(),opponentMoves).isEmpty();
//we will pass the king's current location , and pass the enimes moves , and see if the destination coordinate of ther moves
//if it does attacking the king , we will get a collection of moves that attacks the king's position
//and calculate the current player check , if the list is empty so it's not a check
}//constructor end
public King getPlayerKing(){
return this.playerKing;
}
public Collection<Moves> getLegalMoves(){
return this.legalMoves;
}
protected static Collection<Moves> calculateAttacksOnTile(int piecePosition, Collection<Moves> moves)
{
final List<Moves> attackMoves = new ArrayList<>();
for (final Moves move:moves){
if(piecePosition == move.getDestinationCoordinate()){
attackMoves.add(move);
}
}
return ImmutableList.copyOf(attackMoves);
}
protected King establishKing() {
for(final Piece piece : getActivePieces()) {
if(piece.getPieceType().isKing()) {
return (King) piece;
}
}
throw new RuntimeException("Should not reach here! " +this.getAlliance()+ " king could not be established!");
//If the piece is the king and it's going to return it ,if we get through the loop
//we were not able to establish the king we are going to throw a run time exception
//زي كأنك بتقول للي بيلعب ان المنطقة دي مينفعش يلعب فيها
}
public boolean isMoveLeagl(final Moves move){
return this.legalMoves.contains(move); //TODO review this syntax again on google
}
public boolean isInCheck(){
return this.isInCheck;
}
public boolean isInCheckMate(){
return this.isInCheck && !hasEscapeMoves();
}
private boolean hasEscapeMoves(){
for (final Moves move : this.legalMoves){
final MoveTransition transition = makeMove(move);
if (transition.getMoveStatus().isDone()){
return true;
}
}
return false;
//we will pass the king's current location , and pass the enimes moves , and see if the destination coordinate of ther moves
//if it does attacking the king , we will get a collection of moves that attacks the king's position
//and calculate the current player check , if the list is empty so it's not a check
//For loop for making a move , if there is noway , so it will return false and it'll be a checkmate
//بيعمل زي حركات وهمية بس مش علي الBoard قدامك , بيشوف فيها ازاي الملك ميبقاش كش مات
}
public boolean isInStaleMate(){
//You are not in check but also you don't have escape moves !
return !this.isInCheck && !hasEscapeMoves();
}
public boolean isCasteled(){
return false;
}
//when we make a move we are going to return a move transition to rap the board that the transition is to.
public MoveTransition makeMove(final Moves move){
if (!isMoveLeagl(move)){
return new MoveTransition(this.board,move,MoveStatus.ILLEGAL_MOVE);
}//end if
//if the move is not illegal
final Board transitionBoard= move.execute();
final Collection<Moves> kingAttacks = Player.calculateAttacksOnTile(transitionBoard.currentPlayer().getOpponent().getPlayerKing().getPiecePosition(),
transitionBoard.currentPlayer().getLegalMoves());
if(!kingAttacks.isEmpty()){
return new MoveTransition(this.board,move,MoveStatus.LEAVES_PLAYER_IN_CHECK);
}
return new MoveTransition(transitionBoard,move,MoveStatus.DONE);
/* ========================Explanation=====================*/
/* if the move is ILLEGAL it's not part of the collection of legal moves that the player has,
then, do the move transation that your return that doesn't take us to a new board,
it returns to the same board and the move status is illegal..
---
The next thing is we use the move to POLYMORPHICLY EXECUTE the move and return us a new board
the we transition to.
And we ask ,Are there any attacks on the current player's king when we do that ?
if there are -> you can NOT make that move..
otherwise -> return the move transition board wrapped in a new move transition
you can't make any moves that exposes your king to check.
To calculate the attacks on the king , we invoked " calculateAttacksOnTile" , and we pass in
the current player's opponent king, becaus after we make the move , we're no longer the current player
,so we get the king's current position and then we get the curent players legal moves.
this's gonna return a new board, where the current player switches to the opponent
"Lyk if we are whites and seeing if blacks can have an attacks on the king or not"
*/
}
public abstract Collection<Piece> getActivePieces();
public abstract Alliance getAlliance();
public abstract Player getOpponent();
protected abstract Collection<Moves> calculateKingCastles(Collection<Moves> playerLegals, Collection<Moves> opponentsLegals);
}
package com.chess.engine.player;
import com.chess.engine.Alliance;
import com.chess.engine.board.Board;
import com.chess.engine.board.Moves;
import com.chess.engine.board.Tile;
import com.chess.engine.pieces.Piece;
import com.chess.engine.pieces.Rook;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.chess.engine.board.Moves.*;
/**
* Created by ibrahim on 5/1/17.
*/
public class WhitePlayer extends Player {
public WhitePlayer(final Board board,
final Collection<Moves> whiteStanderedLegalMoves,
final Collection<Moves> blackStanderedLegalMoves) {
super(board,whiteStanderedLegalMoves,blackStanderedLegalMoves);
}
@Override
public Collection<Piece> getActivePieces() {
return this.board.getWhitePieces();
}
@Override
public Alliance getAlliance() {
return Alliance.WHITE;
}
@Override
public Player getOpponent() {
return this.board.blackPlayer();
}
@Override
protected Collection<Moves> calculateKingCastles(final Collection<Moves> playerLegals,
final Collection<Moves> opponentsLegals) {
final List<Moves> KingCastles = new ArrayList<>();
if(this.playerKing.isFirstMove() && !this.isInCheck()){
//King Side Castle
if(!this.board.getTile(61).isTileOccupied() && !this.board.getTile(62).isTileOccupied()){
final Tile rookTile = this.board.getTile(63);
if(rookTile.isTileOccupied() && rookTile.getPiece().isFirstMove()){
if(Player.calculateAttacksOnTile(61,opponentsLegals).isEmpty() &&
Player.calculateAttacksOnTile(62,opponentsLegals).isEmpty() &&
rookTile.getPiece().getPieceType().isRook()){
KingCastles.add(new KingSideCastleMove(this.board,
this.playerKing,
62,
(Rook)rookTile.getPiece(),
rookTile.getTileCoordinate(),
61));
//The above statements are the in between tiles in castling
}//one more if
}//end if
}//end if
//Queen Side Castle
if(!this.board.getTile(59).isTileOccupied() &&
!this.board.getTile(58).isTileOccupied() &&
!this.board.getTile(57).isTileOccupied()){
final Tile rookTile = this.board.getTile(56);
if(rookTile.isTileOccupied() && rookTile.getPiece().isFirstMove() &&
Player.calculateAttacksOnTile(58,opponentsLegals).isEmpty() &&
Player.calculateAttacksOnTile(59,opponentsLegals).isEmpty() &&
rookTile.getPiece().getPieceType().isRook()){
KingCastles.add(new QueenSideCastleMove(this.board,
this.playerKing,
58,
(Rook)rookTile.getPiece(),
rookTile.getTileCoordinate(),
59));
}
}
}//end if
return ImmutableList.copyOf(KingCastles);
}//end of collection
}//class end
package com.chess.gui;
import com.chess.engine.board.Board;
import com.chess.engine.board.BoardUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
/**
* Created by ibrahim on 5/3/17.
*/
public class Table {
private final JFrame gameFrame;
private final BoardPanel boardPanel;
private final Board chessBoard;
private static String defaultPieceImagePath = "art/pieces/plains/";
private static final Dimension BOARD_PANEL_DIMENSION = new Dimension(400,400);
private final static Dimension OUTER_FRAME_DIMENSION = new Dimension(600,600);
private static final Dimension TILE_PANEL_DIMENSION =new Dimension(10,10) ;
private final Color lightTileColor = Color.decode("#FFFACD");
private final Color darkTileColor = Color.decode("#593E1A");
public Table() {
this.gameFrame = new JFrame("JChess");
this.gameFrame.setLayout(new BorderLayout());
final JMenuBar tableMenuBar= createTableMenuBar();
this.gameFrame.setJMenuBar(tableMenuBar);
this.boardPanel= new BoardPanel();
this.gameFrame.add(this.boardPanel,BorderLayout.CENTER);
this.chessBoard = Board.createStanderedBoard();
this.gameFrame.setSize(OUTER_FRAME_DIMENSION);
this.gameFrame.setVisible(true);
}
private JMenuBar createTableMenuBar() {
final JMenuBar tableMenuBar = new JMenuBar();
tableMenuBar.add(createFileMenu());
return tableMenuBar;
}//end of method " populate menu bar"
private JMenu createFileMenu() {
final JMenu fileMenu = new JMenu("file");
final JMenuItem openPGN = new JMenuItem("Load PGN File");
openPGN.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open up the PGN File!");
}
});
fileMenu.add(openPGN);
final JMenuItem exitMenuItem= new JMenuItem("Exit");
exitMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
fileMenu.add(exitMenuItem);
return fileMenu;
}//End of create file menu
private class BoardPanel extends JPanel {
//this class creats 8*8 JPanel -> 64 tiles for chess
final List<TilePanel> boardTiles;
BoardPanel(){
super(new GridLayout(8,8));
this.boardTiles = new ArrayList<>();
for (int i=0 ; i< BoardUtils.NUM_TILES;i++){
final TilePanel tilePanel= new TilePanel(this,i);
this.boardTiles.add(tilePanel);
add(tilePanel);
//Each tile keeping and adding two of JPanels
}//for loop end
setPreferredSize(BOARD_PANEL_DIMENSION);
validate();
}
}//end of board panel
private class TilePanel extends JPanel{
//Maps our tile in our game
private final int tileId;
TilePanel(final BoardPanel boardPanel,
final int tileId){
super(new GridBagLayout());
this.tileId = tileId;
setPreferredSize(TILE_PANEL_DIMENSION);
assignTileColor();
assignTilePieceIcon(Board.createStanderedBoard());
validate();
}
private void assignTilePieceIcon(final Board board){
this.removeAll();
if (board.getTile(this.tileId).isTileOccupied()){
try {
final BufferedImage image = ImageIO.read(new File(defaultPieceImagePath +
board.getTile(this.tileId).getPiece().getPieceAlliance().toString().substring(0, 1) +
board.getTile(this.tileId).getPiece().toString() + ".gif"));
add(new JLabel(new ImageIcon(image)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void assignTileColor() {
if (BoardUtils.EIGHTH_RANK[this.tileId] ||
BoardUtils.SIXTH_RANK[this.tileId] ||
BoardUtils.FOURTH_RANK[this.tileId]||
BoardUtils.SECOND_RANK[this.tileId]){
setBackground(this.tileId % 2 == 0 ? lightTileColor : darkTileColor);
}
else if(BoardUtils.SEVENTH_RANK[this.tileId]||
BoardUtils.FIFTH_RANK[this.tileId]||
BoardUtils.THIRD_RANK[this.tileId]||
BoardUtils.FIRST_RANK[this.tileId]){
setBackground(this.tileId % 2 != 0 ? lightTileColor : darkTileColor);
}
}///Assign tile color
}//end of tile panel
}
package com.chess;
import com.chess.engine.board.Board;
import com.chess.gui.Table;
/**
* Created by ibrahim on 5/1/17.
*/
public class JChess {
public static void main(String[] args){
Board board = Board.createStanderedBoard();
System.out.println(board);
Table table = new Table();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment