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;