In my html+js web app for board game playtesting I want a few features changed. 1. Make the display responsive so that it fits mobile screens. If possible make it somehow easier to click the tiny corners on touchscreens. 2. A small fix is needed - a failed flood fill action (one that doesn't find a properely enclosed area) should NOT automatically pass the turn. 3. The random wall generating on setup should be reworked, it shouldn't anymore happen upon setting up a new game. Instead, a new game board should be covered by a "fog of war", by 9 squares laid out in 3x3 fashion, each covering 3x3 square fields and borders and corners *between them*. Note: outside borders and borders between the fog patches are NOT covered by any fog. For this implementation, clearing a patch of fog should happen by simply clicking on it any time, with no restrictions. Clearing a fog patch should run terrain features generation function on the uncovered area, except for 2 first clearings that happen in the game. For now the generation function should for each of 12 uncovered border fields with a 0.2 probability turn it into a black wall. Future implementations will generate bonus features on square fields aswell. CODE: <!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Interactive Game Board</title>
    <style>
        /* Game board container */
        #game-container {
            display: grid;
            /* Define alternating wall and cell sizes: Walls are 10px, cells are 50px */
            grid-template-columns: 10px repeat(9, 50px 10px);
            grid-template-rows: 10px repeat(9, 50px 10px);
            gap: 0;
            position: relative;
            width: calc(10px + 9 * (50px + 10px)); /* 10 + 9*(50+10) = 10 + 540 = 550px */
            height: calc(10px + 9 * (50px + 10px)); /* 550px */
            margin: 50px auto;
            border: 10px solid #333;
            background-color: #fff;
        }

        /* Cells */
        .cell {
            width: 100%;
            height: 100%;
            background-color: white;
            border: none; /* Borders are handled by grid walls */
            position: relative;
            cursor: pointer;
            overflow: hidden;
        }

        /* Marker container */
        .marker-container {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-weight: bold;
            font-size: 24px;
            pointer-events: none; /* Allows clicks to pass through to the cell */
        }

        /* Number container */
        .number-container {
            position: absolute;
            top: 2px;
            left: 2px;
            font-size: 14px;
            pointer-events: none; /* Allows clicks to pass through to the cell */
        }

        /* Corners */
        .corner {
            width: 100%;
            height: 100%;
            background-color: #666;
            cursor: pointer;
        }

        /* Horizontal walls */
        .h-wall {
            width: 100%;
            height: 100%;
            background-color: transparent; /* Initially no wall */
            cursor: pointer;
        }

        /* Vertical walls */
        .v-wall {
            width: 100%;
            height: 100%;
            background-color: transparent; /* Initially no wall */
            cursor: pointer;
        }

        /* Hover effect */
        .cell:hover,
        .corner:hover,
        .h-wall:hover,
        .v-wall:hover {
            background-color: #ffd700;
        }

        /* Controls */
        #controls {
            text-align: center;
            margin: 20px;
        }

        #controls button {
            padding: 10px 20px;
            margin: 5px;
            font-size: 16px;
            cursor: pointer;
        }

        /* Status display */
        #status-container {
            text-align: center;
            font-size: 18px;
            margin-bottom: 10px;
        }

        .status-item {
            margin: 5px;
        }

        .wall-counter {
            margin-top: 10px;
            font-size: 16px;
            color: #333;
        }

        /* Message display */
        #message {
            text-align: center;
            font-size: 16px;
            margin-bottom: 10px;
            color: green;
        }

        /* Filled area */
        .filled {
            background-color: rgba(0, 0, 255, 0.2);
        }

        .filled-red {
            background-color: rgba(255, 0, 0, 0.2);
        }

        /* Disabled walls (black walls) */
        .disabled-wall {
            background-color: black !important;
            cursor: not-allowed !important;
        }
    </style>
</head>
<body>
    <div id="status-container">
        <div class="status-item">Current Player: <span id="current-player" style="color: blue;">Blue (O)</span></div>
        <div class="wall-counter">
            Blue Walls Used: <span id="blue-walls-used">0</span> |
            Red Walls Used: <span id="red-walls-used">0</span>
        </div>
    </div>
    <div id="message"></div>
    <div id="game-container"></div>
    <div id="controls">
        <button id="flood-button" disabled>Flood</button>
        <button id="count-button" disabled>Count</button>
        <button id="pass-button" disabled>Pass Turn</button>
        <button id="reset-button">Reset Game</button>
    </div>
    <script>
        const N = 9; // Grid size
        const gameContainer = document.getElementById('game-container');
        const statusDisplay = document.getElementById('current-player');
        const messageDisplay = document.getElementById('message');
        const floodButton = document.getElementById('flood-button');
        const countButton = document.getElementById('count-button');
        const passButton = document.getElementById('pass-button');
        const resetButton = document.getElementById('reset-button');
        const blueWallsUsedDisplay = document.getElementById('blue-walls-used');
        const redWallsUsedDisplay = document.getElementById('red-walls-used');

        let currentPlayer = 'blue'; // 'blue' or 'red'
        let turnPhase = 1; // 1: Place marker, 2: Choose action
        let actionMode = null; // 'flood' or 'count'
        let wallMode = false; // Indicates if in wall drawing mode
        let firstCorner = null; // Stores first corner selected for wall
        let countNumber = {
            blue: 1,
            red: 1
        };
        let optionalWallDrawn = false; // Tracks optional wall during flood

        const totalWalls = 2 * (N + 1) * N; // h-walls + v-walls = 2 * 10 * 9 = 180
        const percentageWallsToDisable = 0.12; // 12%
        const wallsToDisableCount = Math.floor(totalWalls * percentageWallsToDisable); // 21

        const players = {
            blue: {
                name: 'Blue',
                color: 'blue',
                marker: 'O',
                markerPosition: null,
                usedWalls: 0
            },
            red: {
                name: 'Red',
                color: 'red',
                marker: 'X',
                markerPosition: null,
                usedWalls: 0
            }
        };

        // Initialize game board elements
        function initGameBoard() {
            gameContainer.innerHTML = '';
            // Create cells
            for (let i = 0; i < N; i++) {
                for (let j = 0; j < N; j++) {
                    const cell = document.createElement('div');
                    cell.classList.add('cell');
                    cell.dataset.row = i;
                    cell.dataset.col = j;
                    cell.style.gridRowStart = 2 + i * 2; // Cells are on even grid lines
                    cell.style.gridColumnStart = 2 + j * 2;

                    // Create marker and number containers
                    const markerContainer = document.createElement('div');
                    markerContainer.classList.add('marker-container');
                    markerContainer.id = `marker-${i}-${j}`;

                    const numberContainer = document.createElement('div');
                    numberContainer.classList.add('number-container');
                    numberContainer.id = `number-${i}-${j}`;

                    cell.appendChild(markerContainer);
                    cell.appendChild(numberContainer);

                    cell.addEventListener('click', onCellClick);
                    gameContainer.appendChild(cell);
                }
            }

            // Create corners
            for (let i = 0; i <= N; i++) {
                for (let j = 0; j <= N; j++) {
                    const corner = document.createElement('div');
                    corner.classList.add('corner');
                    corner.dataset.row = i;
                    corner.dataset.col = j;
                    corner.style.gridRowStart = 1 + i * 2;
                    corner.style.gridColumnStart = 1 + j * 2;
                    corner.addEventListener('click', onCornerClick);
                    gameContainer.appendChild(corner);
                }
            }

            // Create horizontal walls
            for (let i = 0; i <= N; i++) {
                for (let j = 0; j < N; j++) {
                    const hWall = document.createElement('div');
                    hWall.classList.add('h-wall');
                    hWall.dataset.row = i;
                    hWall.dataset.col = j;
                    hWall.style.gridRowStart = 1 + i * 2;
                    hWall.style.gridColumnStart = 2 + j * 2;
                    hWall.addEventListener('click', onWallClick);
                    gameContainer.appendChild(hWall);
                }
            }

            // Create vertical walls
            for (let i = 0; i < N; i++) {
                for (let j = 0; j <= N; j++) {
                    const vWall = document.createElement('div');
                    vWall.classList.add('v-wall');
                    vWall.dataset.row = i;
                    vWall.dataset.col = j;
                    vWall.style.gridRowStart = 2 + i * 2;
                    vWall.style.gridColumnStart = 1 + j * 2;
                    vWall.addEventListener('click', onWallClick);
                    gameContainer.appendChild(vWall);
                }
            }

            // Randomly disable 12% of walls
            disableRandomWalls();
        }

        // Function to randomly disable walls at the start of the game
        function disableRandomWalls() {
            const allWalls = Array.from(document.querySelectorAll('.h-wall, .v-wall'));
            const disabledWalls = getRandomUniqueElements(allWalls, wallsToDisableCount);

            disabledWalls.forEach(wall => {
                wall.classList.add('disabled-wall');
                wall.removeEventListener('click', onWallClick); // Disable clicking
            });
        }

        // Utility function to get random unique elements from an array
        function getRandomUniqueElements(array, count) {
            const shuffled = array.slice();
            for (let i = shuffled.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
            }
            return shuffled.slice(0, count);
        }

        // Reset Game
        function resetGame() {
            currentPlayer = 'blue';
            turnPhase = 1;
            actionMode = null;
            wallMode = false;
            firstCorner = null;
            countNumber = {
                blue: 1,
                red: 1
            };
            optionalWallDrawn = false;
            players.blue.markerPosition = null;
            players.red.markerPosition = null;
            players.blue.usedWalls = 0;
            players.red.usedWalls = 0;
            updateStatus();
            updateWallCounters();
            setMessage('');
            disableButtons();
            initGameBoard();
        }

        // Update status display
        function updateStatus() {
            statusDisplay.textContent = `${players[currentPlayer].name} (${players[currentPlayer].marker})`;
            statusDisplay.style.color = players[currentPlayer].color;
        }

        // Update wall counters display
        function updateWallCounters() {
            blueWallsUsedDisplay.textContent = players.blue.usedWalls;
            redWallsUsedDisplay.textContent = players.red.usedWalls;
        }

        // Set message display
        function setMessage(msg, color = 'green') {
            messageDisplay.textContent = msg;
            messageDisplay.style.color = color;
        }

        // Disable action buttons
        function disableButtons() {
            floodButton.disabled = true;
            countButton.disabled = true;
            passButton.disabled = true;
        }

        // Enable action buttons
        function enableButtons() {
            floodButton.disabled = false;
            countButton.disabled = false;
            passButton.disabled = false;
        }

        // Cell click handler
        function onCellClick(e) {
            const cell = e.currentTarget;
            const row = parseInt(cell.dataset.row);
            const col = parseInt(cell.dataset.col);

            if (turnPhase === 1) {
                // Place marker

                // Remove existing marker if any
                if (players[currentPlayer].markerPosition) {
                    const prevPos = players[currentPlayer].markerPosition;
                    const prevMarkerContainer = document.getElementById(`marker-${prevPos.row}-${prevPos.col}`);
                    if (prevMarkerContainer) {
                        const existingMarker = prevMarkerContainer.querySelector(`span[data-player="${currentPlayer}"]`);
                        if (existingMarker) {
                            prevMarkerContainer.removeChild(existingMarker);
                        }
                    }
                }

                // Update marker container without affecting numbers
                const markerContainer = document.getElementById(`marker-${row}-${col}`);
                // Add the marker for the current player
                const existingMarker = markerContainer.querySelector(`span[data-player="${currentPlayer}"]`);
                if (!existingMarker) {
                    const marker = document.createElement('span');
                    marker.textContent = players[currentPlayer].marker;
                    marker.style.color = players[currentPlayer].color;
                    marker.dataset.player = currentPlayer;
                    markerContainer.appendChild(marker);
                }

                // Update marker position for the player
                players[currentPlayer].markerPosition = { row, col };

                // Enable action buttons
                enableButtons();

                // Move to next turn phase
                turnPhase = 2;
                setMessage('Marker placed. Choose an action.');
            } else if (turnPhase === 2) {
                if (actionMode === 'flood') {
                    performFloodFill(row, col);
                    actionMode = null;
                    // After flood fill, end the turn
                    endTurn();
                } else if (actionMode === 'count') {
                    placeCount(cell);
                }
            }
        }

        // Corner click handler
        function onCornerClick(e) {
            if (turnPhase !== 2) {
                return;
            }
            const corner = e.currentTarget;
            const row = parseInt(corner.dataset.row);
            const col = parseInt(corner.dataset.col);

            if (wallMode) {
                // Second corner click
                const dist = Math.abs(firstCorner.row - row) + Math.abs(firstCorner.col - col);
                if ((firstCorner.row === row || firstCorner.col === col) && (dist === 1 || dist === 2)) {
                    const success = drawWallBetweenCorners(firstCorner, { row, col }, currentPlayer);
                    if (success) {
                        setMessage('Wall drawn successfully.', 'green');
                        players[currentPlayer].usedWalls += 1;
                        updateWallCounters();
                        if (actionMode === 'flood') {
                            // During flood, allow drawing only one optional wall
                            optionalWallDrawn = true;
                            // Remain in action mode 'flood' to allow flood fill
                        } else {
                            // Normally, end the turn after drawing a wall
                            endTurn();
                        }
                    } else {
                        setMessage('Failed to draw wall. It might already exist.', 'red');
                    }
                    // Reset wall drawing state
                    wallMode = false;
                    firstCorner.element.style.backgroundColor = '#666';
                    firstCorner = null;
                } else {
                    setMessage('Second corner must be adjacent horizontally or vertically.', 'red');
                }
            } else {
                // First corner click
                if (actionMode === 'flood' && optionalWallDrawn) {
                    // Already drew optional wall during flood
                    setMessage('Optional wall already drawn for this flood action.', 'red');
                    return;
                }

                // Check if corner is adjacent to the current player's marker position
                const markerPos = players[currentPlayer].markerPosition;
                if (markerPos && isCornerAdjacentToCell(row, col, markerPos.row, markerPos.col)) {
                    wallMode = true;
                    firstCorner = { row, col, element: corner };
                    corner.style.backgroundColor = players[currentPlayer].color;
                    if (actionMode === 'flood') {
                        setMessage('Select the second corner to draw the optional wall.', 'blue');
                    } else {
                        setMessage('Select the second corner to draw the wall.', 'blue');
                    }
                } else {
                    setMessage('Select a corner adjacent to your marker cell.', 'red');
                }
            }
        }

        // Wall click handler (to prevent walls from being clickable)
        function onWallClick(e) {
            // Currently, walls are drawn via corner clicks. Clicking walls themselves does nothing.
            // If additional functionalities are desired (e.g., removing walls), implement here.
        }

        // Check if corner is adjacent to cell
        function isCornerAdjacentToCell(cornerRow, cornerCol, cellRow, cellCol) {
            const cellCorners = getCellCorners(cellRow, cellCol);
            return cellCorners.some(c => c.row === cornerRow && c.col === cornerCol);
        }

        // Get corners of a cell
        function getCellCorners(cellRow, cellCol) {
            const topLeft = { row: cellRow, col: cellCol };
            const topRight = { row: cellRow, col: cellCol + 1 };
            const bottomLeft = { row: cellRow + 1, col: cellCol };
            const bottomRight = { row: cellRow + 1, col: cellCol + 1 };
            return [topLeft, topRight, bottomLeft, bottomRight];
        }

        // Draw wall between two corners
        // Returns true if wall was successfully drawn, false otherwise
        function drawWallBetweenCorners(corner1, corner2, player) {
            let wallsDrawn = [];

            if (corner1.row === corner2.row) {
                // Horizontal wall(s)
                const minCol = Math.min(corner1.col, corner2.col);
                const maxCol = Math.max(corner1.col, corner2.col);
                for (let col = minCol; col < maxCol; col++) {
                    const hWall = document.querySelector(`.h-wall[data-row="${corner1.row}"][data-col="${col}"]`);
                    if (hWall) {
                        if (isWallPresent(hWall)) {
                            // Wall already exists
                            return false;
                        }
                        hWall.style.backgroundColor = players[player].color;
                        wallsDrawn.push(hWall);
                    }
                }
            } else if (corner1.col === corner2.col) {
                // Vertical wall(s)
                const minRow = Math.min(corner1.row, corner2.row);
                const maxRow = Math.max(corner1.row, corner2.row);
                for (let row = minRow; row < maxRow; row++) {
                    const vWall = document.querySelector(`.v-wall[data-row="${row}"][data-col="${corner1.col}"]`);
                    if (vWall) {
                        if (isWallPresent(vWall)) {
                            // Wall already exists
                            return false;
                        }
                        vWall.style.backgroundColor = players[player].color;
                        wallsDrawn.push(vWall);
                    }
                }
            } else {
                // Diagonal walls are not allowed
                return false;
            }

            // If all walls drawn successfully, update counts
            if (wallsDrawn.length > 0) {
                return true;
            } else {
                return false;
            }
        }

        // Check if a wall is already present (not disabled)
        function isWallPresent(wallElement) {
            // A wall is present if its background color is not transparent and not black (disabled)
            const bgColor = window.getComputedStyle(wallElement).backgroundColor;
            return bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent' && bgColor !== 'black';
        }

        // old 1.0 code below
        // Flood button handler
        floodButton.addEventListener('click', () => {
            if (actionMode !== null) return;
            actionMode = 'flood';
            optionalWallDrawn = false;
            setMessage('Flood mode activated. Optionally draw one wall adjacent to your marker, then click on a cell to perform flood fill.', 'blue');
            // Enable wall drawing; Flood mode manages walls differently
        });

        // Count button handler
        countButton.addEventListener('click', () => {
            if (actionMode !== null) return;
            actionMode = 'count';
            setMessage('Count mode activated. Click on cells to place counts. Click Pass Turn when done.', 'blue');
        });

        // Pass button handler
        passButton.addEventListener('click', () => {
            endTurn();
        });

        // Reset button handler
        resetButton.addEventListener('click', () => {
            resetGame();
        });

        // Perform Flood Fill
        function performFloodFill(startRow, startCol) {
            const visited = new Set();
            const fillColor = currentPlayer === 'blue' ? 'filled' : 'filled-red';
            const queue = [{ row: startRow, col: startCol }];
            let isEnclosed = true;

            while (queue.length > 0) {
                const { row, col } = queue.shift();
                const key = `${row},${col}`;
                if (visited.has(key)) continue;
                visited.add(key);

                // Check if cell is on boundary WITHOUT a wall blocking the flood
                if (
                    (row === 0 && (!isWallPresent(getCellWalls(row, col).top))) ||
                    (row === N - 1 && (!isWallPresent(getCellWalls(row, col).bottom))) ||
                    (col === 0 && (!isWallPresent(getCellWalls(row, col).left))) ||
                    (col === N - 1 && (!isWallPresent(getCellWalls(row, col).right)))
                ) {
                    isEnclosed = false;
                }

                // Check all four directions
                const walls = getCellWalls(row, col);

                // Top
                if (!walls.top || !isWallPresent(walls.top)) {
                    if (row > 0) {
                        queue.push({ row: row - 1, col });
                    }
                }

                // Bottom
                if (!walls.bottom || !isWallPresent(walls.bottom)) {
                    if (row < N - 1) {
                        queue.push({ row: row + 1, col });
                    }
                }

                // Left
                if (!walls.left || !isWallPresent(walls.left)) {
                    if (col > 0) {
                        queue.push({ row, col: col - 1 });
                    }
                }

                // Right
                if (!walls.right || !isWallPresent(walls.right)) {
                    if (col < N - 1) {
                        queue.push({ row, col: col + 1 });
                    }
                }
            }

            if (isEnclosed) {
                // Fill the area
                visited.forEach(key => {
                    const [row, col] = key.split(',').map(Number);
                    const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
                    if (cell) {
                        cell.classList.add(fillColor);
                    }
                });
                setMessage('Area is enclosed. Flood Fill completed!', 'green');
            } else {
                setMessage('Area is not fully enclosed. Flood Fill failed.', 'red');
            }
        }

        // Get walls around a cell
        function getCellWalls(row, col) {
            const walls = {};

            // Top wall
            walls.top = document.querySelector(`.h-wall[data-row="${row}"][data-col="${col}"]`);

            // Bottom wall
            walls.bottom = document.querySelector(`.h-wall[data-row="${row + 1}"][data-col="${col}"]`);

            // Left wall
            walls.left = document.querySelector(`.v-wall[data-row="${row}"][data-col="${col}"]`);

            // Right wall
            walls.right = document.querySelector(`.v-wall[data-row="${row}"][data-col="${col + 1}"]`);

            return walls;
        }

        // Check if wall is present (colored)
        function isWallPresent(wall) {
            if (!wall) return false;
            const bgColor = window.getComputedStyle(wall).backgroundColor;
            // Transparent walls have RGBA(0, 0, 0, 0) or 'transparent'
            return bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent';
        }

        // Place count on cell
        function placeCount(cell) {
            const row = parseInt(cell.dataset.row);
            const col = parseInt(cell.dataset.col);
            const numberContainer = document.getElementById(`number-${row}-${col}`);

            if (numberContainer.textContent) {
                setMessage('Cell already has a number.', 'red');
                return;
            }

            const number = countNumber[currentPlayer]++;
            numberContainer.textContent = number;
            numberContainer.style.color = players[currentPlayer].color;
            setMessage('Count placed.', 'green');
        }

        // End turn
        function endTurn() {
            // Reset variables
            turnPhase = 1;
            actionMode = null;
            wallMode = false;
            firstCorner = null;
            optionalWallDrawn = false;

            // Disable action buttons
            disableButtons();

            // Swap player
            currentPlayer = currentPlayer === 'blue' ? 'red' : 'blue';
            updateStatus();
            setMessage('Turn passed to the next player.', 'blue');
        }

        // Initialize the game
        resetGame();
    </script>
</body>
</html>