There must be a logical path through the maze to get the main character successfully from the starting point to the finish point. The water pot should change color with each move made by the main character so that we know if it will be a win or a lose when contact is made at the center point.
Browse files
script.js
CHANGED
|
@@ -35,30 +35,36 @@ let health = MAX_HEALTH;
|
|
| 35 |
updateUI();
|
| 36 |
addEventListeners();
|
| 37 |
}
|
| 38 |
-
|
| 39 |
-
// Generate maze with walls and paths
|
| 40 |
function generateMaze() {
|
| 41 |
mazeGrid.innerHTML = '';
|
| 42 |
maze = Array(CELL_COUNT).fill().map((_, i) => {
|
| 43 |
const cell = document.createElement('div');
|
| 44 |
cell.className = 'cell';
|
| 45 |
cell.dataset.index = i;
|
| 46 |
-
|
| 47 |
-
// Create maze walls with more structure
|
| 48 |
-
let isWall = false;
|
| 49 |
const row = Math.floor(i / GRID_SIZE);
|
| 50 |
const col = i % GRID_SIZE;
|
|
|
|
| 51 |
// Solid outer perimeter walls
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
}
|
|
|
|
| 59 |
// Ensure start, water and goal positions are accessible
|
| 60 |
if (i === playerPosition || i === waterPosition || i === goalPosition) {
|
| 61 |
-
isWall = false;
|
| 62 |
}
|
| 63 |
if (isWall) {
|
| 64 |
cell.classList.add('wall');
|
|
@@ -121,17 +127,26 @@ if (isWall) {
|
|
| 121 |
}
|
| 122 |
}
|
| 123 |
}
|
| 124 |
-
// Place water at center
|
| 125 |
function placeWater() {
|
| 126 |
const cell = maze[waterPosition].element;
|
| 127 |
cell.classList.add('water');
|
| 128 |
cell.innerHTML = '💧';
|
|
|
|
| 129 |
|
| 130 |
// Mark goal position
|
| 131 |
const goalCell = maze[goalPosition].element;
|
| 132 |
goalCell.classList.add('goal');
|
| 133 |
goalCell.innerHTML = '🏁';
|
| 134 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
// Update UI elements
|
| 136 |
function updateUI() {
|
| 137 |
scoreValue.textContent = score;
|
|
@@ -213,7 +228,6 @@ if (isWall) {
|
|
| 213 |
endGame(true);
|
| 214 |
return;
|
| 215 |
}
|
| 216 |
-
|
| 217 |
// Move player
|
| 218 |
playerPosition = newPosition;
|
| 219 |
newCell.classList.add('player');
|
|
@@ -222,9 +236,12 @@ endGame(true);
|
|
| 222 |
// Move enemies
|
| 223 |
moveEnemies();
|
| 224 |
|
|
|
|
|
|
|
|
|
|
| 225 |
// Update UI
|
| 226 |
updateUI();
|
| 227 |
-
|
| 228 |
}
|
| 229 |
|
| 230 |
// Move enemies towards player
|
|
|
|
| 35 |
updateUI();
|
| 36 |
addEventListeners();
|
| 37 |
}
|
| 38 |
+
// Generate maze with walls and paths ensuring a path exists
|
|
|
|
| 39 |
function generateMaze() {
|
| 40 |
mazeGrid.innerHTML = '';
|
| 41 |
maze = Array(CELL_COUNT).fill().map((_, i) => {
|
| 42 |
const cell = document.createElement('div');
|
| 43 |
cell.className = 'cell';
|
| 44 |
cell.dataset.index = i;
|
| 45 |
+
|
|
|
|
|
|
|
| 46 |
const row = Math.floor(i / GRID_SIZE);
|
| 47 |
const col = i % GRID_SIZE;
|
| 48 |
+
|
| 49 |
// Solid outer perimeter walls
|
| 50 |
+
let isWall = (row === 0 || row === GRID_SIZE-1 || col === 0 || col === GRID_SIZE-1);
|
| 51 |
+
|
| 52 |
+
// Create a guaranteed path from start to goal
|
| 53 |
+
if (!isWall) {
|
| 54 |
+
// Create a diagonal path from start to goal
|
| 55 |
+
const isOnPath =
|
| 56 |
+
(row === Math.floor(col * (GRID_SIZE-4)/(GRID_SIZE-4)) + 2) ||
|
| 57 |
+
(col === Math.floor(row * (GRID_SIZE-4)/(GRID_SIZE-4)) + 2);
|
| 58 |
+
|
| 59 |
+
// Add some randomness to the path
|
| 60 |
+
if (!isOnPath) {
|
| 61 |
+
isWall = Math.random() < 0.3;
|
| 62 |
+
}
|
| 63 |
}
|
| 64 |
+
|
| 65 |
// Ensure start, water and goal positions are accessible
|
| 66 |
if (i === playerPosition || i === waterPosition || i === goalPosition) {
|
| 67 |
+
isWall = false;
|
| 68 |
}
|
| 69 |
if (isWall) {
|
| 70 |
cell.classList.add('wall');
|
|
|
|
| 127 |
}
|
| 128 |
}
|
| 129 |
}
|
| 130 |
+
// Place water at center with random outcome
|
| 131 |
function placeWater() {
|
| 132 |
const cell = maze[waterPosition].element;
|
| 133 |
cell.classList.add('water');
|
| 134 |
cell.innerHTML = '💧';
|
| 135 |
+
updateWaterColor();
|
| 136 |
|
| 137 |
// Mark goal position
|
| 138 |
const goalCell = maze[goalPosition].element;
|
| 139 |
goalCell.classList.add('goal');
|
| 140 |
goalCell.innerHTML = '🏁';
|
| 141 |
}
|
| 142 |
+
|
| 143 |
+
// Update water color based on random outcome
|
| 144 |
+
function updateWaterColor() {
|
| 145 |
+
const waterCell = maze[waterPosition].element;
|
| 146 |
+
const willWin = Math.random() > 0.5;
|
| 147 |
+
waterCell.style.backgroundColor = willWin ? '#bbf7d0' : '#fecaca';
|
| 148 |
+
waterCell.style.border = willWin ? '1px solid #4ade80' : '1px solid #ef4444';
|
| 149 |
+
}
|
| 150 |
// Update UI elements
|
| 151 |
function updateUI() {
|
| 152 |
scoreValue.textContent = score;
|
|
|
|
| 228 |
endGame(true);
|
| 229 |
return;
|
| 230 |
}
|
|
|
|
| 231 |
// Move player
|
| 232 |
playerPosition = newPosition;
|
| 233 |
newCell.classList.add('player');
|
|
|
|
| 236 |
// Move enemies
|
| 237 |
moveEnemies();
|
| 238 |
|
| 239 |
+
// Update water color with each move
|
| 240 |
+
updateWaterColor();
|
| 241 |
+
|
| 242 |
// Update UI
|
| 243 |
updateUI();
|
| 244 |
+
}
|
| 245 |
}
|
| 246 |
|
| 247 |
// Move enemies towards player
|
style.css
CHANGED
|
@@ -71,9 +71,16 @@ body {
|
|
| 71 |
}
|
| 72 |
.water {
|
| 73 |
background-color: #e0f2fe;
|
| 74 |
-
|
|
|
|
| 75 |
z-index: 4;
|
| 76 |
font-size: 0.5rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
}
|
| 78 |
@keyframes ripple {
|
| 79 |
0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); }
|
|
|
|
| 71 |
}
|
| 72 |
.water {
|
| 73 |
background-color: #e0f2fe;
|
| 74 |
+
border: 1px solid #38bdf8;
|
| 75 |
+
animation: ripple 3s infinite, colorChange 2s infinite alternate;
|
| 76 |
z-index: 4;
|
| 77 |
font-size: 0.5rem;
|
| 78 |
+
transition: background-color 0.3s ease, border-color 0.3s ease;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
@keyframes colorChange {
|
| 82 |
+
0% { opacity: 0.8; }
|
| 83 |
+
100% { opacity: 1; }
|
| 84 |
}
|
| 85 |
@keyframes ripple {
|
| 86 |
0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); }
|