Add hollow circles for empty state

Replace pebbles with hollow circles with a thin grey border when they are all gone.
-edited `src/components/SubtractionGame.tsx
This commit is contained in:
gpt-engineer-app[bot] 2025-08-22 11:08:33 +00:00
parent cbe125d871
commit f48f7863cc

View file

@ -8,6 +8,7 @@ const SubtractionGame = () => {
const [k, setK] = useState([3]); const [k, setK] = useState([3]);
const [gameStarted, setGameStarted] = useState(false); const [gameStarted, setGameStarted] = useState(false);
const [circles, setCircles] = useState<number[]>([]); const [circles, setCircles] = useState<number[]>([]);
const [removedCircles, setRemovedCircles] = useState<Set<number>>(new Set());
const [currentPlayer, setCurrentPlayer] = useState<'Lata' | 'Raj'>('Lata'); const [currentPlayer, setCurrentPlayer] = useState<'Lata' | 'Raj'>('Lata');
const [winner, setWinner] = useState<string | null>(null); const [winner, setWinner] = useState<string | null>(null);
const [highlightedIndices, setHighlightedIndices] = useState<number[]>([]); const [highlightedIndices, setHighlightedIndices] = useState<number[]>([]);
@ -23,18 +24,21 @@ const SubtractionGame = () => {
// Calculate highlighted indices // Calculate highlighted indices
useEffect(() => { useEffect(() => {
if (circles.length > 0) { if (circles.length > 0) {
const activeCircles = circles.filter(i => !removedCircles.has(i));
const lastKIndices = []; const lastKIndices = [];
const start = Math.max(0, circles.length - k[0]); const activeCount = activeCircles.length;
for (let i = start; i < circles.length; i++) { const start = Math.max(0, activeCount - k[0]);
lastKIndices.push(i); for (let i = start; i < activeCount; i++) {
lastKIndices.push(activeCircles[i]);
} }
setHighlightedIndices(lastKIndices); setHighlightedIndices(lastKIndices);
} }
}, [circles, k]); }, [circles, k, removedCircles]);
const startGame = () => { const startGame = () => {
const initialCircles = Array.from({ length: n[0] }, (_, i) => i); const initialCircles = Array.from({ length: n[0] }, (_, i) => i);
setCircles(initialCircles); setCircles(initialCircles);
setRemovedCircles(new Set());
setGameStarted(true); setGameStarted(true);
setCurrentPlayer('Lata'); setCurrentPlayer('Lata');
setWinner(null); setWinner(null);
@ -43,6 +47,7 @@ const SubtractionGame = () => {
const resetGame = () => { const resetGame = () => {
setGameStarted(false); setGameStarted(false);
setCircles([]); setCircles([]);
setRemovedCircles(new Set());
setWinner(null); setWinner(null);
setCurrentPlayer('Lata'); setCurrentPlayer('Lata');
setHighlightedIndices([]); setHighlightedIndices([]);
@ -50,16 +55,25 @@ const SubtractionGame = () => {
}; };
const handleCircleClick = (index: number) => { const handleCircleClick = (index: number) => {
if (!gameStarted || winner || !highlightedIndices.includes(index)) { if (!gameStarted || winner || !highlightedIndices.includes(index) || removedCircles.has(index)) {
return; return;
} }
// Remove all circles to the right of clicked circle // Mark all circles from clicked index onwards as removed
const newCircles = circles.slice(0, index); const newRemovedCircles = new Set(removedCircles);
setCircles(newCircles); const activeCircles = circles.filter(i => !removedCircles.has(i));
const clickedPosition = activeCircles.indexOf(index);
// Check if game is over // Remove all circles from clicked position onwards
if (newCircles.length === 0) { for (let i = clickedPosition; i < activeCircles.length; i++) {
newRemovedCircles.add(activeCircles[i]);
}
setRemovedCircles(newRemovedCircles);
// Check if game is over (no active circles left)
const remainingActive = circles.filter(i => !newRemovedCircles.has(i));
if (remainingActive.length === 0) {
setWinner(currentPlayer); setWinner(currentPlayer);
setGameStarted(false); setGameStarted(false);
// Trigger confetti // Trigger confetti
@ -81,8 +95,14 @@ const SubtractionGame = () => {
}; };
const getCircleClass = (index: number) => { const getCircleClass = (index: number) => {
const isRemoved = removedCircles.has(index);
const isHighlighted = highlightedIndices.includes(index); const isHighlighted = highlightedIndices.includes(index);
const isHovered = hoveredIndex !== null && index >= hoveredIndex; const isHovered = hoveredIndex !== null && index >= hoveredIndex;
if (isRemoved) {
return 'w-8 h-8 rounded-full border border-gray-300 bg-transparent';
}
const baseClass = `w-8 h-8 rounded-full border-2 border-black transition-colors ${isHighlighted ? 'cursor-pointer' : ''}`; const baseClass = `w-8 h-8 rounded-full border-2 border-black transition-colors ${isHighlighted ? 'cursor-pointer' : ''}`;
let fillClass; let fillClass;
@ -183,7 +203,7 @@ const SubtractionGame = () => {
key={index} key={index}
className={getCircleClass(index)} className={getCircleClass(index)}
onClick={() => handleCircleClick(index)} onClick={() => handleCircleClick(index)}
onMouseEnter={() => highlightedIndices.includes(index) ? setHoveredIndex(index) : null} onMouseEnter={() => (highlightedIndices.includes(index) && !removedCircles.has(index)) ? setHoveredIndex(index) : null}
onMouseLeave={() => setHoveredIndex(null)} onMouseLeave={() => setHoveredIndex(null)}
title={highlightedIndices.includes(index) ? 'Click to select' : 'Not selectable'} title={highlightedIndices.includes(index) ? 'Click to select' : 'Not selectable'}
/> />
@ -193,7 +213,7 @@ const SubtractionGame = () => {
{circles.length > 0 && ( {circles.length > 0 && (
<div className="text-center mt-6"> <div className="text-center mt-6">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{highlightedIndices.length} circle(s) highlighted Last {Math.min(k[0], circles.length)} positions {highlightedIndices.length} circle(s) highlighted Last {Math.min(k[0], circles.filter(i => !removedCircles.has(i)).length)} positions
</p> </p>
</div> </div>
)} )}