-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
13 lines (13 loc) · 15.2 KB
/
index.js
File metadata and controls
13 lines (13 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
class ChessPiece{x;y;img;color;possibleMoves(grid){return[]}constructor(y,x,color){this.x=x;this.y=y;this.color=color}markPossibleMoves(grid){let moves=this.moves(grid);for(let move of moves){let cell=grid[move[1]][move[0]];cell.markRed()}}cleanMarkedCells(grid){let moves=this.moves(grid);for(let move of moves){let cell=grid[move[1]][move[0]];cell.cleanColor()}}isInGridBounds(move){let isValid=false;if(move[1]>=0&&move[1]<8&&move[0]>=0&&move[0]<8){isValid=true}return isValid}changeCords(y,x){this.y=y;this.x=x}checkValidMove(move){let isValid=false;if(this.isInGridBounds(move)){if(!grid[move[1]][move[0]].piece||grid[move[1]][move[0]].piece&&grid[move[1]][move[0]].piece.color!=this.color){isValid=true}}return isValid}moves(grid){let moves=this.possibleMoves(grid);moves=moves.filter(move=>this.checkValidMove(move)&&!this.isKingOnPos(grid,move));return moves}possibleDiagonalMovement(grid){let moves=[];let i=this.y+1;let j=this.x+1;let isKingFound=false;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i++;j++}isKingFound=false;i=this.y-1;j=this.x+1;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i--;j++}isKingFound=false;i=this.y+1;j=this.x-1;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i++;j--}isKingFound=false;i=this.y-1;j=this.x-1;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i--;j--}isKingFound=false;return moves}diagonalMovement(grid){const moves=[];let i=this.y+1;let j=this.x+1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i++;j++}i=this.y+1;j=this.x-1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i++;j--}i=this.y-1;j=this.x+1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i--;j++}i=this.y-1;j=this.x-1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i--;j--}return moves}possibleAxisMovement(grid){const moves=[];let i=this.y-1;let j=this.x;let isKingFound=false;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i--}i=this.y+1;j=this.x;isKingFound=false;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}i++}i=this.y;j=this.x-1;isKingFound=false;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}j--}i=this.y;j=this.x+1;isKingFound=false;while(this.isInGridBounds([j,i])){if(isKingFound&&grid[i][j].piece){break}else if(this.isKingOnPos(grid,[j,i])){isKingFound=true;moves.push([j,i])}else if(grid[i][j].piece){moves.push([j,i]);break}else{moves.push([j,i])}j++}return moves}axisMovement(grid){const moves=[];let i=this.y-1;let j=this.x;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i--}i=this.y+1;j=this.x;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}i++}i=this.y;j=this.x-1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}j--}i=this.y;j=this.x+1;while(this.isInGridBounds([j,i])&&this.checkValidMove([j,i])&&!this.isKingOnPos(grid,[j,i])){moves.push([j,i]);if(grid[i][j].piece&&grid[i][j].piece.color!=this.color){break}j++}return moves}isKingOnPos(grid,pos){let isValid=false;if(grid[pos[1]][pos[0]].piece&&grid[pos[1]][pos[0]].piece instanceof King){isValid=true}return isValid}}class Bishop extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-bishop.png" alt="king" class="figure"></img>`}possibleMoves(grid){const moves=[];moves.push(...this.possibleDiagonalMovement(grid));return moves}moves(){const moves=[];moves.push(...this.diagonalMovement(grid));return moves}}class King extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-king.png" alt="king" class="figure"></img>`}possibleMoves(grid){return[[this.x-1,this.y],[this.x+1,this.y],[this.x+1,this.y+1],[this.x-1,this.y-1],[this.x,this.y+1],[this.x,this.y-1],[this.x+1,this.y-1],[this.x-1,this.y+1]]}computeCheckMate(enemyPieces){let kingPositions=[[this.x,this.y]];for(let i=this.y-1;i<=this.y+1;i++){for(let j=this.x-1;j<=this.x+1;j++){if(this.checkValidMove([j,i])){kingPositions.push([j,i])}}}console.log(kingPositions);for(let enemy of enemyPieces){const moves=enemy.possibleMoves(grid);for(let move of moves){if(move[0]>=this.x-1&&move[0]<=this.x+1&&move[1]>=this.y-1&&move[1]<=this.y+1){kingPositions=kingPositions.filter(pos=>pos[0]!=move[0]||pos[1]!=move[1])}}}console.log(kingPositions);return kingPositions.length===0}}class Knight extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-knight.png" alt="king" class="figure"></img>`}possibleMoves(grid){const moves=[[this.x+1,this.y-2],[this.x-1,this.y-2],[this.x+1,this.y+2],[this.x-1,this.y+2],[this.x+2,this.y+1],[this.x+2,this.y-1],[this.x-2,this.y+1],[this.x-2,this.y-1]];return moves}}class Pawn extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-pawn.png" alt="pedone" class="figure"></img>`}possibleMoves(grid){let moves=[];if(this.isInGridBounds([this.x,this.y-1])){if(!grid[this.y-1][this.x].piece){moves.push([this.x,this.y-1])}}if(this.isInGridBounds([this.x+1,this.y-1])){if(grid[this.y-1][this.x+1].piece&&grid[this.y-1][this.x+1].piece.color!=this.color){moves.push([this.x+1,this.y-1])}}if(this.isInGridBounds([this.x-1,this.y-1])){if(grid[this.y-1][this.x-1].piece&&grid[this.y-1][this.x-1].piece.color!=this.color){moves.push([this.x-1,this.y-1])}}return moves}}class Queen extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-queen.png" alt="king" class="figure"></img>`}possibleMoves(grid){const moves=[];moves.push(...this.possibleDiagonalMovement(grid));moves.push(...this.possibleAxisMovement(grid));return moves}moves(){const moves=[];moves.push(...this.diagonalMovement(grid));moves.push(...this.axisMovement(grid));return moves}}class Rook extends ChessPiece{constructor(y,x,color){super(y,x,color);this.img=`<img src="./images/${color}-rook.png" alt="king" class="figure"></img>`}possibleMoves(grid){const moves=[];moves.push(...this.possibleAxisMovement(grid));return moves}moves(grid){const moves=[];moves.push(...this.axisMovement(grid));return moves}}function createGrid(){let isLastWhite=false;let brown="#643528";let cellColor;for(let i=0;i<8;i++){const row=[];for(let j=0;j<8;j++){cellColor=isLastWhite?"white":brown;const cell=new GridCell(j,i,null,cellColor);row.push(cell);isLastWhite=!isLastWhite}grid.push(row);isLastWhite=!isLastWhite}}function loadDOMGrid(){gridEl.innerHTML="";for(let y=0;y<grid.length;y++){const row=document.createElement("tr");for(let x=0;x<grid[y].length;x++){const cell=document.createElement("td");cell.x=x;cell.y=y;cell.addEventListener("click",handleCellClick);grid[y][x].htmlNode=cell;cell.style.backgroundColor=grid[y][x].color;row.append(cell)}gridEl.append(row)}}function resetGrid(){isLevelWon=false;isLevelLost=false;lastSelectedCell=null;selectedCell=null;grid=[];gridEl.innerHTML="";blackKing=null;alleyPieces=[];createGrid();loadDOMGrid()}class GridCell{htmlNode;color;x;y;piece;constructor(x,y,htmlNode,color){this.x=x;this.y=y;this.htmlNode=htmlNode;this.color=color}changePiece(piece){if(!piece){this.htmlNode.innerHTML="";this.piece=null}else{this.htmlNode.innerHTML=piece.img;this.piece=piece}}highlight(){const highlightColor="yellow";this.htmlNode.style.backgroundColor=highlightColor}deHighlight(){this.htmlNode.style.backgroundColor=this.color}markRed(){this.htmlNode.style.backgroundColor="#ffda00"}cleanColor(){this.htmlNode.style.backgroundColor=this.color}clearCell(grid){if(this.piece){this.piece.cleanMarkedCells(grid)}this.deHighlight()}}let grid=[];const gridEl=document.querySelector(".chess-grid");const remainingMovesEl=document.querySelector(".remaining-moves");const levelEl=document.querySelector(".level");let level=1;let isLevelWon=false;let isLevelLost=false;let remainingMoves=0;let lastSelectedCell=null;let selectedCell=null;let blackKing;let alleyPieces=[];createGrid();loadDOMGrid();console.log(grid);let levels=[level1,level2,level3,level4,level5,level6,level7];levels[level-1]();function putPieces(...pieces){for(let piece of pieces){grid[piece.y][piece.x].changePiece(piece);if(piece.color==="white"){alleyPieces.push(piece)}}}function setMovesNumber(movesNumber){remainingMoves=movesNumber;remainingMovesEl.innerHTML="Remaining Moves: "+movesNumber}function level1(){setMovesNumber(3);blackKing=new King(0,0,"black");putPieces(blackKing,new Pawn(1,0,"black"),new Pawn(1,1,"black"),new Pawn(1,2,"black"));putPieces(new Queen(4,5,"white"),new Knight(6,3,"white"))}function level2(){setMovesNumber(1);blackKing=new King(0,7,"black");putPieces(blackKing,new Pawn(1,7,"black"),new Pawn(1,6,"black"),new Pawn(1,5,"black"));putPieces(new Queen(4,5,"white"),new Knight(6,3,"white"))}function level3(){setMovesNumber(2);blackKing=new King(0,7,"black");putPieces(blackKing,new Pawn(1,7,"black"),new Pawn(1,6,"black"),new Pawn(1,5,"black"));putPieces(new Rook(4,5,"white"),new Knight(6,3,"white"))}function level4(){setMovesNumber(3);blackKing=new King(2,7,"black");putPieces(blackKing,new Pawn(3,7,"black"),new Pawn(3,6,"black"),new Pawn(3,5,"black"),new Pawn(2,3,"black"),new Pawn(3,2,"black"),new Pawn(3,5,"black"));putPieces(new Rook(4,5,"white"),new Rook(6,1,"white"))}function level5(){setMovesNumber(2);blackKing=new King(0,0,"black");putPieces(blackKing,new Pawn(1,1,"black"),new Pawn(1,0,"black"),new Rook(0,1,"black"));putPieces(new Rook(4,5,"white"),new Knight(6,3,"white"))}function level6(){setMovesNumber(2);blackKing=new King(0,1,"black");putPieces(blackKing,new Pawn(4,2,"black"),new Pawn(3,6,"black"),new Pawn(3,5,"black"),new Pawn(2,3,"black"),new Pawn(3,2,"black"),new Pawn(3,5,"black"));putPieces(new Bishop(5,5,"white"),new Rook(6,1,"white"),new Rook(4,4,"white"))}function level7(){setMovesNumber(3);blackKing=new King(2,4,"black");putPieces(blackKing,new Pawn(1,4,"black"),new Pawn(4,2,"black"),new Pawn(1,3,"black"),new Pawn(3,5,"black"),new Pawn(2,3,"black"),new Pawn(3,2,"black"),new Pawn(2,5,"black"));putPieces(new Bishop(5,5,"white"),new Bishop(7,2,"white"))}function consumeMove(){remainingMoves--;remainingMovesEl.innerHTML="Remaining Moves: "+remainingMoves;if(remainingMoves<0){console.log("You lost");isLevelLost=true;isLevelWon=false;showDefeatDialog()}}function handleCellClick(event){lastSelectedCell=selectedCell;selectedCell=grid[event.target.y][event.target.x];console.log(event.target.y,event.target.x);if(lastSelectedCell===selectedCell){if(selectedCell.piece){selectedCell.piece.cleanMarkedCells(grid)}selectedCell.deHighlight();selectedCell=null;lastSelectedCell=null;return}if(lastSelectedCell){lastSelectedCell.clearCell(grid)}selectedCell.highlight();if(lastSelectedCell&&lastSelectedCell.piece){let isValidMove=lastSelectedCell.piece.moves(grid).find(move=>{return move[0]===selectedCell.x&&move[1]===selectedCell.y});if(isValidMove){consumeMove();lastSelectedCell.clearCell(grid);selectedCell.changePiece(lastSelectedCell.piece);lastSelectedCell.changePiece(null);selectedCell.piece.changeCords(selectedCell.y,selectedCell.x);selectedCell=null;lastSelectedCell=null}else{if(selectedCell&&selectedCell.piece){if(selectedCell.piece.color==="black"){selectedCell.clearCell(grid);selectedCell=null}else{selectedCell.piece.markPossibleMoves(grid)}}}}else{if(selectedCell&&selectedCell.piece){if(selectedCell.piece.color=="black"){selectedCell.clearCell(grid);selectedCell=null}else{selectedCell.piece.markPossibleMoves(grid)}}}isLevelWon=blackKing.computeCheckMate(alleyPieces);if(isLevelWon){console.log("Level Won"+isLevelWon);showLevelWonDialog()}else if(remainingMoves<=0){console.log("Level Lost "+isLevelLost);showDefeatDialog()}}function showLevelWonDialog(){const backdrop=document.createElement("div");backdrop.classList.add("backdrop");const dialog=document.createElement("div");dialog.classList.add("dialog");dialog.innerHTML=`
<h2 class="finish-result">Victory...For Now!</h2>
<p class="finish-description">You won but there are other levels to face</p>
<button class="finish-button" onclick="goToNextLevel()">Next Level<button>
`;const body=document.querySelector("body");body.appendChild(dialog);body.appendChild(backdrop)}function showDefeatDialog(){const backdrop=document.createElement("div");backdrop.classList.add("backdrop");const dialog=document.createElement("div");dialog.classList.add("dialog");dialog.innerHTML=`
<h2 class="finish-result">Loser!</h2>
<p class="finish-description">It seems you are not as smart as I thought</p>
<button class="finish-button" onclick="resetLevel()">Try Again<button>
`;const body=document.querySelector("body");body.appendChild(dialog);body.appendChild(backdrop)}function showGameWonDialog(){const backdrop=document.createElement("div");backdrop.classList.add("backdrop");const dialog=document.createElement("div");dialog.classList.add("dialog");dialog.innerHTML=`
<h2 class="finish-result">You are a real chess master!</h2>
<p class="finish-description">You successfully finished all levels...but many other will come in the future</p>
<button class="finish-button" onclick="resetGame()">Restart Game<button>
`;const body=document.querySelector("body");body.appendChild(dialog);body.appendChild(backdrop)}function resetGame(){isLevelWon=false;isLevelLost=false;removeDialog();levelEl.innerText="Level 1";level=1;resetGrid();level1()}function resetLevel(){isLevelWon=false;isLevelLost=false;removeDialog();resetGrid();levels[level-1]()}function goToNextLevel(){removeDialog();resetGrid();level++;if(level>levels.length){showGameWonDialog()}else{levels[level-1]();levelEl.innerText="Level "+level}}function removeDialog(){const body=document.querySelector("body");body.querySelector(".dialog").remove();body.querySelector(".backdrop").remove()}