<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>8 Queens Puzzle</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>8 Queens Puzzle</h1>
    <div class="controls">
        <button id="reset-button">Reset Game</button>
        <p id="message">Place 8 queens so that none attack each other. Click a square to place/remove a queen.</p>
        <p>Queens placed: <span id="queen-count">0</span> / 8</p>
    </div>

    <div id="chessboard">
        <!-- Squares will be generated by JavaScript -->
    </div>

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

h1 {
    color: #333;
}

.controls {
    margin-bottom: 20px;
    text-align: center;
}

#reset-button {
    padding: 10px 20px;
    font-size: 1em;
    cursor: pointer;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    margin-bottom: 10px;
}

#reset-button:hover {
    background-color: #45a049;
}

#message {
    font-style: italic;
    color: #555;
    min-height: 20px; /* Prevent layout shift */
}

#queen-count {
    font-weight: bold;
}

#chessboard {
    width: 400px; /* Adjust size as needed */
    height: 400px; /* Should be equal to width */
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(8, 1fr);
    border: 3px solid #333;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.square {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2.5em; /* Adjust queen size */
    cursor: pointer;
    user-select: none; /* Prevent text selection on click */
    transition: background-color 0.1s ease-in-out; /* Smooth highlight */
}

.square.light {
    background-color: #f0d9b5; /* Light square color */
}

.square.dark {
    background-color: #b58863; /* Dark square color */
}

.square.queen::before {
    content: '♛'; /* Queen symbol */
    color: #000; /* Queen color */
}

/* Optional: Highlight invalid moves briefly */
/* .square.invalid {
    background-color: rgba(255, 0, 0, 0.5) !important;
} */

/* Style for winning state */
.win #message {
    color: green;
    font-weight: bold;
}
document.addEventListener('DOMContentLoaded', () => {
    const boardSize = 8;
    const chessboard = document.getElementById('chessboard');
    const messageElement = document.getElementById('message');
    const queenCountElement = document.getElementById('queen-count');
    const resetButton = document.getElementById('reset-button');
    const bodyElement = document.body;

    let boardState = Array(boardSize).fill(null).map(() => Array(boardSize).fill(0)); // 0: empty, 1: queen
    let queenCount = 0;
    let gameOver = false;

    // --- Board Generation ---
    function createBoard() {
        chessboard.innerHTML = ''; // Clear previous board
        for (let row = 0; row < boardSize; row++) {
            for (let col = 0; col < boardSize; col++) {
                const square = document.createElement('div');
                square.classList.add('square');
                square.classList.add(((row + col) % 2 === 0) ? 'light' : 'dark');
                square.dataset.row = row;
                square.dataset.col = col;
                square.addEventListener('click', handleSquareClick);
                chessboard.appendChild(square);
            }
        }
    }

    // --- Game Logic ---
    function isSafe(row, col) {
        // Check row and column
        for (let i = 0; i < boardSize; i++) {
            if (boardState[row][i] === 1 || boardState[i][col] === 1) {
                return false;
            }
        }

        // Check diagonals
        for (let i = 1; row - i >= 0 && col - i >= 0; i++) { // Top-left
            if (boardState[row - i][col - i] === 1) return false;
        }
        for (let i = 1; row - i >= 0 && col + i < boardSize; i++) { // Top-right
            if (boardState[row - i][col + i] === 1) return false;
        }
        for (let i = 1; row + i < boardSize && col - i >= 0; i++) { // Bottom-left
            if (boardState[row + i][col - i] === 1) return false;
        }
        for (let i = 1; row + i < boardSize && col + i < boardSize; i++) { // Bottom-right
            if (boardState[row + i][col + i] === 1) return false;
        }

        return true;
    }

    function handleSquareClick(event) {
        if (gameOver) return; // Don't allow changes after winning

        const square = event.target;
        const row = parseInt(square.dataset.row);
        const col = parseInt(square.dataset.col);

        messageElement.textContent = "Place 8 queens so that none attack each other."; // Reset message
        bodyElement.classList.remove('win');

        if (boardState[row][col] === 1) {
            // Remove queen
            boardState[row][col] = 0;
            square.classList.remove('queen');
            queenCount--;
        } else {
            // Try to place queen
            if (isSafe(row, col)) {
                boardState[row][col] = 1;
                square.classList.add('queen');
                queenCount++;

                if (queenCount === boardSize) {
                    checkWinCondition();
                }
            } else {
                // Optionally provide feedback for invalid placement
                // square.classList.add('invalid');
                // setTimeout(() => square.classList.remove('invalid'), 200);
                messageElement.textContent = "Invalid move! A queen here is attacked.";
            }
        }
        updateQueenCount();
    }

    function updateQueenCount() {
        queenCountElement.textContent = queenCount;
    }

    function checkWinCondition() {
        // Since we prevent invalid moves, reaching 8 queens means success
        if (queenCount === boardSize) {
            messageElement.textContent = "Congratulations! You solved the 8 Queens puzzle!";
            bodyElement.classList.add('win'); // Add class for styling
            gameOver = true; // Stop further placements
        }
    }

    // --- Reset ---
    function resetGame() {
        boardState = Array(boardSize).fill(null).map(() => Array(boardSize).fill(0));
        queenCount = 0;
        gameOver = false;
        messageElement.textContent = "Place 8 queens so that none attack each other.";
        bodyElement.classList.remove('win');
        updateQueenCount();
        // Clear visual representation
        const squares = chessboard.querySelectorAll('.square');
        squares.forEach(square => square.classList.remove('queen'));
    }

    // --- Initialization ---
    createBoard();
    resetButton.addEventListener('click', resetGame);
    updateQueenCount(); // Initial count (0)
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.