"use client"; import { useState } from "react"; import { generateSudoku, solveSudoku, Difficulty, SudokuGrid } from "./sudokuGenerator"; function cloneGrid(grid: SudokuGrid): SudokuGrid { return grid.map(row => [...row]); } function getInvalidCells(grid: SudokuGrid): boolean[][] { const invalid: boolean[][] = Array.from({ length: 9 }, () => Array(9).fill(false)); for (let row = 0; row < 9; row++) { for (let col = 0; col < 9; col++) { const val = grid[row][col]; if (val === 0) continue; for (let k = 0; k < 9; k++) { if (k !== col && grid[row][k] === val) invalid[row][col] = true; if (k !== row && grid[k][col] === val) invalid[row][col] = true; } const startRow = row - row % 3; const startCol = col - col % 3; for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { const r = startRow + i; const c = startCol + j; if ((r !== row || c !== col) && grid[r][c] === val) invalid[row][col] = true; } } } } return invalid; } function SudokuBoard({ grid, onChange, editable, invalidCells, fixedCells }: { grid: SudokuGrid; onChange?: (row: number, col: number, value: number) => void; editable?: boolean; invalidCells?: boolean[][]; fixedCells?: boolean[][] }) { return ( {grid.map((row, i) => ( {row.map((cell, j) => ( ))} ))}
{editable && onChange ? ( fixedCells && fixedCells[i][j] ? ( {cell} ) : ( onChange(i, j, Number(e.target.value))} style={{width:'100%',height:'100%',textAlign:'center',background:'#fff',border:'none',outline:'none',fontSize:20,fontWeight:'bold',color:invalidCells && invalidCells[i][j] ? '#d32f2f' : '#222'}} /> ) ) : ( cell !== 0 ? ( {cell} ) : "" )}
); } export default function Home() { const [difficulty, setDifficulty] = useState("easy"); const [grid, setGrid] = useState(null); const [solvedGrid, setSolvedGrid] = useState(null); const [error, setError] = useState(""); const [customGrid, setCustomGrid] = useState(Array.from({ length: 9 }, () => Array(9).fill(0))); const [showCustom, setShowCustom] = useState(false); const [userGrid, setUserGrid] = useState(null); const [checkResult, setCheckResult] = useState(""); const handleGenerate = () => { const generated = generateSudoku(difficulty); setGrid(generated); setUserGrid(cloneGrid(generated)); setSolvedGrid(null); setError(""); setShowCustom(false); setCheckResult(""); }; const handleUserChange = (row: number, col: number, value: number) => { if (!userGrid) return; if (value < 0 || value > 9) return; setUserGrid(prev => { if (!prev) return null; const copy = cloneGrid(prev); copy[row][col] = value; return copy; }); }; const handleCheck = () => { if (!userGrid || !grid) return; const invalid = getInvalidCells(userGrid); const hasInvalid = invalid.flat().some(Boolean); if (hasInvalid) { setCheckResult("Erreur : La grille contient des chiffres en conflit (ligne, colonne ou bloc). Les chiffres invalides sont en rouge."); return; } for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { if (userGrid[i][j] === 0) { setCheckResult("La grille n'est pas entièrement remplie."); return; } } } for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { if (grid[i][j] !== 0 && userGrid[i][j] !== grid[i][j]) { setCheckResult("Erreur : Vous avez modifié une case pré-remplie."); return; } } } setCheckResult("Bravo ! La solution est correcte."); }; const handleSolve = () => { if (!grid) return; const gridCopy = cloneGrid(grid); const solved = solveSudoku(gridCopy); if (solved) { setSolvedGrid(gridCopy); setError(""); } else { setError("Grille non résoluble."); } }; const handleCustomSolve = () => { const invalid = getInvalidCells(customGrid); const hasInvalid = invalid.flat().some(Boolean); if (hasInvalid) { setSolvedGrid(null); setError("Erreur : La grille contient des chiffres en conflit (ligne, colonne ou bloc). Les chiffres invalides sont en rouge."); return; } const gridCopy = cloneGrid(customGrid); const solved = solveSudoku(gridCopy); if (solved) { setSolvedGrid(gridCopy); setError(""); } else { setSolvedGrid(null); setError("Grille non résoluble."); } }; const handleCustomChange = (row: number, col: number, value: number) => { if (value < 0 || value > 9) return; setCustomGrid(prev => { const copy = cloneGrid(prev); copy[row][col] = value; return copy; }); }; return (

Sudoku

{grid && userGrid && (

Remplissez la grille

row.map(cell => cell !== 0))} /> {checkResult &&
{checkResult}
}
)} {showCustom && (

Saisissez votre grille

)} {solvedGrid && (

Solution

)} {error &&
{error}
}
); }