// Constants
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
// Death sound, credit:
// https://www.youtube.com/watch?v=r6JK-gRELI0
const soundDead = "/uploads/dalye54/Wilhelm_death.mp3";
const startRadius = 500;
const maxRadius = startRadius * 10;
const skycolor = '#4442ff';
var deathSound = new Audio(soundDead);
AB.clockTick = 50;
AB.maxSteps = 1000000;
ABWorld.drawCameraControls = false;
// beach skyboxes, credit:
// https://opengameart.org/content/beach-skyboxes
const skyboxArray = ["/uploads/dalye54/posx.jpg",
"/uploads/dalye54/negx.jpg",
"/uploads/dalye54/posy.jpg",
"/uploads/dalye54/negy.jpg",
"/uploads/dalye54/posz.jpg",
"/uploads/dalye54/negz.jpg"
];
const walnutCube = new THREE.TextureLoader().load('/uploads/dalye54/walnut.jpg');
const beechCube = new THREE.TextureLoader().load('/uploads/dalye54/beech.jpg');
// Class Information
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
var selectorSide = new THREE.BoxGeometry (10, 1, 50); // Used for displaying the selector.
var selectorRoof = new THREE.BoxGeometry (50, 1, 10); // Used for displaying the selector.
var nextMove = new THREE.BoxGeometry(30, 1, 30); // Used for displaying the next possible moves.
var nextKillSide = new THREE.BoxGeometry(10,1,30); // Used for displaying the next possible moves when opposite piece is in the position.
var nextKillRoof = new THREE.BoxGeometry(30,1,10); // Used for displaying the next possible moves when opposite piece is in the position.
var chessPieces;
// Load in the 3D objects for the chess pieces.
function loadResources()
{
var first = new THREE.MTLLoader();
first.setResourcePath ( "/uploads/dalye54/" );
first.setPath ( "/uploads/dalye54/" );
first.load ("chess.mtl", function (materials)
{
materials.preload();
var second = new THREE.OBJLoader();
second.setPath( "/uploads/dalye54/" );
second.setMaterials(materials);
second.load("chess.obj", function (object)
{
chessPieces = object;
if ( asynchFinished() ) displayPieces() ;
});
});
}
// Function for waiting for the load to finish.
function asynchFinished()
{
if ( chessPieces ) return true;
else return false;
}
// Game class, which keeps track of what colour should be making a move.
class Game
{
constructor() // Set the colour to white at the start.
{
this.turn = "white";
this.winner = false;
this.colourWinner;
}
switchTurn() // Switch colour when a move has been made.
{
if (this.turn == "white")
{
this.turn = "black";
return;
}
else if (this.turn == "black")
{
this.turn = "white";
return;
}
}
displayTurn() // Return the current colour that has to make a move.
{
return this.turn;
}
gameOver(winColour)
{
this.colourWinner = winColour;
this.winner = true;
}
}
// Player class, keeps track of what colour the player has picked to play.
class Player
{
constructor() // Set the colour to white at the start.
{
this.colour = "white";
}
displayColour() // Return the current colour the place has chosen.
{
return this.colour;
}
setBlack() // Switch colour to black.
{
this.colour = 'black';
}
setWhite() // Switch colour to white.
{
this.colour = 'white';
}
}
var user = new Player(); // Initialise the player class.
// DisplaySelect class which is the blue box that is what the user controls when moving.
class DisplaySelect
{
constructor(x_cord, z_cord) // Set the cords of the selecter to somewhere on the board.
{
this.piecePosition = [x_cord, z_cord];
this.parts = [];
}
displayPiece() // Displays the piece on the board
{
colour = new THREE.MeshBasicMaterial( { color: 'blue' } );
theLeft = new THREE.Mesh(selectorSide, colour);
theLeft.position.x = -195 + (50*this.piecePosition[0]);
theLeft.position.y = 25.5;
theLeft.position.z = -175 + (50*this.piecePosition[1]);
theRight = new THREE.Mesh(selectorSide, colour);
theRight.position.x = -155 + (50*this.piecePosition[0]);
theRight.position.y = 25.5;
theRight.position.z = -175 + (50*this.piecePosition[1]);
theBottom = new THREE.Mesh(selectorRoof, colour);
theTop = new THREE.Mesh(selectorRoof, colour);
theTop.position.x = -175 + (50*this.piecePosition[0]);
theTop.position.y = 25.5;
theTop.position.z = -195 + (50*this.piecePosition[1]);
theBottom.position.x = -175 + (50*this.piecePosition[0]);
theBottom.position.y = 25.5;
theBottom.position.z = -155 + (50*this.piecePosition[1]);
this.parts.push(theLeft,theRight,theBottom,theTop);
ABWorld.scene.add(theLeft);
ABWorld.scene.add(theRight);
ABWorld.scene.add(theTop);
ABWorld.scene.add(theBottom);
}
deletePiece() // Delete the piece from the board
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
down() // Move the piece down
{
if (this.piecePosition[1] == 7)
{
return;
}
this.piecePosition[1] += 1;
length = this.parts.length;
for (var i = 0; i < length; i++)
{
this.parts[i].translateZ(50);
}
}
up() // Move the piece up
{
if (this.piecePosition[1] === 0)
{
return;
}
this.piecePosition[1] -= 1;
length = this.parts.length;
for (var i = 0; i < length; i++)
{
this.parts[i].translateZ(-50);
}
}
right() // Move the piece right
{
if (this.piecePosition[0] == 7)
{
return;
}
this.piecePosition[0] += 1;
length = this.parts.length;
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(50);
}
}
left() // Move the piece left
{
if (this.piecePosition[0] === 0)
{
return;
}
this.piecePosition[0] -= 1;
length = this.parts.length;
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(-50);
}
}
location() // Return the current location of the piece
{
return this.piecePosition;
}
}
var part;
var enPassant = [];
// Pawn class
class Pawn
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][6].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -341 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 375 + (50*this.piecePosition[1]);
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][0].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -341 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part); // Add the piece to the world
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Uses a different method for displaying moves as pawns can have a different type of move for their first.
{
var tmpXCord, tmpZCord;
possibleMoves[0].push(this.piecePosition);
if (this.pieceColour == 'white') // Direction switches by the colour of the piece.
{
tmpZCord = this.piecePosition[1] - 1;
} else {
tmpZCord = this.piecePosition[1] + 1;
}
tmpXCord = this.piecePosition[0];
var lengthCheck;
if (this.pieceColour == "black")
{
if (this.piecePosition[1] == 1) // If it is the pawns first move then it can move 2 spaces
{
lengthCheck = 2;
} else
{
lengthCheck = 1;
}
} else
{
if (this.piecePosition[1] == 6)
{
lengthCheck = 2;
} else
{
lengthCheck = 1;
}
}
for (var i = 0; i < lengthCheck; i++) // Loop to check the possible moves a piece could make
{
if (tmpZCord == 8 || tmpZCord == -1 || tmpXCord == 8 || tmpXCord == -1) // Makes sure the coordinate is on the board
{
break;
}
if (map[tmpZCord][tmpXCord] == "")
{
displayOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
} else
{
break;
}
if (this.pieceColour == 'white')
{
tmpZCord -= 1;
} else {
tmpZCord += 1;
}
}
tmpXCord = this.piecePosition[0];
tmpZCord = this.piecePosition[1];
if (this.pieceColour == 'white') // Checks to see if the white pawn can take any pieces diagonal from it
{
if (tmpZCord != 8 && tmpZCord != 0 && tmpXCord != 7 && tmpXCord != -1 && map[tmpZCord - 1][tmpXCord + 1][0] == 'black') // Check that the piece is the opposite colour and is on the board
{
displayDeathOnBoard(tmpXCord + 1,tmpZCord - 1);
possibleMoves[1].push([tmpXCord + 1,tmpZCord - 1]);
}
if (tmpZCord != 8 && tmpZCord != 0 && tmpXCord != 8 && tmpXCord != 0 && map[tmpZCord - 1][tmpXCord - 1][0] == 'black')
{
displayDeathOnBoard(tmpXCord - 1, tmpZCord - 1);
possibleMoves[1].push([tmpXCord - 1,tmpZCord - 1]);
}
} else { // Checks to see if the black pawn can take any pieces diagonal from it
if (tmpZCord != 7 && tmpZCord != -1 && tmpXCord != 7 && tmpXCord != -1 && map[tmpZCord + 1][tmpXCord + 1][0] == 'white') // Check that the piece is the opposite colour and is on the board
{
displayDeathOnBoard(tmpXCord + 1,tmpZCord + 1);
possibleMoves[1].push([tmpXCord + 1,tmpZCord + 1]);
}
if (tmpZCord != 7 && tmpZCord != -1 && tmpXCord != 8 && tmpXCord != 0 && map[tmpZCord + 1][tmpXCord - 1][0] == 'white')
{
displayDeathOnBoard(tmpXCord - 1, tmpZCord + 1);
possibleMoves[1].push([tmpXCord - 1,tmpZCord + 1]);
}
}
if (enPassant.length > 0) // En Passant check to see if this pawn could peform an En Passant maneuver.
{
if (enPassant[0] == true) // If the list is set to true that means a pawn has just moved 2 pieces
{
length = 2;
for (i = 0; i < length; i++)
{
if (enPassant[1][i][0] == this.piecePosition[0] && enPassant[1][i][1] == this.piecePosition[1]) // If we are beside the pawn we can perform the maneuver
{
displayDeathOnBoard(enPassant[2][0], enPassant[2][1]);
possibleMoves[1].push(enPassant[2]);
console.log("We can En Passant this!")
}
}
}
}
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
for (var i = 0; i < length; i++) // Translates the piece to the new postion
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0]
var zCord = this.piecePosition[1]
if (this.pieceColour == "white")
{
if ((zCord - 1) <= 7 && (zCord - 1) >= 0 && (xCord + 1) <= 7 && (xCord + 1) >= 0)
{
checkMap[zCord - 1][xCord + 1] = "x";
}
if ((zCord - 1) <= 7 && (zCord - 1) >= 0 && (xCord - 1) <= 7 && (xCord - 1) >= 0)
{
checkMap[zCord - 1][xCord - 1] = "x";
}
} else
{
if ((zCord + 1) <= 7 && (zCord + 1) >= 0 && (xCord + 1) <= 7 && (xCord + 1) >= 0)
{
checkMap[zCord + 1][xCord + 1] = "x";
}
if ((zCord + 1) <= 7 && (zCord + 1) >= 0 && (xCord - 1) <= 7 && (xCord - 1) >= 0)
{
checkMap[zCord + 1][xCord - 1] = "x";
}
}
}
pieceType() // Returns the name of the piece
{
return "pawn";
}
}
// Rook class
class Rook
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
this.hasMoved = false; // Has a special attribute used for Castling
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][7].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -5 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 378 + (50*this.piecePosition[1]);
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][1].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -5 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part); // Add the piece to the world
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Displays all the possible moves the rook piece can make
{
var xCord, zCord;
possibleMoves[0].push(this.piecePosition);
xCord = this.piecePosition[0];
zCord = this.piecePosition[1];
displayLineCheck([xCord, zCord], 0, 1, this.pieceColour) // Uses a function to perform the tasks of displaying a certain direction of moves
displayLineCheck([xCord, zCord], 0, -1, this.pieceColour)
displayLineCheck([xCord, zCord], 1, 0, this.pieceColour)
displayLineCheck([xCord, zCord], -1, 0, this.pieceColour)
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
for (var i = 0; i < length; i++) // Translates the piece to the new postion
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
pieceMoved() // When the castle has moved it can no longer castle with the king
{
this.hasMoved = true;
}
checkMove() // Returns whether the rook has moved
{
return this.hasMoved
}
pieceType() // Returns the name of the piece
{
return "rook";
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0];
var zCord = this.piecePosition[1];
lineCheck([xCord, zCord], 0, 1);
lineCheck([xCord, zCord], 1, 0);
lineCheck([xCord, zCord], 0, -1);
lineCheck([xCord, zCord], -1, 0);
}
}
// Knight class
class Knight
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][8].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -277 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = -725 + (50*this.piecePosition[1]);
part.rotation.y = Math.PI / 1; // Rotate the piece so it is facing the correct way
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][2].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -72 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part);
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Displays all the possible moves the knight piece can make
{
var tmpXCord, tmpZCord;
possibleMoves[0].push(this.piecePosition);
tmpXCord = this.piecePosition[0];
tmpZCord = this.piecePosition[1];
displaySingleCheck([tmpXCord, tmpZCord], 2,-1,this.pieceColour,this.pieceType()); // A knight uses a different function to display each move
displaySingleCheck([tmpXCord, tmpZCord], 2,1,this.pieceColour,this.pieceType()); // This function does not use a for loop and simply displays the specific position
displaySingleCheck([tmpXCord, tmpZCord], 1,2,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], 1,-2,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -1,2,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -1,-2,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -2,-1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -2,1,this.pieceColour,this.pieceType());
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
if (this.pieceColour === 'white') // Translates the piece to the new postion
{
for (var i = 0; i < length; i++) // If the piece is white then it must move the opposite direction due to the fact the position of the piece was turned around
{
this.parts[i].translateX(xPosition * -50);
this.parts[i].translateZ(zPosition * -50);
}
}
else
{
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0];
var zCord = this.piecePosition[1];
singleValueCheck([xCord, zCord],2, -1)
singleValueCheck([xCord, zCord],2, 1)
singleValueCheck([xCord, zCord],1, 2)
singleValueCheck([xCord, zCord],1, -2)
singleValueCheck([xCord, zCord],-1, 2)
singleValueCheck([xCord, zCord],-1, -2)
singleValueCheck([xCord, zCord],-2, -1)
singleValueCheck([xCord, zCord],-2, 1)
}
pieceType() // Returns the name of the piece
{
return "knight";
}
}
// Bishop class
class Bishop
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][9].clone();
part.scale.multiplyScalar (0.25);
part.position.x = -210 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = -725 + (50*this.piecePosition[1]);
part.rotation.y = Math.PI / 1;
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][3].clone();
part.scale.multiplyScalar (0.25);
part.position.x = -141 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part); // Add the piece to the world
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Displays all the possible moves the Bishop piece can make
{
var xCord, zCord;
possibleMoves[0].push(this.piecePosition);
xCord = this.piecePosition[0];
zCord = this.piecePosition[1];
displayLineCheck([xCord, zCord], 1, 1, this.pieceColour);
displayLineCheck([xCord, zCord], 1, -1, this.pieceColour);
displayLineCheck([xCord, zCord], -1, 1, this.pieceColour);
displayLineCheck([xCord, zCord], -1, -1, this.pieceColour);
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
if (this.pieceColour === 'white') // Translates the piece to the new postion
{
for (var i = 0; i < length; i++) // If the piece is white then it must move the opposite direction due to the fact the position of the piece was turned around
{
this.parts[i].translateX(xPosition * -50);
this.parts[i].translateZ(zPosition * -50);
}
}
else
{
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0];
var zCord = this.piecePosition[1];
lineCheck([xCord, zCord], 1, 1);
lineCheck([xCord, zCord], 1, -1);
lineCheck([xCord, zCord], -1, 1);
lineCheck([xCord, zCord], -1, -1);
}
pieceType() // Returns the name of the piece
{
return "bishop";
}
}
// Queen class
class Queen
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][10].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -140 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = -725 + (50*this.piecePosition[1]);
part.rotation.y = Math.PI / 1; // Rotate the piece so it is facing the correct way
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][4].clone();
part.scale.multiplyScalar ( .25 );
part.position.x = -210 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part);
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Displays all the possible moves the Queen piece can make
{
var xCord, zCord;
possibleMoves[0].push(this.piecePosition);
xCord = this.piecePosition[0];
zCord = this.piecePosition[1];
displayLineCheck([xCord, zCord], 0, 1, this.pieceColour);
displayLineCheck([xCord, zCord], 0, -1, this.pieceColour);
displayLineCheck([xCord, zCord], 1, 0, this.pieceColour);
displayLineCheck([xCord, zCord], -1, 0, this.pieceColour);
displayLineCheck([xCord, zCord], 1, 1, this.pieceColour);
displayLineCheck([xCord, zCord], 1, -1, this.pieceColour);
displayLineCheck([xCord, zCord], -1, 1, this.pieceColour);
displayLineCheck([xCord, zCord], -1, -1, this.pieceColour);
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
if (this.pieceColour === 'white') // Translates the piece to the new postion
{
for (var i = 0; i < length; i++) // If the piece is white then it must move the opposite direction due to the fact the position of the piece was turned around
{
this.parts[i].translateX(xPosition * -50);
this.parts[i].translateZ(zPosition * -50);
}
}
else
{
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0];
var zCord = this.piecePosition[1];
lineCheck([xCord, zCord], 1, 1);
lineCheck([xCord, zCord], 1, -1);
lineCheck([xCord, zCord], -1, 1);
lineCheck([xCord, zCord], -1, -1);
lineCheck([xCord, zCord], 1, 0);
lineCheck([xCord, zCord], -1, 0);
lineCheck([xCord, zCord], 0, 1);
lineCheck([xCord, zCord], 0, -1);
}
pieceType() // Returns the name of the piece
{
return "queen";
}
}
// King class
class King
{
constructor(x_cord, z_cord, pieceColour) // Sets the starting coordinate for the piece and the colour
{
this.piecePosition = [x_cord, z_cord];
this.pieceColour = pieceColour;
this.parts = [];
this.hasMoved = false; // Has a special attribute used for Castling
}
displayPiece() // Displays the piece
{
if (this.pieceColour === 'white') // Displays the white model if its a white piece
{
part = chessPieces['children'][11].clone();
part.scale.multiplyScalar ( 0.25 );
part.position.x = -71 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = -725 + (50*this.piecePosition[1]);
part.rotation.y = Math.PI / 1; // Rotate the piece so it is facing the correct way
}
else // Displays the black model if its a black piece
{
part = chessPieces['children'][5].clone();
part.scale.multiplyScalar ( 0.25 );
part.position.x = -279 + (50*this.piecePosition[0]);
part.position.y = 25;
part.position.z = 212 + (50*this.piecePosition[1]);
}
this.parts.push(part);
ABWorld.scene.add(part);
}
deletePiece() // Removes the piece model
{
length = this.parts.length;
for (var i = 0; i < length; i++)
{
ABWorld.scene.remove(this.parts[i]);
}
}
displayMoves() // Displays all the possible moves the king piece can make
{
var tmpXCord, tmpZCord;
possibleMoves[0].push(this.piecePosition);
tmpXCord = this.piecePosition[0];
tmpZCord = this.piecePosition[1];
displaySingleCheck([tmpXCord, tmpZCord], 1,-1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], 1,0,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], 1,1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], 0,1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], 0,-1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -1,-1,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -1,0,this.pieceColour,this.pieceType());
displaySingleCheck([tmpXCord, tmpZCord], -1,1,this.pieceColour,this.pieceType());
if (map[tmpZCord][tmpXCord][2].checkMove() === false && map[tmpZCord][tmpXCord + 1] === "" && map[tmpZCord][tmpXCord + 2] === "" && map[tmpZCord][tmpXCord + 3] !== "" && map[tmpZCord][tmpXCord + 3][2].pieceType() == "rook" && map[tmpZCord][tmpXCord + 3][2].checkMove() === false)
{
displaySingleCheck([tmpXCord, tmpZCord], 2,0,this.pieceColour,this.pieceType());
}
if (map[tmpZCord][tmpXCord][2].checkMove() === false && map[tmpZCord][tmpXCord - 1] === "" && map[tmpZCord][tmpXCord - 2] === "" && map[tmpZCord][tmpXCord - 3] === "" && map[tmpZCord][tmpXCord - 4] !== "" && map[tmpZCord][tmpXCord - 4][2].pieceType() == "rook" && map[tmpZCord][tmpXCord - 4][2].checkMove() === false)
{
displaySingleCheck([tmpXCord, tmpZCord], -2,0,this.pieceColour,this.pieceType());
}
}
updatePosition(XCord, ZCord) // Updates on the board once the piece has been moved
{
var xPosition = XCord - this.piecePosition[0]; // Gets the difference between the original location and the new location
var zPosition = ZCord - this.piecePosition[1];
this.piecePosition[0] = XCord;
this.piecePosition[1] = ZCord;
length = this.parts.length;
if (this.pieceColour === 'white') // Translates the piece to the new postion
{
for (var i = 0; i < length; i++) // If the piece is white then it must move the opposite direction due to the fact the position of the piece was turned around
{
this.parts[i].translateX(xPosition * -50);
this.parts[i].translateZ(zPosition * -50);
}
}
else
{
for (var i = 0; i < length; i++)
{
this.parts[i].translateX(xPosition * 50);
this.parts[i].translateZ(zPosition * 50);
}
}
}
checkKing() // For marking where the opposing king cant move too
{
var xCord = this.piecePosition[0];
var zCord = this.piecePosition[1];
singleValueCheck([xCord, zCord],0, 1);
singleValueCheck([xCord, zCord],1, 1);
singleValueCheck([xCord, zCord],-1, 1);
singleValueCheck([xCord, zCord],-1, 0);
singleValueCheck([xCord, zCord],1, 0);
singleValueCheck([xCord, zCord],0, -1);
singleValueCheck([xCord, zCord],1, -1);
singleValueCheck([xCord, zCord],-1, -1);
}
pieceMoved()
{
this.hasMoved = true;
}
checkMove()
{
return this.hasMoved;
}
pieceType() // Returns the name of the piece
{
return "king";
}
}
var displaySelector = new DisplaySelect(0,0); // initialise the selecter at postion 0,0
// Loop through a given direction displaying possible moves
function displayLineCheck(location, xCordDifference, zCordDifference, colour)
{
var tmpXCord, tmpZCord;
tmpXCord = location[0];
tmpZCord = location[1];
for (var i = 0; i < 8; i++) // Uses the same diagonal display moves as the Bishop class
{
tmpZCord += zCordDifference; // Changing the z cord
tmpXCord += xCordDifference; // Changing the x cord
if (tmpZCord == 8 || tmpZCord == -1 || tmpXCord == 8 || tmpXCord == -1) // Break the loop if the square is not blank or the coordinate is out of the board
{
break; // Break if any of the points are out of the 7x7 array
}
if (map[tmpZCord][tmpXCord] === "") // If an empty spot then display it as a move
{
displayOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
} else if (map[tmpZCord][tmpXCord][0] !== colour) // If not empty but the opposite players colour then display it as a kill attempt
{
displayDeathOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
break;
} else
{
break;
}
}
}
// Check given input displaying it if its a possible move
function displaySingleCheck(location, xCordDifference, zCordDifference, colour, type)
{
var tmpXCord, tmpZCord;
tmpXCord = location[0] + xCordDifference;
tmpZCord = location[1] + zCordDifference;
if (tmpZCord > 7 || tmpZCord < 0 || tmpXCord > 7 || tmpXCord < 0) // Checks to make sure the changed positions are on the board
{
return;
}
if (map[tmpZCord][tmpXCord] === "")
{
if (type == "king") // Checks if its a king checking its moves as a king wont be able to move into a square that a opposite piece could move too
{
if (checkMap[tmpZCord][tmpXCord] === "") // Checks on the checkMap to make sure their isnt an opposing piece watching that position
{
displayOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
return;
}
} else
{
displayOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
return;
}
} else if (map[tmpZCord][tmpXCord][0] !== colour) // Same checks apply like the previous
{
if (type == "king")
{
if (checkMap[tmpZCord][tmpXCord] === "")
{
displayDeathOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
return;
}
} else
{
displayDeathOnBoard(tmpXCord,tmpZCord);
possibleMoves[1].push([tmpXCord,tmpZCord]);
return;
}
}
}
// For Positioning Pieces
// -----------------------------------------------------------------------------------------------------------------
var HL00,HL01,HL02,HL03,HL04,HL05,HL06,HL07,HL10,HL11,HL12,HL13,HL14,HL15,HL16,HL17,HL20,HL21,HL22,HL23,HL24,HL25,HL26,HL27,HL30,HL31,HL32,HL33,HL34,HL35,HL36,HL37,HL40,HL41,HL42,HL43,HL44,HL45,HL46,HL47,HL50,HL51,HL52,HL53,HL54,HL55,HL56,HL57,HL60,HL61,HL62,HL63,HL64,HL65,HL66,HL67,HL70,HL71,HL72,HL73,HL74,HL75,HL76,HL77; // Used for showing possible moves
var possibleMoves = [[],[]]; // Possible moves stores where a piece could be moved too
var BP1,BP2,BP3,BP4,BP5,BP6,BP7,BP8; // Pawns
var WP1,WP2,WP3,WP4,WP5,WP6,WP7,WP8; // Pawns
var BR1, BR2; // Rooks
var WR1, WR2; // Rooks
var BKN1, BKN2; // Knights
var WKN1, WKN2; // Knights
var BB1, BB2; // Bishops
var WB1, WB2; // Bishops
var BQ; // Queen
var WQ; // Queen
var BK; // King
var WK; // King
var theLeft, theRight, theBottom, theTop; // For Selector
var theLeftKill, theRightKill, theBottomKill, theTopKill; // Displaying the kill box for a piece
// Map of the board and the location of all the pieces
var map = [[['black','R',BR1],['black','Kn',BKN1],['black','B',BB1],['black','Q',BQ],['black','K',BK],['black','B',BB2],['black','Kn',BKN2],['black','R',BR2]],
[['black','P',BP1],['black','P',BP2],['black','P',BP3],['black','P',BP4],['black','P',BP5],['black','P',BP6],['black','P',BP7],['black','P',BP8]],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
[['white','P',WP1],['white','P',WP2],['white','P',WP3],['white','P',WP4],['white','P',WP5],['white','P',WP6],['white','P',WP7],['white','P',WP8]],
[['white','R',WR1],['white','Kn',BKN1],['white','B',WB1],['white','Q',WQ],['white','K',WK],['white','B',WB2],['white','Kn',WKN2],['white','R',WR2]]];
// CheckMap will display all the places the opposing pieces could take, if the king moved there
var checkMap = [['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','',''],
['','','','','','','','']];
// Map of variables used to display the possible move locations
var mapMoves = [[HL00,HL01,HL02,HL03,HL04,HL05,HL06,HL07],
[HL10,HL11,HL12,HL13,HL14,HL15,HL16,HL17],
[HL20,HL21,HL22,HL23,HL24,HL25,HL26,HL27],
[HL30,HL31,HL32,HL33,HL34,HL35,HL36,HL37],
[HL40,HL41,HL42,HL43,HL44,HL45,HL46,HL47],
[HL50,HL51,HL52,HL53,HL54,HL55,HL56,HL57],
[HL60,HL61,HL62,HL63,HL64,HL65,HL66,HL67],
[HL70,HL71,HL72,HL73,HL74,HL75,HL76,HL77]];
// Function for displaying the yellow box of a move on the board
function displayOnBoard(xCord,zCord)
{
colour = new THREE.MeshBasicMaterial( { color: 'yellow' } );
mapMoves[zCord][xCord] = new THREE.Mesh(nextMove, colour);
mapMoves[zCord][xCord].position.x = -175 + (50 * xCord);
mapMoves[zCord][xCord].position.y = 25.5;
mapMoves[zCord][xCord].position.z = -175 + (50 * zCord);
ABWorld.scene.add(mapMoves[zCord][xCord]);
}
// Function for displaying the red kill box around the opposite colour of a piece
function displayDeathOnBoard(xCord,zCord)
{
colour = new THREE.MeshBasicMaterial( { color: 'red' } );
mapMoves[zCord][xCord] = [];
theLeftKill = new THREE.Mesh(nextKillSide, colour);
theLeftKill.position.x = -195 + (50*xCord);
theLeftKill.position.y = 26.5;
theLeftKill.position.z = -175 + (50*zCord);
theRightKill = new THREE.Mesh(nextKillSide, colour);
theRightKill.position.x = -155 + (50*xCord);
theRightKill.position.y = 26.5;
theRightKill.position.z = -175 + (50*zCord);
theBottomKill = new THREE.Mesh(nextKillRoof, colour);
theBottomKill.position.x = -175 + (50*xCord);
theBottomKill.position.y = 26.5;
theBottomKill.position.z = -155 + (50*zCord);
theTopKill = new THREE.Mesh(nextKillRoof, colour);
theTopKill.position.x = -175 + (50*xCord);
theTopKill.position.y = 26.5;
theTopKill.position.z = -195 + (50*zCord);
mapMoves[zCord][xCord].push(theLeftKill,theRightKill,theBottomKill,theTopKill);
ABWorld.scene.add(theLeftKill);
ABWorld.scene.add(theRightKill);
ABWorld.scene.add(theBottomKill);
ABWorld.scene.add(theTopKill);
}
// Function for comparing the socket information with what is on this current board
function compareInput(first, second)
{
enPassantBoolean = false;
var tmp = map[first[1]][first[0]]; // Get the first location which is the original location of the piece
if (tmp[2].pieceType() == "king" && tmp[2].checkMove() === false)
{
if (map[second[1]][second[0]] === '')
{
castleCheck(tmp, second);
}
}
if (map[second[1]][second[0]] === '') // If the second location is empty then simply move the piece
{
if (tmp[2].pieceType() == "pawn")
{
if (enPassant.length > 0 && second[0] == enPassant[2][0] && second[1] == enPassant[2][1])
{
deathSound.play(); // Play death sound
map[enPassant[3][1]][enPassant[3][0]][2].deletePiece();
map[enPassant[3][1]][enPassant[3][0]] = '';
} else
{
enPassantCheck(tmp, [first[0], first[1]], second);
}
}
map[second[1]][second[0]] = tmp;
map[first[1]][first[0]] = '';
map[second[1]][second[0]][2].updatePosition(second[0],second[1]);
} else if (map[second[1]][second[0]] !== '') // If the second location is not empty then delete the piece there and move the piece
{
deathSound.play(); // Play death sound
if (map[second[1]][second[0]][2].pieceType() == "king")
{
chessGame.gameOver(map[first[1]][first[0]][0]);
}
map[second[1]][second[0]][2].deletePiece();
map[second[1]][second[0]] = tmp;
map[first[1]][first[0]] = '';
map[second[1]][second[0]][2].updatePosition(second[0],second[1]);
}
if (second[1] === 0 || second[1] == 7) // If it is the first or last row check
{
if (map[second[1]][second[0]][2].pieceType() == "pawn") // If the piece on the first or last row is a pawn then change that pawn into a queen
{
map[second[1]][second[0]][2].deletePiece();
map[second[1]][second[0]][2] = undefined;
map[second[1]][second[0]][2] = new Queen(second[0],second[1],map[second[1]][second[0]][0]); // Initialise the queen in the correct board location
map[second[1]][second[0]][2].displayPiece(); // Display the new queen
}
}
}
// Remove all the possible moves from the board, i.e. the yellow boxes and reb boxes
function removeFromBoard()
{
length = possibleMoves[1].length;
for (var i = 0; i < length; i++) // Loop through the possiblemoves list and remove them from the board
{
if (Array.isArray(mapMoves[possibleMoves[1][i][1]][possibleMoves[1][i][0]]))
{
var lengthMini = mapMoves[possibleMoves[1][i][1]][possibleMoves[1][i][0]].length;
for (var j = 0; j < lengthMini;j++)
{
ABWorld.scene.remove(mapMoves[possibleMoves[1][i][1]][possibleMoves[1][i][0]][j]);
}
mapMoves[possibleMoves[1][i][1]][possibleMoves[1][i][0]] = undefined;
} else {
ABWorld.scene.remove(mapMoves[possibleMoves[1][i][1]][possibleMoves[1][i][0]]);
}
}
}
// For 3D Graphics
// -----------------------------------------------------------------------------------------------------------------
// Set the gridsize
const gridsize = 8;
// Measurements for the board boxes
var boardCube = new THREE.BoxGeometry (50,50,50);
// Function for displaying the board
function displayBoard()
{
var evenOdd = 1;
for (var i = 0; i < gridsize; i += 1)
{
for (var j = 0; j < gridsize; j += 1)
{
if (evenOdd % 2 === 0) // Switch between the colours so the it has a grid pattern
{
colour = new THREE.MeshBasicMaterial( { map: walnutCube } );
}
else
{
colour = new THREE.MeshBasicMaterial( { map: beechCube } );
}
theCube = new THREE.Mesh(boardCube, colour);
theCube.position.x = -175 +(50 * j);
theCube.position.z = -175 +(50 * i);
ABWorld.scene.add(theCube); // DIsplay the cubes on the board
evenOdd += 1;
}
evenOdd += 1;
}
}
// Function for displaying pieces at the start of the game
function displayPieces()
{
for (var i = 0; i < gridsize; i += 1)
{
for (var j = 0; j < gridsize; j += 1) // Loop through the grid and when the pieces are reached initialise them
{
if (map[i][j] != ' ') // If there is a piece, work out which piece it is
{
if (map[i][j][1] == 'P') // If it is a P then the piece is a pawn
{
map[i][j][2] = new Pawn(j,i,map[i][j][0]); // Initialise the pawn
map[i][j][2].displayPiece(); // Display the piece
} else if (map[i][j][1] == 'R') // If it is a R then the piece is a rook
{
map[i][j][2] = new Rook(j,i,map[i][j][0]); // Initialise the rook
map[i][j][2].displayPiece(); // Display the piece
}
else if (map[i][j][1] == 'Kn') // If it is a Kn then the piece is a knight
{
map[i][j][2] = new Knight(j,i,map[i][j][0]); // Initialise the knight
map[i][j][2].displayPiece(); // Display the piece
}
else if (map[i][j][1] == 'B') // If it is a B then the piece is a bishop
{
map[i][j][2] = new Bishop(j,i,map[i][j][0]); // Initialise the bishop
map[i][j][2].displayPiece(); // Display the piece
}
else if (map[i][j][1] == 'Q') // If it is a Q then the piece is a queen
{
map[i][j][2] = new Queen(j,i,map[i][j][0]); // Initialise the queen
map[i][j][2].displayPiece(); // Display the piece
}
else if (map[i][j][1] == 'K') // If it is a K then the piece is a king
{
map[i][j][2] = new King(j,i,map[i][j][0]); // Initialise the king
map[i][j][2].displayPiece(); // Display the piece
}
}
}
}
}
// Handling Inputs
// -----------------------------------------------------------------------------------------------------------------
function keyHandler(event)
{
if (event.keyCode == 37) // If the left arrow is clicked then move the selector left
{
displaySelector.left();
}
else if (event.keyCode == 38) // If the up arrow is clicked then move the selector up
{
displaySelector.up();
}
else if (event.keyCode == 39) // If the right arrow is clicked then move the selector right
{
displaySelector.right();
}
else if (event.keyCode == 40) // If the down arrow is clicked then move the selector down
{
displaySelector.down();
}
else if (event.keyCode == 13) // If the Enter key is clicked then check what the user wants
{
length = possibleMoves[1].length;
for (var i = 0; i < length; i++) // Check to see if the user has clicked a piece before
{
if (possibleMoves[1][i][0] == displaySelector.location()[0] && possibleMoves[1][i][1] == displaySelector.location()[1]) // If the user has clicked enter over a possible move location then make the move happen
{
chessGame.switchTurn(); // Switch the turn of the game
updateOnAllBoards([possibleMoves[0][0][0],possibleMoves[0][0][1]], displaySelector.location()); // Send to the socket sender so all people on the game get the updated positions
movingPieceOnBoard(); // Move the piece on the board
removeFromBoard(); // Remove the possible moves from the board
possibleMoves = [[],[]]; // Reset the possible moves list
return; // Leave the functions
}
} // If the user didnt pick a possible move location then check what they clicked enter on
removeFromBoard(); // Remove the possible moves from the board
possibleMoves = [[],[]]; // Rest the possible moves list
if (map[displaySelector.location()[1]][displaySelector.location()[0]] !== '') // If they clicked enter over a non empty area then display the moves of that piece if it is their colour
{
if (user.displayColour() == map[displaySelector.location()[1]][displaySelector.location()[0]][0] && chessGame.displayTurn() == map[displaySelector.location()[1]][displaySelector.location()[0]][0])
{
map[displaySelector.location()[1]][displaySelector.location()[0]][2].displayMoves(); // Display the moves of the piece the user clicked
}
}
}
else if (event.keyCode == 32) // Click spawn for testing
{
console.log(map);
}
}
//
// Check for king check
// Marks all the postions a piece can take in a certain direction
function lineCheck(location, xCordDifference, zCordDifference)
{
tmpXCord = location[0];
tmpZCord = location[1];
for (var i = 0; i < 8; i++) // Loop through displaying the possible moves that the piece could take
{
tmpXCord += xCordDifference;
tmpZCord += zCordDifference;
if (tmpZCord == 8 || tmpZCord == -1 || tmpXCord == 8 || tmpXCord == -1) // Break the loop if the coordinate is out of the board
{
break;
}
if (map[tmpZCord][tmpXCord] === "") // If the space is blank add it to the array
{
checkMap[tmpZCord][tmpXCord] = "x";
} else if (map[tmpZCord][tmpXCord] !== "") // If the space has a piece add it to the array and break the for loop
{
checkMap[tmpZCord][tmpXCord] = "x";
break;
} else {
break;
}
}
}
// Marks if a postion can be moved too by a piece
function singleValueCheck(location, xCordDifference, zCordDifference)
{
tmpXCord = location[0] + xCordDifference;
tmpZCord = location[1] + zCordDifference;
if (tmpZCord > 7 || tmpZCord < 0 || tmpXCord > 7 || tmpXCord < 0) // leave the function if the coordinate is out of the board
{
return;
}
if (map[tmpZCord][tmpXCord] === "")
{
checkMap[tmpZCord][tmpXCord] = "x";
return;
} else if (map[tmpZCord][tmpXCord] !== "")
{
checkMap[tmpZCord][tmpXCord] = "x";
return;
}
}
// Resets the map of where a king can't move too once the go is over
function clearTheMap(checkMap)
{
for (var i = 0; i < 8; i++)
{
for (var j = 0; j < 8; j++)
{
checkMap[i][j] = "";
}
}
}
// Displays the warning once your king has been placed in check
function splashCheck()
{
if (chessGame.turn == "white")
{
return "<hr> <p> Warning <p> <hr> <p>White player has put you in check!<p> <button onclick='AB.removeSplash()'>Continue Game</button>";
} else
{
return "<hr> <p> Warning <p> <hr> <p>Black player has put you in check!<p> <button onclick='AB.removeSplash()'>Continue Game</button>";
}
}
// Will check to see if the king is currently in check
function kingCheckMateCheck()
{
clearTheMap(checkMap);
var colour = chessGame.turn;
var kingLocation;
for (var i = 0; i < 8; i++)
{
for (var j = 0; j < 8; j++)
{
if (map[i][j] !== '')
{
if (map[i][j][0] == colour)
{
map[i][j][2].checkKing();
} else if (map[i][j][2].pieceType() == "king") // Save the kings position
{
kingLocation = map[i][j][2].piecePosition;
}
}
}
}
if (checkMap[kingLocation[1]][kingLocation[0]]) // If the kings positon has a 'x' on it in checkMap then it is in check
{
AB.newSplash();
AB.splashHtml(splashCheck());
}
}
// Will update a king or rook so they have made their first move
function checkFirstTurn(piece)
{
if (piece.pieceType() == "king" || piece.pieceType() == "rook")
{
piece.pieceMoved();
}
return piece;
}
// Castle check to see if a player has moved to perform a castle manoeuvre
function castleCheck(tmp, list)
{
if (tmp[0] == "white") // Checks if king is white
{
if (map[7][0][1] == 'R') // Check the white rook is in the right position
{
if (map[7][0][2].checkMove() === false) // Check the white rook has not moved
{
if (list[0] == 2 && list[1] == 7) // If it has moved to the side of the king, perform the castle manoeuvre
{
var tmpRook = map[7][0];
map[7][3] = tmpRook;
map[7][0] = '';
map[7][3][2].updatePosition(3,7);
}
}
}
if (map[7][7][1] == 'R') // Check the white rook is in the right position
{
if (map[7][7][2].checkMove() === false) // Check the white rook has not moved
{
if (list[0] == 6 && list[1] == 7) // If it has moved to the side of the king, perform the castle manoeuvre
{
var tmpRook = map[7][7];
map[7][5] = tmpRook;
map[7][7] = '';
map[7][5][2].updatePosition(5,7);
}
}
}
} else if (tmp[0] == "black") // Checks if king is black
{
if (map[0][0][1] == 'R') // Check the black rook is in the right position
{
if (map[0][0][2].checkMove() === false) // Check the black rook has not moved
{
if (list[0] == 2 && list[1] === 0) // If it has moved to the side of the king, perform the castle manoeuvre
{
var tmpRook = map[0][0];
map[0][3] = tmpRook;
map[0][0] = '';
map[0][3][2].updatePosition(3,0);
}
}
}
if (map[0][7][1] == 'R') // Check the black rook is in the right position
{
if (map[0][7][2].checkMove() === false) // Check the black rook has not moved
{
if (list[0] == 6 && list[1] === 0) // If it has moved to the side of the king, perform the castle manoeuvre
{
var tmpRook = map[0][7];
map[0][5] = tmpRook;
map[0][7] = '';
map[0][5][2].updatePosition(5,0);
}
}
}
}
}
// The En Passant check function
var enPassantBoolean;
function enPassantCheck(piece, first, second)
{
if (piece[2].pieceColour == "white") // If a white pawn was moved
{
if (first[1] == 6) // From starting point and made a 2 jump move, it could be En Passanted
{
if (second[1] == 4)
{
// Save the location, in case a black pawn is nearby
enPassant = [true, [[second[0] + 1, second[1]], [second[0] - 1, second[1]]], [second[0], second[1] + 1], [second[0],second[1]]];
enPassantBoolean = true; // Set En Passant Boolean to true so the list is not reset
}
}
} else if (piece[2].pieceColour == "black") // If a black pawn was moved
{
if (first[1] == 1) // From starting point and made a 2 jump move, it could be En Passanted
{
if (second[1] == 3)
{
// Save the location, in case a white pawn is nearby
enPassant = [true, [[second[0] + 1, second[1]], [second[0] - 1, second[1]]], [second[0], second[1] - 1], [second[0],second[1]]];
enPassantBoolean = true;
}
}
}
}
// Function for moving a piece on the board locacally
function movingPieceOnBoard()
{
enPassantBoolean = false;
var tmp = map[possibleMoves[0][0][1]][possibleMoves[0][0][0]]; // Get the original location of the piece
if (tmp[2].pieceType() == "king" && tmp[2].checkMove() === false)
{
if (map[displaySelector.location()[1]][displaySelector.location()[0]] === '')
{
castleCheck(tmp, displaySelector.location());
}
}
if (map[displaySelector.location()[1]][displaySelector.location()[0]] === '') // If the location it is being moved to is empty then simply move the piece
{
tmp[2] = checkFirstTurn(tmp[2]);
if (tmp[2].pieceType() == "pawn")
{
if (enPassant.length > 0 && displaySelector.location()[0] == enPassant[2][0] && displaySelector.location()[1] == enPassant[2][1]) // If the displayselector was moved to the En Passant position then delete the pawn
{
deathSound.play(); // Play death sound
map[enPassant[3][1]][enPassant[3][0]][2].deletePiece();
map[enPassant[3][1]][enPassant[3][0]] = '';
} else
{
enPassantCheck(tmp, [possibleMoves[0][0][0], possibleMoves[0][0][1]], displaySelector.location());
}
}
map[displaySelector.location()[1]][displaySelector.location()[0]] = tmp;
map[possibleMoves[0][0][1]][possibleMoves[0][0][0]] = '';
map[displaySelector.location()[1]][displaySelector.location()[0]][2].updatePosition(displaySelector.location()[0],displaySelector.location()[1]);
} else if (map[displaySelector.location()[1]][displaySelector.location()[0]] !== '') // If the location it is being moved to is not empty then delete the piece then move it
{
deathSound.play(); // Play death sound
tmp[2] = checkFirstTurn(tmp[2]);
if (map[displaySelector.location()[1]][displaySelector.location()[0]][2].pieceType() == "king")
{
chessGame.gameOver(map[possibleMoves[0][0][1]][possibleMoves[0][0][0]][0]);
}
map[displaySelector.location()[1]][displaySelector.location()[0]][2].deletePiece();
map[displaySelector.location()[1]][displaySelector.location()[0]] = tmp;
map[possibleMoves[0][0][1]][possibleMoves[0][0][0]] = '';
map[displaySelector.location()[1]][displaySelector.location()[0]][2].updatePosition(displaySelector.location()[0],displaySelector.location()[1]);
}
if (displaySelector.location()[1] === 0 || displaySelector.location()[1] == 7) // If it is the first or last row check
{
if (map[displaySelector.location()[1]][displaySelector.location()[0]][2].pieceType() == "pawn") // If the piece on the first or last row is a pawn then change that pawn into a queen
{
map[displaySelector.location()[1]][displaySelector.location()[0]][2].deletePiece();
map[displaySelector.location()[1]][displaySelector.location()[0]][2] = undefined;
map[displaySelector.location()[1]][displaySelector.location()[0]][2] = new Queen(displaySelector.location()[0],displaySelector.location()[1],map[displaySelector.location()[1]][displaySelector.location()[0]][0]); // Initialise the queen in the correct board location
map[displaySelector.location()[1]][displaySelector.location()[0]][2].displayPiece(); // Display the new queen
}
}
if (enPassantBoolean === false) // Reset En Passant if no pawn made a 2 move
{
enPassant = [];
}
}
// Have a light for showing the pieces
const LIGHTCOLOR = 0xffffff ;
// Commands in the side of the screen for users using the game
function commands()
{
if (chessGame.displayTurn() == "white") // Picking white team
{
AB.msg ( ` <hr> <p> Chess game. Pick a side. Click buttons to pick colour. <p>
<button onclick='user.setBlack()' class=ab-largenormbutton > Black </button>
<button onclick='user.setWhite()' class=ab-largenormbutton > White </button> <p>
<h1>White Turn</h1>
</hr>`);
}
else if (chessGame.displayTurn() == "black") // Picking black team
{
AB.msg ( ` <hr> <p> Chess game. Pick a side. Click buttons to pick colour. <p>
<button onclick='user.setBlack()' class=ab-largenormbutton > Black </button>
<button onclick='user.setWhite()' class=ab-largenormbutton > White </button> <p>
<h1>Black Turn</h1>
</hr>`);
}
}
var chessGame = new Game(); // initialise the game
AB.world.newRun = function()
{
ABWorld.init3d ( startRadius, maxRadius, skycolor );
loadResources(); // Load the models in
displayBoard(); // Display the board
displaySelector.displayPiece(); // Display the selector piece
ABWorld.scene.background = new THREE.CubeTextureLoader().load ( skyboxArray, function()
{
ABWorld.render();
AB.removeLoading();
});
var thelight = new THREE.DirectionalLight ( LIGHTCOLOR, 1 ); // Set up the light
thelight.position.set ( startRadius, startRadius, startRadius ); // Set a location for it
ABWorld.scene.add(thelight); // Add it ot the world
var newthelight = new THREE.DirectionalLight ( LIGHTCOLOR, 1 ); // Set up the light
newthelight.position.set ( -500, 500, -500 ); // Set a location for it
ABWorld.scene.add(newthelight); // Add it ot the world
commands(); // Add it to the world
};
var turn = 0;
AB.world.nextStep = function()
{
document.onkeydown = keyHandler; // Key handler for inputs
if (chessGame.winner == true && turn == 0)
{
setTimeout(function ()
{
AB.world.endRun();
}, 200);
turn = 1;
}
};
AB.world.endRun = function()
{
AB.newSplash();
AB.splashHtml(splashEnd());
};
// Game over screen, with reset to start new game
function splashEnd()
{
if (chessGame.colourWinner == "white")
{
return "<hr> <p> Game is complete <p> <hr> <p>White player won the game<p> <button onclick='window.location.reload(true)'>New Game</button>";
} else
{
return "<hr> <p> Game is complete <p> <hr> <p>Black player won the game<p> <button onclick='window.location.reload(true)'>New Game</button>";
}
}
// Game is full screen
function splashFull()
{
return "<hr> Game is full please try again later <hr>";
}
// Start Socket
AB.socketStart();
function updateOnAllBoards(first, second) // First co-ordinate is where the piece was, second co-ordinate is where the piece was moved too.
{
if ( AB.socket )
{
if (AB.socket.connected)
{
data = { first : first,
second : second
};
AB.socketOut (data); // Sends the data to the other clients.
}
}
commands();
}
var safe = false;
// Checks the amount of users on the world, if more then 2 then you can not play
AB.socketUserlist = function(userList)
{
console.log(userList);
console.log(AB.runReady);
if (userList.length > 2 && safe === false) // If more then 2 then you don't get to play
{
AB.newSplash();
console.log("To many players");
AB.splashHtml(splashFull());
} else { // If not more then 2 then set safe to true so you won't be removed
safe = true;
}
};
AB.socketIn = function(data) // When data is received pass it to a function to compare the differences.
{
console.log(data);
compareInput(data.first, data.second); // Make the changes on this local map with the new positions.
kingCheckMateCheck(); // Once a move has been received, check to see if it puts a king in check.
chessGame.switchTurn(); // Switch the turn. i.e. (from black to white or from white to black).
commands();
};