Update pebble game rules

Allow the user to continue playing the pebble game as long as there are removable pebbles. The pebble at position 1 is always considered removable.
This commit is contained in:
gpt-engineer-app[bot] 2025-08-21 10:47:57 +00:00
parent 8917e1a66f
commit d57837d286

View file

@ -51,41 +51,43 @@ const PebblePlacementGame: React.FC<PebblePlacementGameProps> = ({ showSocialSha
}; };
const canRemovePebble = (position: number): boolean => { const canRemovePebble = (position: number): boolean => {
// Can only remove if pebble is placed and predecessor has pebble (or position 1) // Can only remove if pebble is placed
if (!placedPebbles.has(position)) return false; if (!placedPebbles.has(position)) return false;
// Position 1 is always removable
if (position === 1) return true; if (position === 1) return true;
// For other positions, predecessor must have pebble
return placedPebbles.has(position - 1); return placedPebbles.has(position - 1);
}; };
const hasAnyRemovablePebble = (): boolean => {
return Array.from(placedPebbles).some(pos => canRemovePebble(pos));
};
const handlePositionClick = (position: number) => { const handlePositionClick = (position: number) => {
if (!gameStarted) return; if (!gameStarted) return;
const newPlacedPebbles = new Set(placedPebbles);
if (placedPebbles.has(position)) { if (placedPebbles.has(position)) {
// Try to remove pebble // Try to remove pebble
if (canRemovePebble(position)) { if (canRemovePebble(position)) {
// Check if removing this pebble would make any later pebbles invalid const newPlacedPebbles = new Set(placedPebbles);
const pebblesAfter = Array.from(placedPebbles).filter(p => p > position); newPlacedPebbles.delete(position);
let canRemove = true;
for (const laterPebble of pebblesAfter) { // Cascade removal: remove any pebbles that become invalid
if (laterPebble === position + 1) { const sortedPebbles = Array.from(newPlacedPebbles).sort((a, b) => a - b);
// Direct successor would become invalid for (const pebblePos of sortedPebbles) {
canRemove = false; if (pebblePos > 1 && !newPlacedPebbles.has(pebblePos - 1)) {
break; newPlacedPebbles.delete(pebblePos);
} }
} }
if (canRemove) { const pebblesRemoved = placedPebbles.size - newPlacedPebbles.size;
newPlacedPebbles.delete(position); setPlacedPebbles(newPlacedPebbles);
setPlacedPebbles(newPlacedPebbles); setPebblesInHand(pebblesInHand + pebblesRemoved);
setPebblesInHand(pebblesInHand + 1);
}
} }
} else { } else {
// Try to place pebble // Try to place pebble
if (pebblesInHand > 0 && canPlacePebble(position)) { if (pebblesInHand > 0 && canPlacePebble(position)) {
const newPlacedPebbles = new Set(placedPebbles);
newPlacedPebbles.add(position); newPlacedPebbles.add(position);
setPlacedPebbles(newPlacedPebbles); setPlacedPebbles(newPlacedPebbles);
setPebblesInHand(pebblesInHand - 1); setPebblesInHand(pebblesInHand - 1);
@ -168,6 +170,8 @@ const PebblePlacementGame: React.FC<PebblePlacementGameProps> = ({ showSocialSha
<li> You can always place a pebble on position 1</li> <li> You can always place a pebble on position 1</li>
<li> You can place a pebble on position i only if position (i-1) has a pebble</li> <li> You can place a pebble on position i only if position (i-1) has a pebble</li>
<li> You can remove a pebble from position i only if position (i-1) has a pebble</li> <li> You can remove a pebble from position i only if position (i-1) has a pebble</li>
<li> The pebble on position 1 is always removable</li>
<li> Removing a pebble may cascade and remove other pebbles that become invalid</li>
<li> Goal: Place a pebble on the largest possible position</li> <li> Goal: Place a pebble on the largest possible position</li>
</ul> </ul>
</div> </div>
@ -218,9 +222,15 @@ const PebblePlacementGame: React.FC<PebblePlacementGameProps> = ({ showSocialSha
<p className="text-muted-foreground"> <p className="text-muted-foreground">
Your furthest position: <span className="font-semibold text-foreground">{furthestReached}</span> Your furthest position: <span className="font-semibold text-foreground">{furthestReached}</span>
</p> </p>
<p className="text-sm text-muted-foreground mt-2"> {hasAnyRemovablePebble() ? (
Can you rearrange your pebbles to reach even further? <p className="text-sm text-muted-foreground mt-2">
</p> You can still rearrange your pebbles to try reaching further!
</p>
) : (
<p className="text-sm text-muted-foreground mt-2">
No more moves possible - great job!
</p>
)}
</div> </div>
)} )}
</CardContent> </CardContent>