diff --git a/README.md b/README.md index d4236cc..da2810c 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,13 @@
3)Animate the game movements (For e.g., smoother bullets)
-4)Create a single-player mode where the opponent is a bot. -
5)Add spells (For eg: spell which makes a piece passthrough for a move)
+4)Create a single-player mode where the opponent is a bot. +
+ +##List of Bugs Found in Bot So Far +1) say the bot is rotating one of its ricos/semiricos it'll rotate, no issues.... but but but if the same piece is moved by the bot in the next move, it'll rotate again to its initial position. The Dom structure is such that if a rico is rotated it parent node (ie .square) is rotated and not the svg element or the rico div. Upon moving the rico, that new parent will have style.transform = rotate(0deg) and old parent will have style.transform = rotate(90deg). +Note: other pieces going to the old parent will have 90 deg rotation whichh is absurdd. +2) if a semiRico is broken it is not visually reflected immediately (its being updated in the next move only) though the master array is updated simulatneously. +3) rico/semirico turning is not considered as a move => even after they rotate, one more move is getting executed => 2 bullets are being shot!!!!! \ No newline at end of file diff --git a/hacker-mode.css b/hacker-mode.css index 913ea2d..103c793 100644 --- a/hacker-mode.css +++ b/hacker-mode.css @@ -24,8 +24,8 @@ body { justify-content: center; flex-direction: column; align-items: center; - min-height: 100vh; - min-width: 700px; + height: 100vh; + width: 700px; width: 33.3333%; } @@ -68,7 +68,10 @@ h1 { margin: 10px; backdrop-filter: blur(10px); } - +#swap{ + justify-content: center; + margin-top: 5px; +} #control-center-child { display: flex; justify-content: space-between; @@ -402,10 +405,20 @@ button:disabled { align-items: center; width: 100%; height: 100vh; + overflow-x: hidden; + background: url(assets/background3.jpg); + background-size: cover; + } + + #left-div { + height: 0; + width: 0; } h1 { text-align: center; + font-size: 30px; + margin-top: 70px; } #gameboard { @@ -457,11 +470,45 @@ button:disabled { width: 10px; } -} + #game-state-history { + height: 225px; + width: 70%; + font-size: 11px; + + + } + + #right-div { + width: 100%; + height: 100%; + } -@media screen and (max-width: 420px) { #control-center { - /* width: 300px; */ + scale: .85; + } + + #center-div { + height: 700px; + width: 100%; + } + + #winner-notice { scale: .7; } -} \ No newline at end of file + + #directionalBullet { + height: 23px; + width: 23px; + } + #control-panel-parent{ + width: 100%; + display: flex; + justify-content: center; + align-items: center; + + } + #timertext{ + font-size: .7em; + } + +} diff --git a/hacker-mode.html b/hacker-mode.html index de50f85..2c18581 100644 --- a/hacker-mode.html +++ b/hacker-mode.html @@ -17,7 +17,7 @@

Ricochet Rumble hacker

-
+
@@ -29,6 +29,7 @@

Ricochet Rumble hacker

It's green's turn

+
00:21
diff --git a/hackerplus.css b/hackerplus.css index dc4e4b4..9dc62c0 100644 --- a/hackerplus.css +++ b/hackerplus.css @@ -12,7 +12,7 @@ body { justify-content: center; flex-direction: row; align-items: center; - min-height: 100vh; + height: 100vh; width: 100%; background: url(assets/background4.jpg); background-size: cover; @@ -24,8 +24,8 @@ body { justify-content: center; flex-direction: column; align-items: center; - min-height: 100vh; - min-width: 700px; + height: 100vh; + width: 700px; width: 33.3333%; } @@ -403,10 +403,21 @@ button:disabled { align-items: center; width: 100%; height: 100vh; + overflow-x: hidden; + background: url(assets/background3.jpg); + background-size: cover; + } + + #left-div { + height: 0; + width: 0; } h1 { text-align: center; + font-size: 27px; + margin-top: 70px; + color: aqua; } #gameboard { @@ -458,11 +469,44 @@ button:disabled { width: 10px; } -} + #game-state-history { + height: 225px; + width: 70%; + font-size: 11px; + + + } + + #right-div { + width: 100%; + height: 100%; + } -@media screen and (max-width: 420px) { #control-center { - /* width: 300px; */ + scale: .8; + } + + #center-div { + height: 700px; + width: 100%; + } + + #winner-notice { scale: .7; } -} \ No newline at end of file + + #directionalBullet { + height: 23px; + width: 23px; + } + #control-panel-parent{ + width: 100%; + display: flex; + justify-content: center; + align-items: center; + + } + #timertext{ + font-size: .7em; + } +} diff --git a/hackerplus.html b/hackerplus.html index 656a5a4..d87eaaf 100644 --- a/hackerplus.html +++ b/hackerplus.html @@ -17,7 +17,7 @@

Ricochet Rumble hacker++

-
+
diff --git a/hackerplus.js b/hackerplus.js index 52efbb2..8c5c0e6 100644 --- a/hackerplus.js +++ b/hackerplus.js @@ -152,7 +152,7 @@ function resetGame() { } function gameWin(element, currentLocation) { - saveGameState() + saveGameState(); currentLocation.removeChild(bulletDiv); // console.log("game over"); @@ -177,7 +177,7 @@ function playAgain() { localStorage.removeItem("gameStateHistory"); } function handlePlayerLossByTime(player) { - saveGameState() + saveGameState(); gameOver = true; isBulletMoving = false; @@ -201,6 +201,7 @@ function changePlayer() { if (currentPlayer === "green") { currentPlayer = "blue"; playerDisplay.innerText = "blue's"; + botMove(); } else { currentPlayer = "green"; playerDisplay.innerText = "green's"; @@ -319,11 +320,13 @@ function replayGame() { }).then(() => { setTimeout(() => { handleCannonShoot(currentPlayer === "green" ? "blue" : "green"); - },100); + }, 100); }); index++; } else { - showWinnerNotice(history); + setTimeout(()=>{ + showWinnerNotice(history); + },2000) } } @@ -344,6 +347,120 @@ function logMove(description) { movesBoardChild.textContent = description; gameHistoryBoard.append(movesBoardChild); } +//here im assuming that the blue player is bot +function botMove() { + if (gameOver || gamePaused || currentPlayer !== "blue") { + return; + } + const validMoves = getAllValidMovesForBot("blue"); + if (validMoves.length === 0) { + handlePlayerLossByTime("blue"); + return; + } + const randomIndex = Math.floor(Math.random() * validMoves.length); + const randomMove = validMoves[randomIndex]; + executeBotMove(randomMove); +} + +function getAllValidMovesForBot(player) { + const validMoves = []; + const parser = new DOMParser(); + + for (let i = 0; i < width * width; i++) { + const piece = startPieces[i]; + const row = Math.floor(i / width); + const column = i % width; + + // Parse the piece string into a DOM element + const doc = parser.parseFromString(piece, "text/html"); + const pieceDOM = doc.querySelector("div"); + // console.log(pieceDOM.parentNode); + if (pieceDOM && pieceDOM.getAttribute("class").includes(player)) { + const moves = getValidMovesForPieceForBot(row, column, pieceDOM); + validMoves.push(...moves); + // The below is for ricochets + if (pieceDOM.id === "semiRicochet" || pieceDOM.id === "ricochet") { + validMoves.push({ piece, row, column, type: "rotate" }); + } + } + } + return validMoves; +} + +function getValidMovesForPieceForBot(row, column, piece) { + const moves = []; + const directions = []; + + if (piece.id === "topCannon" || piece.id === "bottomCanon") { + directions.push({ row: 0, column: -1 }); + directions.push({ row: 0, column: 1 }); + } else { + directions.push( + { row: -1, column: 0 }, // Up + { row: 1, column: 0 }, // Down + { row: 0, column: -1 }, // Left + { row: 0, column: 1 }, // Right + { row: -1, column: -1 }, // Up-Left + { row: -1, column: 1 }, // Up-Right + { row: 1, column: -1 }, // Down-Left + { row: 1, column: 1 } // Down-Right + ); + } + + directions.forEach((direction) => { + const newRow = row + direction.row; + const newColumn = column + direction.column; + + // Check if the new position is valid + if ( + isValidPosition(newRow, newColumn) && + startPieces[newRow * width + newColumn] === "" + ) { + moves.push({ + piece, + oldRow: row, + oldColumn: column, + row: newRow, + column: newColumn, + type: "move", + }); + } + }); + return moves; +} +function executeBotMove(move) { + console.log("move", move); + if (move.type === "move") { + movePiece(move.oldRow, move.oldColumn, move.row, move.column); + } else if (move.type === "rotate") { + rotatePieceForBot(move.row, move.column); + } + updateBoard(); +} +function rotatePieceForBot(row, column) { + const pieceIndex = row * width + column; + const pieceHTML = startPieces[pieceIndex]; + + // Parse the piece HTML into a DOM element + const parser = new DOMParser(); + const doc = parser.parseFromString(pieceHTML, "text/html"); + const pieceDOM = doc.querySelector("div"); + + if (pieceDOM.id === "semiRicochet" || pieceDOM.id === "ricochet") { + const currentRotation = ricochetRotation[pieceIndex] || 0; + const newRotation = (currentRotation + 90) % 360; + ricochetRotation[pieceIndex] = newRotation; + + // Apply rotation to the actual DOM element in the game board + const actualPieceDOM = document.querySelector(`#${pieceDOM.id}`); + if (actualPieceDOM) { + actualPieceDOM.style.transform = `rotate(${newRotation}deg)`; + } + } + handleCannonShoot(currentPlayer); + updateBoard(); + changePlayer(); +} resetButton.addEventListener("click", resetGame); pauseButton.addEventListener("click", pauseGame); diff --git a/normal-mode.css b/normal-mode.css index 287255a..be501e9 100644 --- a/normal-mode.css +++ b/normal-mode.css @@ -316,6 +316,7 @@ button:disabled { h1 { text-align: center; + font-size: 25px; } #gameboard { @@ -367,11 +368,23 @@ button:disabled { width: 10px; } -} + #control-panel-parent { + width: 100%; + display: flex; + justify-content: center; + align-items: center; -@media screen and (max-width: 420px) { - #control-center { - /* width: 300px; */ + } + + #timertext { + font-size: .7em; + } + + #winner-notice { scale: .7; } + + #control-center { + scale: .8; + } } \ No newline at end of file diff --git a/normal-mode.html b/normal-mode.html index 6ca257e..f180627 100644 --- a/normal-mode.html +++ b/normal-mode.html @@ -16,7 +16,7 @@

Ricochet Rumble normal

-
+