int[] lightSquareColour = {237, 174, 107};
int[] darkSquareColour = {122, 73, 21};
int[] lastMoveColour1 = {50, 255, 50, 40};
int[] lastMoveColour2 = {50, 255, 50, 60};
int[] selectedSquareColour = {0, 150, 255, 50};
int[] possibleMovesColour = {255, 0, 0, 60};
coordinate selectedSquare = null;
boolean WKingMoved = false;
boolean BKingMoved = false;
boolean WQRookMoved = false;
boolean WKRookMoved = false;
boolean BQRookMoved = false;
boolean BKRookMoved = false;
coordinate pMove1 = null;
coordinate pMove2 = null;
boolean promotion = false;
coordinate promotionPosition = null;
WPawn = loadImage("PawnW.png");
WKnight = loadImage("KnightW.png");
WBishop = loadImage("BishopW.png");
WRook = loadImage("RookW.png");
WQueen = loadImage("QueenW.png");
WKing = loadImage("KingW.png");
BPawn = loadImage("PawnB.png");
BKnight = loadImage("KnightB.png");
BBishop = loadImage("BishopB.png");
BRook = loadImage("RookB.png");
BQueen = loadImage("QueenB.png");
BKing = loadImage("KingB.png");
WPawn.resize(squareSize, squareSize);
WKnight.resize(squareSize, squareSize);
WBishop.resize(squareSize, squareSize);
WRook.resize(squareSize, squareSize);
WQueen.resize(squareSize, squareSize);
WKing.resize(squareSize, squareSize);
BPawn.resize(squareSize, squareSize);
BKnight.resize(squareSize, squareSize);
BBishop.resize(squareSize, squareSize);
BRook.resize(squareSize, squareSize);
BQueen.resize(squareSize, squareSize);
BKing.resize(squareSize, squareSize);
turn = turn == White ? Black : White;
if(millis() < 5000)displayBoard();
int choice = floor(mouseX / (width / 4));
board[promotionPosition.i][promotionPosition.j] = turn | Queen;
board[promotionPosition.i][promotionPosition.j] = turn | Rook;
board[promotionPosition.i][promotionPosition.j] = turn | Bishop;
board[promotionPosition.i][promotionPosition.j] = turn | Knight;
coordinate klc = locateKing(board, White);
if (selectedSquare == null) {
if (mouseX > 0 && mouseX < 800 && mouseY > 0 && mouseY < 800) {
selectedSquare = new coordinate(floor(mouseX / squareSize), floor(mouseY / squareSize));
ArrayList<move> moves = movesFromSquare(board, selectedSquare, turn);
if (floor(mouseX / squareSize) == m.i2 && floor(mouseY / squareSize) == m.j2) {
int[][] temp = makeUpdatingMove(board, m.i1, m.j1, m.i2, m.j2);
checkForGameOver(board, turn);
String checkForGameOver(int[][] b, int t) {
HashMap<coordinate, coordinate> moves = generateLegalMoves(b, t);
int[][] makeUpdatingMove(int[][] b, int i1, int j1, int i2, int j2) {
int[][] temp = makeMove(b, i1, j1, i2, j2);
if (selectedPiece(selectedSquare) == (White | King)) {
if (selectedPiece(selectedSquare) == (Black | King)) {
if (selectedPiece(selectedSquare) == (White | Rook) && i1 == 0) {
if (selectedPiece(selectedSquare) == (White | Rook) && i1 == 7) {
if (selectedPiece(selectedSquare) == (Black | Rook) && i1 == 0) {
if (selectedPiece(selectedSquare) == (Black | Rook) && i1 == 7) {
pMove1 = new coordinate(i1, j1);
pMove2 = new coordinate(i2, j2);
if (j2 == (turn == White ? 0 : 7) && (selectedPiece(selectedSquare) == (White | Pawn) || selectedPiece(selectedSquare) == (Black | Pawn))) {
promotionPosition = new coordinate(i2, j2);
coordinate locateKing(int[][] boardState, int kingColour) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (boardState[i][j] == (kingColour | King)) {
return new coordinate(i, j);
return new coordinate(11111, 11111);
boolean isCheck(int[][] boardState, int kingColour) {
HashMap<coordinate, coordinate> pseudoLegal = generatePseudoLegalMoves(boardState, otherColour(kingColour));
coordinate kingLocation = locateKing(boardState, kingColour);
for (coordinate c : pseudoLegal.values()) {
if (c.i == kingLocation.i && c.j == kingLocation.j
HashMap<coordinate, coordinate> generateLegalMoves(int[][] boardState, int colour) {
HashMap<coordinate, coordinate> pseudoLegal = generatePseudoLegalMoves(boardState, colour);
HashMap<coordinate, coordinate> legalMoves = new HashMap<coordinate, coordinate>();
for (coordinate c1 : pseudoLegal.keySet()) {
coordinate c2 = pseudoLegal.get(c1);
int[][] nb = makeMove(boardState, c1.i, c1.j, c2.i, c2.j);
if(boardState[c1.i][c1.j] == (White | King) || boardState[c1.i][c1.j] == (Black | King)) {
if(abs(c1.i - c2.i) == 2) {
if(!isCheck(makeMove(boardState, c1.i, c1.j, (c1.i + c2.i) / 2, c2.j), (boardState[c1.i][c1.j] >> 3) * 8)) {
if (!isCheck(nb, colour)) {
return(c==White ? Black : White);
HashMap<coordinate, coordinate> generatePseudoLegalMoves(int[][] boardState, int colour) {
HashMap<coordinate, coordinate> moves = new HashMap<coordinate, coordinate>();
for (var j = 0; j < 8; j++) {
for (var i = 0; i < 8; i++) {
int pieceAt = boardState[i][j];
int pieceColour = (pieceAt >> 3) << 3;
int pieceType = pieceAt - pieceColour;
if (pieceColour == colour) {
int direction = pieceColour == White ? -1 : 1;
if (j != (pieceColour == White ? 0 : 7)) {
if (emptySquare(boardState, i, j + direction)) {
moves.put(new coordinate(i, j), new coordinate(i, j + direction));
if (j != (pieceColour == White ? 1 : 6)) {
if (emptySquare(boardState, i, j + direction * 2) && j == (pieceColour == White ? 6 : 1)) {
moves.put(new coordinate(i, j), new coordinate(i, j + direction * 2));
if (enemyPiece(boardState, i + 1, j + direction, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(i + 1, j + direction));
if (boardState[i+1][j] == (otherColour(pieceColour) | Pawn)) {
if (abs(pMove1.j - pMove2.j) == 2 && pMove2.j == (pieceColour == White ? 3 : 4)) {
moves.put(new coordinate(i, j), new coordinate(i + 1, j + direction));
if (enemyPiece(boardState, i - 1, j + direction, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(i - 1, j + direction));
if (boardState[i-1][j] == (otherColour(pieceColour) | Pawn)) {
if (abs(pMove1.j - pMove2.j) == 2 && pMove2.j == (pieceColour == White ? 3 : 4)) {
moves.put(new coordinate(i, j), new coordinate(i - 1, j + direction));
if (pieceType == Rook || pieceType == Queen) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
if (pieceType == Bishop || pieceType == Queen) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
for (int r = 1; r < 16; r++) {
int ni = i + (r * iDirection);
int nj = j + (r * jDirection);
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (!emptySquare(boardState, ni, nj) && !enemyPiece(boardState, ni, nj, pieceColour)) {
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (pieceColour == White) {
if (emptySquare(boardState, 5, 7) && emptySquare(boardState, 6, 7)) {
if (!WKingMoved && !WKRookMoved) {
moves.put(new coordinate(4, 7), new coordinate(6, 7));
if (emptySquare(boardState, 3, 7) && emptySquare(boardState, 2, 7) && emptySquare(boardState, 1, 7)) {
if (!WKingMoved && !WQRookMoved) {
moves.put(new coordinate(4, 7), new coordinate(2, 7));
if (emptySquare(boardState, 5, 0) && emptySquare(boardState, 6, 0)) {
if (!BKingMoved && !BKRookMoved) {
moves.put(new coordinate(4, 0), new coordinate(6, 0));
if (emptySquare(boardState, 3, 0) && emptySquare(boardState, 2, 0) && emptySquare(boardState, 1, 0)) {
if (!BKingMoved && !BQRookMoved) {
moves.put(new coordinate(4, 0), new coordinate(2, 0));
if (pieceType == Knight) {
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (ni < 0 || ni > 7 || nj < 0 || nj > 7) {
if (emptySquare(boardState, ni, nj)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
if (enemyPiece(boardState, ni, nj, pieceColour)) {
moves.put(new coordinate(i, j), new coordinate(ni, nj));
boolean emptySquare(int[][] b, int i, int j) {
boolean enemyPiece(int[][] b, int i, int j, int friendly) {
if (pieceColour(b[i][j]) != friendly && b[i][j] != None) {
int[][] makeMove(int[][] b, int i1, int j1, int i2, int j2) {
int[][] newBoard = new int[8][8];
for (int i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
newBoard[i][j] = b[i][j];
if (newBoard[i1][j1] == (White | King)) {
if (i1 == 4 && i2 == 6) {
newBoard[5][7] = White | Rook;
if (i1 == 4 && i2 == 2) {
newBoard[3][7] = White | Rook;
if (newBoard[i1][j1] == (Black | King)) {
if (i1 == 4 && i2 == 6) {
newBoard[5][0] = Black | Rook;
if (i1 == 4 && i2 == 2) {
newBoard[3][0] = Black | Rook;
if (newBoard[i1][j1] == (White | Pawn) || newBoard[i1][j1] == (Black | Pawn)) {
if (i1 != i2 && j1 != j2) {
if (newBoard[i2][j2] == None) {
board[0][0] = Black | Rook;
board[1][0] = Black | Knight;
board[2][0] = Black | Bishop;
board[3][0] = Black | Queen;
board[4][0] = Black | King;
board[5][0] = Black | Bishop;
board[6][0] = Black | Knight;
board[7][0] = Black | Rook;
board[0][1] = Black | Pawn;
board[1][1] = Black | Pawn;
board[2][1] = Black | Pawn;
board[3][1] = Black | Pawn;
board[4][1] = Black | Pawn;
board[5][1] = Black | Pawn;
board[6][1] = Black | Pawn;
board[7][1] = Black | Pawn;
board[0][7] = White | Rook;
board[1][7] = White | Knight;
board[2][7] = White | Bishop;
board[3][7] = White | Queen;
board[4][7] = White | King;
board[5][7] = White | Bishop;
board[6][7] = White | Knight;
board[7][7] = White | Rook;
board[0][6] = White | Pawn;
board[1][6] = White | Pawn;
board[2][6] = White | Pawn;
board[3][6] = White | Pawn;
board[4][6] = White | Pawn;
board[5][6] = White | Pawn;
board[6][6] = White | Pawn;
board[7][6] = White | Pawn;
int selectedPiece(coordinate sq) {
return board[sq.i][sq.j];
fill(lightSquareColour[0], lightSquareColour[1], lightSquareColour[2]);
for (int j = 0; j < 8; j++) {
for (int i = 0; i < 8; i++) {
fill(darkSquareColour[0], darkSquareColour[1], darkSquareColour[2]);
rect(i * squareSize, j * squareSize, squareSize, squareSize);
fill(darkSquareColour[0], darkSquareColour[1], darkSquareColour[2]);
rect(i * squareSize, j * squareSize, squareSize, squareSize);
boolean highlighted = false;
if (pMove1.i == i && pMove1.j == j) {
fill(lastMoveColour1[0], lastMoveColour1[1], lastMoveColour1[2], lastMoveColour1[3]);
rect(pMove1.i * squareSize, pMove1.j * squareSize, squareSize, squareSize);
if (pMove2.i == i && pMove2.j == j) {
fill(lastMoveColour2[0], lastMoveColour2[1], lastMoveColour2[2], lastMoveColour2[3]);
rect(pMove2.i * squareSize, pMove2.j * squareSize, squareSize, squareSize);
fill(darkSquareColour[0], darkSquareColour[1], darkSquareColour[2]);
rect(i * squareSize, j * squareSize, squareSize, squareSize);
fill(darkSquareColour[0], darkSquareColour[1], darkSquareColour[2]);
rect(i * squareSize, j * squareSize, squareSize, squareSize);
image(pieceImg, (i+0.5) * squareSize, (j+0.5) * squareSize, squareSize, squareSize);
if (selectedSquare != null) {
fill(selectedSquareColour[0], selectedSquareColour[1], selectedSquareColour[2], selectedSquareColour[3]);
rect(selectedSquare.i * squareSize, selectedSquare.j * squareSize, squareSize, squareSize);
if (selectedPiece(selectedSquare) != None) {
ArrayList<move> moves = movesFromSquare(board, selectedSquare, turn);
fill(possibleMovesColour[0], possibleMovesColour[1], possibleMovesColour[2], possibleMovesColour[3]);
rect(m.i2 * squareSize, m.j2 * squareSize, squareSize, squareSize);
String gameOver = checkForGameOver(board, turn);
text(gameOver, 810, height / 2);
text("White to move", 810, 700);
text("Black to move", 810, 100);
rect(0, 0, width, height);
image(WQueen, 0.125 * width, height/2);
image(WRook, 0.375 * width, height/2);
image(WBishop, 0.625 * width, height/2);
image(WKnight, 0.875 * width, height/2);
image(BQueen, 0.125 * width, height/2);
image(BRook, 0.375 * width, height/2);
image(BBishop, 0.625 * width, height/2);
image(BKnight, 0.875 * width, height/2);
ArrayList<move> movesFromSquare(int[][] b, coordinate sq, int whoseTurn) {
ArrayList<move> moves = new ArrayList<move>();
HashMap<coordinate, coordinate> plm = generateLegalMoves(b, whoseTurn);
for (coordinate c : plm.keySet()) {
coordinate v2 = plm.get(c);
if (v1.i == sq.i && v1.j == sq.j)moves.add(new move(v1.i, v1.j, v2.i, v2.j));
move(int i1_, int j1_, int i2_, int j2_) {
coordinate(int i_, int j_) {