<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Maze Navigator</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Dynamic Maze Navigator</h1>
    <div id="maze-container">
        <!-- Maze will be generated here by JavaScript -->
    </div>
    <p id="message">Use arrow keys to move. Find the goal (Yellow)!</p>

    <script src="script.js"></script>
</body>
</html>
body {
    font-family: sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    background-color: #f0f0f0;
}

#maze-container {
    display: grid; /* We'll set columns/rows with JS */
    border: 3px solid #333;
    background-color: #fff; /* Floor color */
    margin-top: 20px;
    position: relative; /* For potential absolute positioning inside */
}

.cell {
    width: 40px; /* Size of each cell */
    height: 40px;
    box-sizing: border-box; /* Include border in size */
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.5em;
    transition: background-color 0.3s ease; /* Smooth transitions for dynamic walls */
}

/* Cell Types */
.floor {
    background-color: #fff;
}

.wall {
    background-color: #555; /* Static Wall */
    border: 1px solid #444;
}

.dynamic-wall {
    background-color: #888; /* Closed Dynamic Wall */
    border: 1px solid #777;
}

.dynamic-wall.open {
    background-color: #e0e0e0; /* Open Dynamic Wall - slightly different from floor */
    border: 1px dashed #ccc; /* Visual cue that it can close */
}

.player {
    background-color: blue;
    border-radius: 50%;
    width: 80%; /* Make player slightly smaller than cell */
    height: 80%;
    z-index: 10; /* Ensure player is visible */
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}

.goal {
    background-color: gold;
    border: 1px solid orange;
}

.pressure-plate {
    background-color: lightcoral; /* Inactive */
    border-radius: 20%;
    width: 70%;
    height: 70%;
    border: 2px outset pink;
}

.pressure-plate.active {
    background-color: darkred; /* Active */
    border: 2px inset red;
}

#message {
    margin-top: 15px;
    font-weight: bold;
    color: #333;
}
document.addEventListener('DOMContentLoaded', () => {
    const mazeContainer = document.getElementById('maze-container');
    const messageElement = document.getElementById('message');

    // --- Maze Definition ---
    // 0: Floor
    // 1: Wall (Static)
    // 2: Player Start
    // 3: Goal
    // 4: Pressure Plate (Inactive)
    // 5: Pressure Plate (Active) - Will be set dynamically
    // 6: Dynamic Wall (Closed)
    // 7: Dynamic Wall (Open) - Represents the state, rendered differently

    let mazeData = [
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [1, 2, 0, 0, 1, 6, 0, 0, 0, 1],
        [1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
        [1, 0, 1, 0, 0, 0, 0, 1, 0, 1],
        [1, 0, 0, 0, 1, 1, 0, 1, 3, 1],
        [1, 1, 1, 4, 1, 6, 0, 1, 1, 1], // Plate at row 5, col 3
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ];

    // --- Dynamic Element Links ---
    // Map pressure plate coordinates (r,c) to the dynamic walls they control (array of {r, c})
    const plateLinks = {
        '5,3': [ { r: 1, c: 5 }, { r: 5, c: 5 } ] // Plate at 5,3 controls walls at 1,5 and 5,5
        // Add more links here for other plates
    };

    // --- Game State ---
    let playerPos = { r: 0, c: 0 };
    let gameActive = true;
    const numRows = mazeData.length;
    const numCols = mazeData[0].length;

    // --- Initialization ---
    function initGame() {
        // Find player start position
        for (let r = 0; r < numRows; r++) {
            for (let c = 0; c < numCols; c++) {
                if (mazeData[r][c] === 2) {
                    playerPos = { r, c };
                    mazeData[r][c] = 0; // Change start position to floor after finding
                    break;
                }
            }
        }
        renderMaze();
        document.addEventListener('keydown', handleKeyPress);
        messageElement.textContent = "Use arrow keys to move. Find the goal (Yellow)!";
    }

    // --- Rendering ---
    function renderMaze() {
        mazeContainer.innerHTML = ''; // Clear previous state
        mazeContainer.style.gridTemplateColumns = `repeat(${numCols}, 40px)`;
        mazeContainer.style.gridTemplateRows = `repeat(${numRows}, 40px)`;

        for (let r = 0; r < numRows; r++) {
            for (let c = 0; c < numCols; c++) {
                const cell = document.createElement('div');
                cell.classList.add('cell');
                cell.dataset.r = r; // Store coordinates for potential interaction later
                cell.dataset.c = c;

                let cellType = mazeData[r][c];
                let isPlayerOnCell = (playerPos.r === r && playerPos.c === c);
                let cellContent = null; // Div for player, plate etc.

                // Determine base cell class (wall, floor, dynamic states)
                switch (cellType) {
                    case 1: cell.classList.add('wall'); break;
                    case 3: cell.classList.add('goal'); break;
                    case 4: // Inactive Plate
                        cell.classList.add('floor'); // Plate sits on floor
                        cellContent = document.createElement('div');
                        cellContent.classList.add('pressure-plate');
                        break;
                    case 5: // Active Plate
                        cell.classList.add('floor');
                        cellContent = document.createElement('div');
                        cellContent.classList.add('pressure-plate', 'active');
                        break;
                    case 6: // Closed Dynamic Wall
                        cell.classList.add('dynamic-wall');
                        break;
                    case 7: // Open Dynamic Wall
                        cell.classList.add('dynamic-wall', 'open');
                        break;
                    case 0: // Floor (or start pos after init)
                    default:
                        cell.classList.add('floor');
                        break;
                }

                // Add player div if player is on this cell
                if (isPlayerOnCell) {
                    const playerDiv = document.createElement('div');
                    playerDiv.classList.add('player');
                    // If there's already content (like a plate), append player to it, otherwise append to cell
                    if (cellContent) {
                        cellContent.appendChild(playerDiv);
                    } else {
                       cell.appendChild(playerDiv);
                    }
                }
                // Add plate content if it exists and player isn't on it
                else if(cellContent){
                     cell.appendChild(cellContent);
                }


                mazeContainer.appendChild(cell);
            }
        }
    }

    // --- Movement & Interaction ---
    function handleKeyPress(event) {
        if (!gameActive) return;

        let dr = 0, dc = 0;
        switch (event.key) {
            case 'ArrowUp':    dr = -1; break;
            case 'ArrowDown':  dr = 1;  break;
            case 'ArrowLeft':  dc = -1; break;
            case 'ArrowRight': dc = 1;  break;
            default: return; // Ignore other keys
        }

        event.preventDefault(); // Prevent page scrolling

        const nextPos = { r: playerPos.r + dr, c: playerPos.c + dc };

        // --- Collision & Boundary Check ---
        if (nextPos.r < 0 || nextPos.r >= numRows || nextPos.c < 0 || nextPos.c >= numCols) {
            return; // Out of bounds
        }

        const targetCellType = mazeData[nextPos.r][nextPos.c];
        if (targetCellType === 1 || targetCellType === 6) { // Wall or Closed Dynamic Wall
            return; // Collision
        }

        // --- Interaction Check (Before Move) ---
        const currentCellType = mazeData[playerPos.r][playerPos.c];
        // Stepping OFF a pressure plate
        if (currentCellType === 5) { // Was on an active plate
             togglePlateAndWalls(playerPos.r, playerPos.c, false); // Deactivate
        }

        // --- Move Player ---
        playerPos = nextPos;

        // --- Interaction Check (After Move) ---
        const newCellType = mazeData[playerPos.r][playerPos.c];
        // Stepping ON a pressure plate
        if (newCellType === 4) { // Stepped on inactive plate
             togglePlateAndWalls(playerPos.r, playerPos.c, true); // Activate
        }

        // --- Re-render ---
        renderMaze();

        // --- Win Condition Check ---
        if (mazeData[playerPos.r][playerPos.c] === 3) {
            messageElement.textContent = "Congratulations! You reached the goal!";
            gameActive = false;
            document.removeEventListener('keydown', handleKeyPress);
        }
         // Update message if stepping on/off plates for clarity (optional)
         else if (newCellType === 5) {
            messageElement.textContent = "Plate activated!";
        } else if (currentCellType === 5 && newCellType !== 5){
             messageElement.textContent = "Plate deactivated.";
        }
    }

    // --- Dynamic Element Logic ---
    function togglePlateAndWalls(plateR, plateC, activate) {
        const plateKey = `${plateR},${plateC}`;

        // Toggle plate state in mazeData
        mazeData[plateR][plateC] = activate ? 5 : 4; // 5 = active, 4 = inactive

        // Find linked walls and toggle their state
        if (plateLinks[plateKey]) {
            plateLinks[plateKey].forEach(wallCoord => {
                const { r, c } = wallCoord;
                if (mazeData[r] && mazeData[r][c] !== undefined) {
                    // Toggle between Closed (6) and Open (7)
                    if (mazeData[r][c] === 6) { // If closed, open it
                        mazeData[r][c] = 7;
                    } else if (mazeData[r][c] === 7) { // If open, close it
                        mazeData[r][c] = 6;
                    }
                    // Note: We could add safety checks here if needed
                }
            });
        }
    }

    // --- Start the Game ---
    initGame();
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.