import React, { useState, useEffect, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { Play, Pause, RotateCcw, Crown, Timer, Trophy } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import SocialShare from './SocialShare'; interface NQueensPuzzleProps { showSocialShare?: boolean; } const NQueensPuzzle: React.FC = ({ showSocialShare = false }) => { const navigate = useNavigate(); const [boardSize, setBoardSize] = useState([8]); const [queens, setQueens] = useState>(new Set()); const [timerStarted, setTimerStarted] = useState(false); const [timeElapsed, setTimeElapsed] = useState(0); const [isRunning, setIsRunning] = useState(false); // Timer effect useEffect(() => { let interval: NodeJS.Timeout; if (isRunning) { interval = setInterval(() => { setTimeElapsed(prev => prev + 1); }, 1000); } return () => clearInterval(interval); }, [isRunning]); const formatTime = (seconds: number) => { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; }; const startTimer = () => { setTimerStarted(true); setIsRunning(true); }; const pauseTimer = () => { setIsRunning(false); }; const resetPuzzle = () => { setQueens(new Set()); setTimerStarted(false); setIsRunning(false); setTimeElapsed(0); }; const isQueenAt = (row: number, col: number) => { return queens.has(`${row}-${col}`); }; const isSquareAttacked = useCallback((row: number, col: number) => { for (const queenPos of queens) { const [queenRow, queenCol] = queenPos.split('-').map(Number); // Same row or column if (queenRow === row || queenCol === col) { return true; } // Diagonal if (Math.abs(queenRow - row) === Math.abs(queenCol - col)) { return true; } } return false; }, [queens]); const handleSquareClick = (row: number, col: number) => { if (!timerStarted) return; const posKey = `${row}-${col}`; if (queens.has(posKey)) { // Remove queen const newQueens = new Set(queens); newQueens.delete(posKey); setQueens(newQueens); } else { // Add queen const newQueens = new Set(queens); newQueens.add(posKey); setQueens(newQueens); } }; const getSquareStyle = (row: number, col: number) => { const isLight = (row + col) % 2 === 0; const hasQueen = isQueenAt(row, col); const isAttacked = !hasQueen && isSquareAttacked(row, col); let baseClasses = "aspect-square border border-border flex items-center justify-center text-2xl font-bold transition-all cursor-pointer relative"; if (isLight) { baseClasses += " bg-amber-100 dark:bg-amber-200"; } else { baseClasses += " bg-amber-600 dark:bg-amber-700"; } if (hasQueen) { baseClasses += " bg-primary/20 ring-2 ring-primary"; } else if (isAttacked) { baseClasses += " bg-destructive/10"; } if (!timerStarted) { baseClasses += " cursor-not-allowed opacity-50"; } else { baseClasses += " hover:bg-accent/20"; } return baseClasses; }; const renderSquare = (row: number, col: number) => { const hasQueen = isQueenAt(row, col); const isAttacked = !hasQueen && isSquareAttacked(row, col); return (
handleSquareClick(row, col)} > {hasQueen && } {isAttacked && (
)}
); }; const currentBoardSize = boardSize[0]; const maxPossibleQueens = currentBoardSize; const currentQueenCount = queens.size; return (
{/* Header */}

N-Queens Puzzle

Place as many queens as possible on the chessboard so that no two queens attack each other. Queens attack horizontally, vertically, and diagonally.

{/* Controls */}
Game Controls
Time: {formatTime(timeElapsed)}
{!timerStarted ? ( ) : ( )}
Queens Placed: {currentQueenCount}/{maxPossibleQueens}
{currentQueenCount === maxPossibleQueens && (
Perfect solution found!
)}
Instructions

• Start the timer to begin placing queens

• Click empty squares to place queens

• Click placed queens to remove them

• Red dots show attacked squares

• Try to place {currentBoardSize} queens without conflicts!

{/* Chessboard */}
{Array.from({ length: currentBoardSize }, (_, row) => Array.from({ length: currentBoardSize }, (_, col) => renderSquare(row, col) ) )}
{!timerStarted && (

Start the timer to begin placing queens

)}
{showSocialShare && ( )}
); }; export default NQueensPuzzle;