diff --git a/web-app/js/projects/snake.js b/web-app/js/projects/snake.js
index 672623b..d268ea6 100644
--- a/web-app/js/projects/snake.js
+++ b/web-app/js/projects/snake.js
@@ -1,8 +1,19 @@
-function getsnakeGameHTML() {
+function getSnakeGameHTML() {
return `
🐍 Classic Snake Game
+
+
+
+
+
+
+
@@ -19,6 +30,10 @@ function getsnakeGameHTML() {
Score
0
+
@@ -40,6 +55,31 @@ function getsnakeGameHTML() {
padding: 20px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
+ .controls-top {
+ margin-bottom: 15px;
+ margin-right: 140px; /* Aligns with canvas center offset */
+ }
+ .difficulty-box select {
+ padding: 6px 10px;
+ border-radius: 6px;
+ border: 1px solid var(--accent-border, #ccc);
+ background-color: #ffffff !important; /* Explicitly forces white background */
+ color: #222222 !important; /* Explicitly forces dark gray/black text */
+ font-size: 14px;
+ font-family: inherit;
+ font-weight: 500;
+ cursor: pointer;
+ outline: none;
+ }
+ .difficulty-box select {
+ padding: 4px 8px;
+ border-radius: 4px;
+ border: 1px solid #aaa;
+ background-color: #ffffff;
+ color: #222222;
+ font-weight: normal;
+ cursor: pointer;
+ }
.game-area {
display: flex;
align-items: flex-start;
@@ -52,16 +92,16 @@ function getsnakeGameHTML() {
}
#canvas-wrapper {
position: relative;
- border: 4px solid var(--success-color);
+ border: 4px solid var(--success-color, #2ecc71);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 15px 35px rgba(0,0,0,0.3);
}
#snakeCanvas {
- background-color: var(--panel-color);
+ background-color: var(--panel-color, #222);
background-image:
- linear-gradient(var(--border-color) 1px, transparent 1px),
- linear-gradient(90deg, var(--border-color) 1px, transparent 1px);
+ linear-gradient(var(--border-color, rgba(255,255,255,0.05)) 1px, transparent 1px),
+ linear-gradient(90deg, var(--border-color, rgba(255,255,255,0.05)) 1px, transparent 1px);
background-size: 20px 20px;
display: block;
}
@@ -71,14 +111,18 @@ function getsnakeGameHTML() {
gap: 15px;
}
.score-card {
- background: var(--accent-soft);
- border: 1px solid var(--accent-border);
- color: var(--text-color);
+ background: var(--accent-soft, #fafafa);
+ border: 1px solid var(--accent-border, #ddd);
+ color: var(--text-color, #333);
padding: 10px 25px;
border-radius: 10px;
text-align: center;
min-width: 120px;
- box-shadow: var(--shadow);
+ box-shadow: var(--shadow, 0 4px 6px rgba(0,0,0,0.1));
+ }
+ .high-score-card {
+ border-color: #f1c40f;
+ background: rgba(241, 196, 15, 0.05);
}
.score-card span {
font-size: 12px;
@@ -92,15 +136,15 @@ function getsnakeGameHTML() {
.button-group {
display: flex;
justify-content: center;
- gap: 30px; /* Space between buttons fixed */
+ gap: 30px;
margin-top: 10px;
- margin-right: 140px; /* Offset to align with canvas center */
+ margin-right: 140px;
}
.instruction-box {
margin-top: 20px;
margin-right: 140px;
text-align: center;
- color: var(--text-secondary);
+ color: var(--text-secondary, #666);
font-size: 15px;
}
#game-over-overlay {
@@ -109,31 +153,40 @@ function getsnakeGameHTML() {
left: 0;
width: 100%;
height: 100%;
- background: var(--overlay-color);
+ background: var(--overlay-color, rgba(0, 0, 0, 0.75));
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
- color: var(--success-color);
+ color: var(--success-color, #2ecc71);
}
#game-over-overlay h1 { font-size: 3rem; margin-bottom: 10px; }
.hidden { display: none !important; }
.btn-primary {
padding: 12px 25px;
+ cursor: pointer;
}
`;
}
-// --- GAME LOGIC ---
+// --- GAME LOGIC STATE ---
let direction = { x: 0, y: 0 };
-let speed = 7;
+let speed = 9; // System baseline operational configuration state
+let scoreMultiplier = 2; // Baseline multiplier scalar state
let score = 0;
let lastPaintTime = 0;
let snakeArr = [{ x: 13, y: 10 }];
let food = { x: 6, y: 7 };
+// Profile configuration mapping matrices
+const CONFIG_DIFFICULTY = {
+ easy: { speed: 5, multiplier: 1 },
+ medium: { speed: 9, multiplier: 2 },
+ hard: { speed: 14, multiplier: 3 }
+};
+
function main(ctime) {
window.requestAnimationFrame(main);
if ((ctime - lastPaintTime) / 1000 < 1 / speed) {
@@ -154,11 +207,44 @@ function isCollide(snake) {
return false;
}
+function applyDifficultySettings() {
+ const selector = document.getElementById('difficultySelect');
+ if (selector) {
+ const value = selector.value;
+ speed = CONFIG_DIFFICULTY[value].speed;
+ scoreMultiplier = CONFIG_DIFFICULTY[value].multiplier;
+ }
+}
+
+function updateBestScoreUI() {
+ const bestScore = localStorage.getItem('snakeBestScore') || 0;
+ const bestScoreElement = document.getElementById('best-score');
+ if (bestScoreElement) {
+ bestScoreElement.innerHTML = bestScore;
+ }
+}
+
+function checkAndSaveHighScore() {
+ const currentBest = parseInt(localStorage.getItem('snakeBestScore') || '0', 10);
+ if (score > currentBest) {
+ localStorage.setItem('snakeBestScore', score);
+ updateBestScoreUI();
+ }
+}
+
function gameEngine() {
if (isCollide(snakeArr)) {
direction = { x: 0, y: 0 };
document.getElementById('final-score').innerHTML = score;
document.getElementById('game-over-overlay').classList.remove('hidden');
+
+ // Execute persistent local evaluations
+ checkAndSaveHighScore();
+
+ // Restore controls visibility states
+ const selector = document.getElementById('difficultySelect');
+ if (selector) selector.disabled = false;
+
snakeArr = [{ x: 13, y: 10 }];
score = 0;
document.getElementById('score').innerHTML = score;
@@ -167,7 +253,7 @@ function gameEngine() {
// Eating food
if (snakeArr[0].y === food.y && snakeArr[0].x === food.x) {
- score += 1;
+ score += (1 * scoreMultiplier); // Scaled multiplier calculations
document.getElementById('score').innerHTML = score;
snakeArr.unshift({ x: snakeArr[0].x + direction.x, y: snakeArr[0].y + direction.y });
let a = 2, b = 16;
@@ -199,11 +285,25 @@ function gameEngine() {
ctx.fillRect(food.x * 20, food.y * 20, 18, 18);
}
-// IMPORTANT: Function to initialize listeners after HTML is loaded
+// Initialize execution listeners
function initSnakeGame() {
window.requestAnimationFrame(main);
+
+ // Set initial historic rendering metrics
+ updateBestScoreUI();
+
+ // Map difficulty listener parameters
+ const selector = document.getElementById('difficultySelect');
+ if (selector) {
+ selector.addEventListener('change', applyDifficultySettings);
+ }
+ // Initialize standard values configuration parameters
+ applyDifficultySettings();
document.getElementById('startGameBtn').addEventListener('click', () => {
+ applyDifficultySettings();
+ // Prevent changing parameter matrices on an active engine run
+ if (selector) selector.disabled = true;
direction = { x: 1, y: 0 }; // Start moving right
});
@@ -213,6 +313,7 @@ function initSnakeGame() {
document.getElementById('overlayRestartBtn').addEventListener('click', () => {
document.getElementById('game-over-overlay').classList.add('hidden');
+ if (selector) selector.disabled = false;
direction = { x: 0, y: 0 };
snakeArr = [{ x: 13, y: 10 }];
score = 0;
@@ -220,6 +321,13 @@ function initSnakeGame() {
});
window.addEventListener('keydown', e => {
+ // Change difficulty selection dynamic evaluations if arrow key registers
+ if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
+ if (selector && !selector.disabled) {
+ selector.disabled = true;
+ }
+ }
+
switch (e.key) {
case "ArrowUp": if (direction.y !== 1) { direction.x = 0; direction.y = -1; } break;
case "ArrowDown": if (direction.y !== -1) { direction.x = 0; direction.y = 1; } break;
@@ -228,3 +336,7 @@ function initSnakeGame() {
}
});
}
+
+// Global scope assignments
+window.getSnakeGameHTML = getSnakeGameHTML;
+window.initSnakeGame = initSnakeGame;
\ No newline at end of file