You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

311 lines
8.9 KiB

class GameLogic{
constructor(pieceList = [], missedOportunities = [], currentPlayer = "white") {
this.pieceList = pieceList;
this.missedOportunities = missedOportunities;
this.currentPlayer = currentPlayer;
}
isMissedOportunity(pieceRecord) {
const id = pieceRecord.id;
return this.missedOportunities.includes(id);
}
generateDefaultPositions(){
var id = 0;
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 3; j++) {
if((i+j) % 2 == 0){
const pieceRecord = {id:id, x:i, y:j, player:"white", type:"basic"};
this.pieceList.push(pieceRecord);
id++;
}
}
}
for (let i = 0; i < 8; i++) {
for (let j = 5; j < 8; j++) {
if((i+j) % 2 == 0){
const pieceRecord = {id:id, x:i, y:j, player:"black", type:"basic"};
this.pieceList.push(pieceRecord);
id++;
}
}
}
}
getPieceRecord(x,y){
if (x > 7 || x < 0 || y > 7 || y < 0) {
return false;
}
return this.pieceList.find(pieceRecord => pieceRecord.x == x && pieceRecord.y == y);
}
nukePieceRecord(pieceRecord) {
const index = this.pieceList.findIndex(record => record.id == pieceRecord.id);
this.pieceList.splice(index, 1);
}
updatePieceRecord(pieceRecord) {
const index = this.pieceList.findIndex(record => record.id == pieceRecord.id);
this.pieceList[index] = pieceRecord;
}
updatePieceRecordPosition(pieceRecord, x, y) {
pieceRecord.x = x;
pieceRecord.y = y;
this.updatePieceRecord(pieceRecord);
return pieceRecord;
}
getCasualties(oldX, oldY, newX, newY) {
const directionX = (newX > oldX) ? 1 : -1;
const directionY = (newY > oldY) ? 1 : -1;
const casualties = new Array();
for (let i = 1; i < (Math.abs(newY - oldY) + 1); i++) {
const x = oldX + (i*directionX);
const y = oldY + (i*directionY);
pieceRecord = this.getPieceRecord(x,y);
if (pieceRecord) {
casualties.push(pieceRecord);
}
}
return casualties;
}
getLoser() {
if (!this.pieceList.find(pieceRecord => pieceRecord.player == "white")) {
return "white";
}
if (!this.pieceList.find(pieceRecord => pieceRecord.player == "black")) {
return "black";
}
return null;
}
continuableInDirectionForQueen(directionX, directionY, pieceRecord) {
const pieceX = pieceRecord.x;
const pieceY = pieceRecord.y;
const player = pieceRecord.player;
for (let i = 1; i < 8; i++) {
const x = pieceX + (i*directionX);
const y = pieceY + (i*directionY);
if(x > 7 || x < 0 || y > 7 || y < 0 || (x+directionX) > 7 || (x+directionX) < 0 || (y+directionY) > 7 || (y+directionY) < 0 ){
return false;
}
const record = this.getPieceRecord(x, y);
if (record) {
if (record.player == player) {
return false;
}
const firstBlockRecord = this.getPieceRecord(x+directionX,y+directionY);
const secondBlockRecord = this.getPieceRecord(x-directionX,y-directionY);
return ((!firstBlockRecord || firstBlockRecord.id == pieceRecord.id) && (!secondBlockRecord || secondBlockRecord.id == pieceRecord.id));
}
}
return false;
}
continuable(pieceRecord){
const x = pieceRecord.x;
const y = pieceRecord.y;
const player = pieceRecord.player;
const type = pieceRecord.type;
if(player == "white" && ((this.getPieceRecord(x+1, y+1) && this.getPieceRecord(x+1, y+1).player != player && !this.getPieceRecord(x+2, y+2) && (y+2) < 8 && (x+2) < 8) || ((this.getPieceRecord(x-1, y+1) && this.getPieceRecord(x-1, y+1).player != player && !this.getPieceRecord(x-2, y+2) && (y+2) < 8 && (x-2) > 0)))){
return true;
}
if( player == "black" && ((this.getPieceRecord(x+1, y-1) && this.getPieceRecord(x+1, y-1).player != player && !this.getPieceRecord(x+2, y-2) && (y-2) > 0 && (x+2) < 8) || ((this.getPieceRecord(x-1, y-1) && this.getPieceRecord(x-1, y-1).player != player && !this.getPieceRecord(x-2, y-2) && (y-2) > 0 && (x-2) > 0)))){
return true;
}
if(type == "queen"){
return (this.continuableInDirectionForQueen(1,1,pieceRecord) || this.continuableInDirectionForQueen(-1,-1,pieceRecord) || this.continuableInDirectionForQueen(-1,1,pieceRecord) || this.continuableInDirectionForQueen(1,-1,pieceRecord));
}
return false;
}
getOportunities(pieceRecord){
const player = pieceRecord.player;
const opportunities = new Array();
this.pieceList.forEach(record => {
if (record.player == player && record != pieceRecord && this.continuable(record)) {
opportunities.push(record.id);
}
});
return opportunities;
}
getOportunitiesIncludingSelf(pieceRecord){
const player = pieceRecord.player;
const opportunities = new Array();
this.pieceList.forEach(record => {
if (record.player == player && this.continuable(record)) {
opportunities.push(record.id);
}
});
return opportunities;
}
isMoveValid(pieceRecord, x, y){
if(0 > y > 7 || 0 > x > 7){
return false;
}
if (this.getPieceRecord(x,y)) {
return false;
}
const currentX = pieceRecord.x;
const currentY = pieceRecord.y;
if (Math.abs(y - currentY) != Math.abs(x - currentX)) {
return false;
}
const player = pieceRecord.player;
const type = pieceRecord.type;
//Check correct Y direction if piece is basic
if (currentY > y && player == "white" && type == "basic") {
return false;
}
const directionY = (y > currentY) ? 1 : -1;
const directionX = (x > currentX) ? 1 : -1;
space = 0;
piecesInWay = 0;
for (let i = 1; i < (Math.abs(y-currentY)+1); i++) {
const nowX = currentX + (i*directionX);
const nowY = currentY + (i*directionY);
if (inWayPieceRecord = this.getPieceRecord(nowX, nowY)) {
if(inWayPieceRecord.player == player){
return false;
}
space = 0;
piecesInWay++;
}else{
space++;
piecesInWay = 0;
}
if(piecesInWay > 1){
return false;
}
if (space > 1 && type == "basic") {
return false;
}
}
return true;
}
swapPlayers() {
this.currentPlayer = (this.currentPlayer == "white") ? "black" : "white";
}
makeMove(pieceRecord, x, y){
const player = pieceRecord.player;
if (!isMoveValid(pieceRecord, x, y)) {
return 0;
}
const oldX = pieceRecord.x;
const oldY = pieceRecord.y;
const casualties = this.getCasualties(oldX, oldY, x, y);
casualties.forEach(casualty => {
this.nukePieceRecord(casualty);
});
this.missedOportunities = new Array();
oportunities = this.getOportunitiesIncludingSelf(pieceRecord);
if(casualties.length == 0 && oportunities.length != 0) {
this.missedOportunities = oportunities;
}
const original_type = pieceRecord.type;
if ((player == "white" && y == 7) || (player == "black" && y == 0) && pieceRecord.type == "basic") {
pieceRecord.type = "queen";
}
const updatedPieceRecord = updatePieceRecordPosition(pieceRecord, x, y);
if (this.continuable(updatedPieceRecord) && casualties.length > 0 && pieceRecord.type == original_type) {
return 2;
}
return 1;
}
nukePieceRecordThatMissedOportunity(pieceRecord) {
if (this.missedOportunities.includes(pieceRecord.id)) {
this.missedOportunities = new Array();
this.nukePieceRecord(pieceRecord);
return true;
}
return false;
}
}
module.exports = GameLogic;