Add pause functionality to Bulgarian Solitaire
Update the "Playing..." button to "Pause". When clicked, the simulation will pause and the button text will change to "Continue", allowing the user to resume or reset the game.
This commit is contained in:
parent
64f864efed
commit
a1945611ef
1 changed files with 31 additions and 7 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Slider } from '@/components/ui/slider';
|
||||
import SocialShare from '@/components/SocialShare';
|
||||
|
|
@ -18,6 +18,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
const [boxes, setBoxes] = useState<Box[]>([]);
|
||||
const [columns, setColumns] = useState<number[][]>([]);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [isPaused, setIsPaused] = useState(false);
|
||||
const [draggedBox, setDraggedBox] = useState<number | null>(null);
|
||||
const [step, setStep] = useState(0);
|
||||
const [isComplete, setIsComplete] = useState(false);
|
||||
|
|
@ -27,6 +28,8 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
const [selectedBoxForMove, setSelectedBoxForMove] = useState<number | null>(null);
|
||||
const [showInstructions, setShowInstructions] = useState(false);
|
||||
|
||||
const pauseRef = useRef(false);
|
||||
|
||||
const totalBoxes = n;
|
||||
|
||||
// Initialize boxes and columns when n changes
|
||||
|
|
@ -173,6 +176,22 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
|
||||
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
const waitForUnpause = async () => {
|
||||
while (pauseRef.current) {
|
||||
await sleep(100);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePause = () => {
|
||||
pauseRef.current = true;
|
||||
setIsPaused(true);
|
||||
};
|
||||
|
||||
const handleResume = () => {
|
||||
pauseRef.current = false;
|
||||
setIsPaused(false);
|
||||
};
|
||||
|
||||
const isTriangularConfiguration = (cols: number[][]) => {
|
||||
const nonEmptyCols = cols.filter(col => col.length > 0).sort((a, b) => a.length - b.length);
|
||||
|
||||
|
|
@ -215,6 +234,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
setHighlightedBoxes(topBoxes);
|
||||
setIsAnimating(true);
|
||||
await sleep(800); // Show highlighting
|
||||
await waitForUnpause(); // Check for pause
|
||||
|
||||
// Create new pile from non-empty columns
|
||||
const newPile: number[] = [];
|
||||
|
|
@ -265,6 +285,7 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
}));
|
||||
|
||||
await sleep(1200); // Wait to see the sorted result
|
||||
await waitForUnpause(); // Check for pause again
|
||||
}
|
||||
|
||||
setIsComplete(isTriangularConfiguration(currentColumns));
|
||||
|
|
@ -278,6 +299,10 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
};
|
||||
|
||||
const reset = () => {
|
||||
pauseRef.current = false;
|
||||
setIsPaused(false);
|
||||
setIsPlaying(false);
|
||||
|
||||
const newBoxes: Box[] = [];
|
||||
for (let i = 0; i < totalBoxes; i++) {
|
||||
newBoxes.push({ id: i, columnIndex: null });
|
||||
|
|
@ -286,7 +311,6 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
setColumns(Array.from({ length: totalBoxes }, () => []));
|
||||
setStep(0);
|
||||
setIsComplete(false);
|
||||
setIsPlaying(false);
|
||||
setHighlightedBoxes(new Set());
|
||||
setIsAnimating(false);
|
||||
};
|
||||
|
|
@ -347,10 +371,10 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
disabled={isPlaying}
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={reset} variant="outline" disabled={isPlaying}>
|
||||
<Button onClick={reset} variant="outline" disabled={isPlaying && !isPaused}>
|
||||
Reset
|
||||
</Button>
|
||||
<Button onClick={randomStart} variant="default" disabled={isPlaying}>
|
||||
<Button onClick={randomStart} variant="default" disabled={isPlaying && !isPaused}>
|
||||
Random Start
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -428,12 +452,12 @@ const BulgarianSolitaire: React.FC<BulgarianSolitaireProps> = ({ showSocialShare
|
|||
{/* Play Button */}
|
||||
<div className="flex justify-center">
|
||||
<Button
|
||||
onClick={simulateBulgarianSolitaire}
|
||||
disabled={isPlaying || containerBoxes.length > 0}
|
||||
onClick={isPlaying ? (isPaused ? handleResume : handlePause) : simulateBulgarianSolitaire}
|
||||
disabled={!isPlaying && containerBoxes.length > 0}
|
||||
size="lg"
|
||||
className="px-12"
|
||||
>
|
||||
{isPlaying ? 'Playing...' : 'Play'}
|
||||
{isPlaying ? (isPaused ? 'Continue' : 'Pause') : 'Play'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue