about summary refs log tree commit diff stats
path: root/js/puzzle-dungeon/game.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/puzzle-dungeon/game.js')
-rw-r--r--js/puzzle-dungeon/game.js267
1 files changed, 159 insertions, 108 deletions
diff --git a/js/puzzle-dungeon/game.js b/js/puzzle-dungeon/game.js
index f742844..4ca91d3 100644
--- a/js/puzzle-dungeon/game.js
+++ b/js/puzzle-dungeon/game.js
@@ -1,131 +1,182 @@
-const canvas = document.getElementById('gameCanvas');
-const ctx = canvas.getContext('2d');
-const cellSize = canvas.width / 10;
-const stepDuration = 200; // Duration for each step
+// game.js
+export let grid = createGrid(10, 10);  // Example grid size
+export let player = {
+    position: { x: 0, y: 0 },
+    inventory: [],
+    health: 10,
+    endurance: 10,
+    score: 0,
+    steps: 0,
+    flashing: false
+};
+let targetPosition = { x: 0, y: 0 };
 
-let player = { x: 0, y: 0 };
-
-function drawGrid() {
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
-    for (let x = 0; x <= canvas.width; x += cellSize) {
-        ctx.moveTo(x, 0);
-        ctx.lineTo(x, canvas.height);
-    }
-    for (let y = 0; y <= canvas.height; y += cellSize) {
-        ctx.moveTo(0, y);
-        ctx.lineTo(canvas.width, y);
+function createGrid(rows, cols) {
+    let grid = [];
+    for (let i = 0; i < rows; i++) {
+        let row = [];
+        for (let j = 0; j < cols; j++) {
+            row.push(null);
+        }
+        grid.push(row);
     }
-    ctx.strokeStyle = '#ddd';
-    ctx.stroke();
+    return grid;
 }
 
-function drawPlayer() {
-    ctx.fillStyle = 'blue';
-    ctx.fillRect(player.x * cellSize, player.y * cellSize, cellSize, cellSize);
+function generateCollectables(grid, numCollectables) {
+    const collectableTypes = ['potion', 'shield', 'food'];
+    const collectableColors = {
+        'potion': 'purple',
+        'shield': 'gold',
+        'food': 'red'
+    };
+    for (let i = 0; i < numCollectables; i++) {
+        let x, y;
+        do {
+            x = Math.floor(Math.random() * grid.length);
+            y = Math.floor(Math.random() * grid[0].length);
+        } while (x === 0 && y === 0);  // Ensure no items at (0,0)
+        const type = collectableTypes[Math.floor(Math.random() * collectableTypes.length)];
+        grid[x][y] = { type, color: collectableColors[type] };
+    }
 }
 
-document.getElementById('commandForm').addEventListener('submit', function (e) {
-    e.preventDefault();
-    const commands = document.getElementById('commands').value.trim();
-    try {
-        const parsedCommands = parseLispCommands(commands);
-        console.log("Parsed Commands:", JSON.stringify(parsedCommands, null, 2)); // Debugging output
-        executeCommands(parsedCommands);
-    } catch (error) {
-        console.error("Error parsing commands:", error);
+function generateDamagingSpaces(grid, numSpaces) {
+    for (let i = 0; i < numSpaces; i++) {
+        let x, y;
+        do {
+            x = Math.floor(Math.random() * grid.length);
+            y = Math.floor(Math.random() * grid[0].length);
+        } while (x === 0 && y === 0);  // Ensure no damaging spaces at (0,0)
+        grid[x][y] = { type: 'damage', color: 'pink' };
     }
-});
+}
 
-function parseLispCommands(commands) {
-    const parse = input => {
-        const tokens = tokenize(input);
-        const ast = buildAST(tokens);
-        return ast;
-    };
+function generateTargetBlock(grid) {
+    let x, y;
+    do {
+        x = Math.floor(Math.random() * grid.length);
+        y = Math.floor(Math.random() * grid[0].length);
+    } while (x === 0 && y === 0);  // Ensure no target block at (0,0)
+    grid[x][y] = { type: 'target', color: 'green' };  // Target block represented by 'X'
+    targetPosition = { x, y };  // Store the target block position
+}
 
-    const tokenize = input => {
-        return input.replace(/\(/g, ' ( ').replace(/\)/g, ' ) ').trim().split(/\s+/);
-    };
+export function drawGrid(grid) {
+    const canvas = document.getElementById('gameCanvas');
+    const ctx = canvas.getContext('2d');
+    const cellSize = Math.min(canvas.width / grid.length, canvas.height / grid[0].length);
+
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
 
-    const buildAST = tokens => {
-        if (!tokens.length) throw new SyntaxError("Unexpected end of input");
+    grid.forEach((row, x) => {
+        row.forEach((cell, y) => {
+            ctx.strokeStyle = 'black';
+            ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
 
-        const token = tokens.shift();
-        if (token === '(') {
-            const list = [];
-            while (tokens[0] !== ')') {
-                list.push(buildAST(tokens));
-                if (!tokens.length) throw new SyntaxError("Missing closing parenthesis");
+            if (cell && cell.color) {
+                ctx.fillStyle = cell.color;
+                ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
+                ctx.fillStyle = 'black';
+                ctx.font = `${cellSize / 2}px Arial`;
+                ctx.textAlign = 'center';
+                ctx.textBaseline = 'middle';
+                let char = '';
+                if (cell.type === 'potion') char = 'p';
+                if (cell.type === 'shield') char = 's';
+                if (cell.type === 'food') char = 'f';
+                if (cell.type === 'damage') char = '!';
+                if (cell.type === 'target') char = 'X';
+                ctx.fillText(char, x * cellSize + cellSize / 2, y * cellSize + cellSize / 2);
             }
-            tokens.shift();
-            return list;
-        } else if (token === ')') {
-            throw new SyntaxError("Unexpected ')'");
-        } else {
-            return isNaN(token) ? token : Number(token);
-        }
-    };
+        });
+    });
 
-    return parse(commands);
+    // Draw player
+    ctx.fillStyle = player.flashing ? 'white' : 'blue';
+    ctx.fillRect(player.position.x * cellSize, player.position.y * cellSize, cellSize, cellSize);
+    ctx.fillStyle = 'black';
+    ctx.font = `${cellSize / 2}px Arial`;
+    ctx.textAlign = 'center';
+    ctx.textBaseline = 'middle';
+    ctx.fillText('@', player.position.x * cellSize + cellSize / 2, player.position.y * cellSize + cellSize / 2);
 }
 
-function executeCommands(commands) {
-    if (commands[0] !== 'move') {
-        console.error("Invalid command: root command must be 'move'");
-        return;
-    }
+export function initializeGame() {
+    grid = createGrid(10, 10);  // Reset grid
+    generateCollectables(grid, 10);  // Adjust the number as needed
+    generateDamagingSpaces(grid, Math.floor(Math.random() * 7) + 1);  // Random number of damaging spaces, no more than 7
+    generateTargetBlock(grid);  // Add target block
+    player.position = { x: 0, y: 0 };  // Reset player position
+    player.inventory = [];  // Clear inventory
+    player.health = 10;  // Reset health
+    player.endurance = 10;  // Reset endurance
+    player.steps = 0;  // Reset steps
+    resizeCanvas();
+    drawGrid(grid);
+    updatePlayerStatus();
+}
 
-    let delay = 0;
-    commands.slice(1).forEach(moveCommand => {
-        const steps = moveCommand[1];
-        for (let i = 0; i < steps; i++) {
-            setTimeout(() => {
-                movePlayer([moveCommand[0], 1]);
-                drawGrid();
-                drawPlayer();
-            }, delay);
-            delay += stepDuration;
-        }
-        if (moveCommand[0] === 'rest') {
-            setTimeout(() => {
-                drawGrid();
-                drawPlayer();
-            }, delay);
-            delay += stepDuration;
-        }
-    });
+export function resizeCanvas() {
+    const canvas = document.getElementById('gameCanvas');
+    const width = Math.min(window.innerWidth, window.innerHeight) * 0.9;
+    canvas.width = width;
+    canvas.height = width;
+    drawGrid(grid);
 }
 
-function movePlayer(moveCommand) {
-    const direction = moveCommand[0];
-    const steps = moveCommand[1];
+export function updatePlayerPosition(newX, newY) {
+    player.position.x = newX;
+    player.position.y = newY;
+    checkForDamageOrTarget();
+    drawGrid(grid);
+    updatePlayerStatus();
+}
 
-    if (typeof direction !== 'string' || typeof steps !== 'number') {
-        console.error(`Invalid move command: ${JSON.stringify(moveCommand)}`);
-        return;
-    }
+export function updatePlayerStatus() {
+    document.getElementById('playerPosition').textContent = `Position: (${player.position.x}, ${player.position.y})`;
+    document.getElementById('playerHealth').textContent = `Health: ${player.health}`;
+    document.getElementById('playerEndurance').textContent = `Endurance: ${player.endurance}`;
+    document.getElementById('playerInventory').textContent = `Inventory: [${player.inventory.join(', ')}]`;
+    document.getElementById('playerScore').textContent = `Score: ${player.score}`;
+}
 
-    switch (direction) {
-        case 'north':
-            player.y = Math.max(0, player.y - steps);
-            break;
-        case 'south':
-            player.y = Math.min(9, player.y + steps);
-            break;
-        case 'east':
-            player.x = Math.min(9, player.x + steps);
-            break;
-        case 'west':
-            player.x = Math.max(0, player.x - steps);
-            break;
-        case 'rest':
-            // No movement, just wait for the duration
-            break;
-        default:
-            console.error(`Unknown direction: ${direction}`);
-            return;
+function checkForDamageOrTarget() {
+    const { x, y } = player.position;
+    const cell = grid[x][y];
+    if (cell && cell.type === 'damage') {
+        const shieldIndex = player.inventory.indexOf('shield');
+        if (shieldIndex > -1) {
+            player.inventory.splice(shieldIndex, 1);  // Use one shield
+            console.log('Used shield to avoid damage');
+        } else {
+            player.health -= 2;
+            console.log(`Stepped on damaging space, health is now ${player.health}`);
+            if (player.health <= 0) {
+                alertGameOver();
+                return;
+            }
+            flashPlayer();
+        }
+    } else if (x === targetPosition.x && y === targetPosition.y) {
+        player.score += 1;
+        console.log(`Reached target block, score is now ${player.score}`);
+        initializeGame();  // Generate new level and reset player position
     }
 }
 
-drawGrid();
-drawPlayer();
+export function alertGameOver() {
+    alert('You have lost the game!');
+    initializeGame();
+}
+
+function flashPlayer(callback) {
+    player.flashing = true;
+    drawGrid(grid);
+    setTimeout(() => {
+        player.flashing = false;
+        drawGrid(grid);
+        updatePlayerStatus();
+        if (callback) callback();
+    }, 250); // Flash duration
+}