Enhance Gold Coin Game: add deselect functionality, prevent moves to occupied cells, improve instructions, add randomized board generation, and prevent interactions before game start
This commit is contained in:
parent
4f27765251
commit
99482e4314
1 changed files with 166 additions and 101 deletions
|
|
@ -3,11 +3,11 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/com
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { ArrowLeft, ArrowRight, Crown, Circle } from 'lucide-react';
|
import { Crown, Circle, RotateCcw, BookOpen, Trophy } from 'lucide-react';
|
||||||
import SocialShare from '@/components/SocialShare';
|
import SocialShare from '@/components/SocialShare';
|
||||||
|
|
||||||
type Player = 0 | 1;
|
type Player = 0 | 1;
|
||||||
type CellState = 'empty' | 'penny' | 'gold' | 'gold-prev';
|
type CellState = 'empty' | 'penny' | 'gold';
|
||||||
|
|
||||||
interface GameState {
|
interface GameState {
|
||||||
track: CellState[];
|
track: CellState[];
|
||||||
|
|
@ -20,7 +20,7 @@ interface GameState {
|
||||||
|
|
||||||
const GoldCoinGame: React.FC = () => {
|
const GoldCoinGame: React.FC = () => {
|
||||||
const [gameState, setGameState] = useState<GameState>({
|
const [gameState, setGameState] = useState<GameState>({
|
||||||
track: ['empty', 'penny', 'empty', 'penny', 'empty', 'penny', 'empty', 'gold', 'empty', 'empty', 'empty'],
|
track: Array(15).fill('empty'),
|
||||||
currentPlayer: 0,
|
currentPlayer: 0,
|
||||||
winner: null,
|
winner: null,
|
||||||
gameStarted: false,
|
gameStarted: false,
|
||||||
|
|
@ -34,9 +34,31 @@ const GoldCoinGame: React.FC = () => {
|
||||||
const playerNames = ['Player 1', 'Player 2'];
|
const playerNames = ['Player 1', 'Player 2'];
|
||||||
const playerColors = ['#3b82f6', '#ef4444'];
|
const playerColors = ['#3b82f6', '#ef4444'];
|
||||||
|
|
||||||
|
const generateRandomBoard = (): CellState[] => {
|
||||||
|
const track = Array(15).fill('empty') as CellState[];
|
||||||
|
|
||||||
|
// Always place the gold coin at position 7-14 (random)
|
||||||
|
const goldPosition = Math.floor(Math.random() * 8) + 7;
|
||||||
|
track[goldPosition] = 'gold';
|
||||||
|
|
||||||
|
// Place 3-5 pennies randomly in positions 0-6
|
||||||
|
const numPennies = Math.floor(Math.random() * 3) + 3; // 3-5 pennies
|
||||||
|
const availablePositions = Array.from({length: 7}, (_, i) => i); // positions 0-6
|
||||||
|
|
||||||
|
for (let i = 0; i < numPennies; i++) {
|
||||||
|
if (availablePositions.length > 0) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * availablePositions.length);
|
||||||
|
const position = availablePositions.splice(randomIndex, 1)[0];
|
||||||
|
track[position] = 'penny';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return track;
|
||||||
|
};
|
||||||
|
|
||||||
const initializeGame = () => {
|
const initializeGame = () => {
|
||||||
setGameState({
|
setGameState({
|
||||||
track: ['empty', 'penny', 'empty', 'penny', 'empty', 'penny', 'empty', 'gold', 'empty', 'empty', 'empty'],
|
track: generateRandomBoard(),
|
||||||
currentPlayer: 0,
|
currentPlayer: 0,
|
||||||
winner: null,
|
winner: null,
|
||||||
gameStarted: true,
|
gameStarted: true,
|
||||||
|
|
@ -47,7 +69,7 @@ const GoldCoinGame: React.FC = () => {
|
||||||
|
|
||||||
const resetGame = () => {
|
const resetGame = () => {
|
||||||
setGameState({
|
setGameState({
|
||||||
track: ['empty', 'penny', 'empty', 'penny', 'empty', 'penny', 'empty', 'gold', 'empty', 'empty', 'empty'],
|
track: Array(15).fill('empty'),
|
||||||
currentPlayer: 0,
|
currentPlayer: 0,
|
||||||
winner: null,
|
winner: null,
|
||||||
gameStarted: false,
|
gameStarted: false,
|
||||||
|
|
@ -60,6 +82,7 @@ const GoldCoinGame: React.FC = () => {
|
||||||
const canMoveCoin = (fromIndex: number, toIndex: number): boolean => {
|
const canMoveCoin = (fromIndex: number, toIndex: number): boolean => {
|
||||||
if (fromIndex <= toIndex) return false; // Can only move left
|
if (fromIndex <= toIndex) return false; // Can only move left
|
||||||
if (toIndex < 0) return false; // Can't move off the track
|
if (toIndex < 0) return false; // Can't move off the track
|
||||||
|
if (gameState.track[toIndex] !== 'empty') return false; // Can't move to a position with a coin
|
||||||
|
|
||||||
// Check if there are any coins in the way
|
// Check if there are any coins in the way
|
||||||
for (let i = toIndex + 1; i < fromIndex; i++) {
|
for (let i = toIndex + 1; i < fromIndex; i++) {
|
||||||
|
|
@ -81,13 +104,32 @@ const GoldCoinGame: React.FC = () => {
|
||||||
return gameState.track[index] !== 'empty';
|
return gameState.track[index] !== 'empty';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getValidMovePositions = (fromIndex: number): number[] => {
|
||||||
|
const validPositions: number[] = [];
|
||||||
|
for (let i = 0; i < fromIndex; i++) {
|
||||||
|
if (canMoveCoin(fromIndex, i)) {
|
||||||
|
validPositions.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return validPositions;
|
||||||
|
};
|
||||||
|
|
||||||
const handleCellClick = (index: number) => {
|
const handleCellClick = (index: number) => {
|
||||||
if (gameState.winner !== null) return;
|
if (gameState.winner !== null || !gameState.gameStarted) return;
|
||||||
|
|
||||||
const cellState = gameState.track[index];
|
const cellState = gameState.track[index];
|
||||||
|
|
||||||
// If a coin is selected, try to move it
|
// If a coin is selected, try to move it
|
||||||
if (gameState.selectedCoin !== null) {
|
if (gameState.selectedCoin !== null) {
|
||||||
|
// If clicking on the same coin, deselect it
|
||||||
|
if (gameState.selectedCoin === index) {
|
||||||
|
setGameState(prev => ({
|
||||||
|
...prev,
|
||||||
|
selectedCoin: null
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (canMoveCoin(gameState.selectedCoin, index)) {
|
if (canMoveCoin(gameState.selectedCoin, index)) {
|
||||||
const newTrack = [...gameState.track];
|
const newTrack = [...gameState.track];
|
||||||
newTrack[index] = newTrack[gameState.selectedCoin];
|
newTrack[index] = newTrack[gameState.selectedCoin];
|
||||||
|
|
@ -115,15 +157,15 @@ const GoldCoinGame: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTakeCoin = (index: number) => {
|
const handleTakeCoin = () => {
|
||||||
if (gameState.winner !== null) return;
|
if (gameState.winner !== null || !gameState.gameStarted || gameState.selectedCoin === null) return;
|
||||||
if (!canTakeCoin(index)) return;
|
if (!canTakeCoin(gameState.selectedCoin)) return;
|
||||||
|
|
||||||
const cellState = gameState.track[index];
|
const cellState = gameState.track[gameState.selectedCoin];
|
||||||
const newTrack = [...gameState.track];
|
const newTrack = [...gameState.track];
|
||||||
newTrack[index] = 'empty';
|
newTrack[gameState.selectedCoin] = 'empty';
|
||||||
|
|
||||||
const moveDescription = `Player ${gameState.currentPlayer + 1} took ${cellState === 'gold' ? 'gold coin' : 'penny'} from position ${index + 1}`;
|
const moveDescription = `Player ${gameState.currentPlayer + 1} took ${cellState === 'gold' ? 'gold coin' : 'penny'} from position ${gameState.selectedCoin + 1}`;
|
||||||
|
|
||||||
// Check if this is a winning move
|
// Check if this is a winning move
|
||||||
const isWinningMove = cellState === 'gold';
|
const isWinningMove = cellState === 'gold';
|
||||||
|
|
@ -144,106 +186,98 @@ const GoldCoinGame: React.FC = () => {
|
||||||
|
|
||||||
const renderCell = (cellState: CellState, index: number) => {
|
const renderCell = (cellState: CellState, index: number) => {
|
||||||
const isSelected = gameState.selectedCoin === index;
|
const isSelected = gameState.selectedCoin === index;
|
||||||
const canTake = canTakeCoin(index);
|
const validPositions = gameState.selectedCoin !== null ? getValidMovePositions(gameState.selectedCoin) : [];
|
||||||
const isClickable = cellState !== 'empty' || gameState.selectedCoin !== null;
|
const isValidMoveTarget = validPositions.includes(index);
|
||||||
|
const isClickable = gameState.gameStarted && (cellState !== 'empty' || gameState.selectedCoin !== null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`
|
className={`
|
||||||
relative w-12 h-12 border-2 border-gray-300 rounded-lg flex items-center justify-center cursor-pointer
|
relative w-14 h-14 border-2 rounded-lg flex items-center justify-center cursor-pointer
|
||||||
transition-all duration-200 hover:scale-105
|
transition-all duration-200 hover:scale-105 shadow-sm
|
||||||
${isSelected ? 'border-blue-500 bg-blue-50' : ''}
|
${isSelected ? 'border-blue-500 bg-blue-50 shadow-md' : 'border-gray-300 bg-white'}
|
||||||
${canTake && cellState !== 'empty' ? 'border-green-500 bg-green-50' : ''}
|
${isValidMoveTarget ? 'border-green-400 bg-green-50 shadow-md' : ''}
|
||||||
${!isClickable ? 'cursor-default hover:scale-100' : ''}
|
${!isClickable ? 'cursor-default hover:scale-100' : 'hover:shadow-md'}
|
||||||
`}
|
`}
|
||||||
onClick={() => handleCellClick(index)}
|
onClick={() => handleCellClick(index)}
|
||||||
>
|
>
|
||||||
{cellState === 'gold' && (
|
{cellState === 'gold' && (
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
<Crown className="w-6 h-6 text-yellow-500" />
|
<Crown className="w-7 h-7 text-yellow-500 drop-shadow-sm" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{cellState === 'penny' && (
|
{cellState === 'penny' && (
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
<Circle className="w-6 h-6 text-orange-500 fill-orange-500" />
|
<Circle className="w-7 h-7 text-orange-500 fill-orange-500 drop-shadow-sm" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{cellState === 'gold-prev' && (
|
<div className="absolute -bottom-7 text-xs text-gray-500 font-mono font-medium">
|
||||||
<div className="flex items-center justify-center opacity-50">
|
|
||||||
<Crown className="w-6 h-6 text-yellow-500" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="absolute -bottom-6 text-xs text-gray-500 font-mono">
|
|
||||||
{index + 1}
|
{index + 1}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderTakeButton = (index: number) => {
|
const getLeftmostCoin = (): { index: number; type: string } | null => {
|
||||||
const canTake = canTakeCoin(index);
|
for (let i = 0; i < gameState.track.length; i++) {
|
||||||
const cellState = gameState.track[index];
|
if (gameState.track[i] !== 'empty') {
|
||||||
|
return { index: i, type: gameState.track[i] };
|
||||||
if (!canTake || cellState === 'empty') return null;
|
}
|
||||||
|
}
|
||||||
return (
|
return null;
|
||||||
<Button
|
|
||||||
key={`take-${index}`}
|
|
||||||
size="sm"
|
|
||||||
variant="outline"
|
|
||||||
className="mt-2 text-xs"
|
|
||||||
onClick={() => handleTakeCoin(index)}
|
|
||||||
>
|
|
||||||
Take {cellState === 'gold' ? 'Gold' : 'Penny'}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const leftmostCoin = getLeftmostCoin();
|
||||||
|
const canTakeSelectedCoin = gameState.selectedCoin !== null && canTakeCoin(gameState.selectedCoin);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-4xl mx-auto p-6 space-y-6">
|
<div className="max-w-6xl mx-auto p-6 space-y-6">
|
||||||
<Card>
|
<Card className="shadow-lg">
|
||||||
<CardHeader>
|
<CardHeader className="text-center pb-6">
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center justify-center gap-3 text-3xl">
|
||||||
<Crown className="w-6 h-6 text-yellow-500" />
|
<Crown className="w-8 h-8 text-yellow-500" />
|
||||||
The Gold Coin Game
|
The Gold Coin Game
|
||||||
|
<Crown className="w-8 h-8 text-yellow-500" />
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription className="text-lg max-w-2xl mx-auto">
|
||||||
A two-player strategy game. Move coins to the left or take the leftmost coin.
|
A strategic two-player game where you move coins to the left or take the leftmost coin.
|
||||||
The player who takes the gold coin wins!
|
The player who takes the gold coin wins!
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-6">
|
<CardContent className="space-y-8">
|
||||||
{/* Game Controls */}
|
{/* Game Controls */}
|
||||||
<div className="flex gap-4">
|
<div className="flex justify-center gap-4">
|
||||||
{!gameState.gameStarted ? (
|
{!gameState.gameStarted ? (
|
||||||
<Button onClick={initializeGame} className="flex-1">
|
<Button onClick={initializeGame} size="lg" className="px-8">
|
||||||
Start Game
|
Start Game
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button onClick={resetGame} variant="outline">
|
<Button onClick={resetGame} variant="outline" size="lg" className="px-8">
|
||||||
|
<RotateCcw className="w-4 h-4 mr-2" />
|
||||||
Reset Game
|
Reset Game
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button onClick={() => setShowRules(true)} variant="outline">
|
<Button onClick={() => setShowRules(true)} variant="outline" size="lg" className="px-8">
|
||||||
|
<BookOpen className="w-4 h-4 mr-2" />
|
||||||
Rules
|
Rules
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Game Status */}
|
{/* Game Status */}
|
||||||
{gameState.gameStarted && (
|
{gameState.gameStarted && (
|
||||||
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
<div className="flex flex-col sm:flex-row items-center justify-between p-6 bg-gradient-to-r from-blue-50 to-purple-50 rounded-xl border">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4 mb-4 sm:mb-0">
|
||||||
<span className="font-medium">Current Player:</span>
|
<span className="font-semibold text-lg">Current Player:</span>
|
||||||
<Badge
|
<Badge
|
||||||
style={{ backgroundColor: playerColors[gameState.currentPlayer] }}
|
style={{ backgroundColor: playerColors[gameState.currentPlayer] }}
|
||||||
className="text-white"
|
className="text-white text-lg px-4 py-2"
|
||||||
>
|
>
|
||||||
{playerNames[gameState.currentPlayer]}
|
{playerNames[gameState.currentPlayer]}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
{gameState.selectedCoin !== null && (
|
{gameState.selectedCoin !== null && (
|
||||||
<div className="text-sm text-blue-600">
|
<div className="text-sm text-blue-700 bg-blue-100 px-4 py-2 rounded-lg font-medium">
|
||||||
Selected coin at position {gameState.selectedCoin + 1}. Click a position to move it.
|
Selected coin at position {gameState.selectedCoin + 1}. Click a position to move it.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -251,35 +285,59 @@ const GoldCoinGame: React.FC = () => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Game Board */}
|
{/* Game Board */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-6">
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<div className="flex gap-2 items-end">
|
<div className="bg-gray-100 p-8 rounded-2xl shadow-inner">
|
||||||
{gameState.track.map((cellState, index) => (
|
<div className="flex gap-3 items-end">
|
||||||
<div key={index} className="flex flex-col items-center">
|
{gameState.track.map((cellState, index) => (
|
||||||
{renderCell(cellState, index)}
|
<div key={index} className="flex flex-col items-center">
|
||||||
{renderTakeButton(index)}
|
{renderCell(cellState, index)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Instructions */}
|
{/* Instructions */}
|
||||||
<div className="text-center text-sm text-gray-600">
|
<div className="text-center">
|
||||||
{gameState.selectedCoin !== null ? (
|
<div className="inline-block bg-gray-50 px-6 py-3 rounded-lg border">
|
||||||
<p>Click a position to move the selected coin, or click "Take" to collect a coin</p>
|
<p className="text-sm text-gray-700 font-medium">
|
||||||
) : (
|
{!gameState.gameStarted ? (
|
||||||
<p>Click on a coin to select it, then click a position to move it left, or click "Take" to collect the leftmost coin</p>
|
"Click 'Start Game' to begin with a randomized board"
|
||||||
)}
|
) : gameState.selectedCoin !== null ? (
|
||||||
|
canTakeSelectedCoin ? (
|
||||||
|
"Use the take button below to remove this coin"
|
||||||
|
) : (
|
||||||
|
"Click a highlighted position to move the selected coin"
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
"Click on a coin to select it, then click a position to move it left, or take the leftmost coin"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Take Coin Button */}
|
||||||
|
{canTakeSelectedCoin && (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Button
|
||||||
|
onClick={handleTakeCoin}
|
||||||
|
size="lg"
|
||||||
|
className="bg-green-600 hover:bg-green-700 text-white px-8"
|
||||||
|
>
|
||||||
|
Take {gameState.track[gameState.selectedCoin!] === 'gold' ? 'Gold Coin' : 'Penny'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Move History */}
|
{/* Move History */}
|
||||||
{gameState.moveHistory.length > 0 && (
|
{gameState.moveHistory.length > 0 && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-3">
|
||||||
<h3 className="font-medium">Move History</h3>
|
<h3 className="font-semibold text-lg text-center">Move History</h3>
|
||||||
<div className="max-h-32 overflow-y-auto space-y-1">
|
<div className="max-h-40 overflow-y-auto space-y-2 bg-gray-50 p-4 rounded-lg">
|
||||||
{gameState.moveHistory.map((move, index) => (
|
{gameState.moveHistory.map((move, index) => (
|
||||||
<div key={index} className="text-sm text-gray-600 bg-gray-50 p-2 rounded">
|
<div key={index} className="text-sm text-gray-700 bg-white p-3 rounded border-l-4 border-blue-500">
|
||||||
{move}
|
{move}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -291,42 +349,46 @@ const GoldCoinGame: React.FC = () => {
|
||||||
|
|
||||||
{/* Rules Dialog */}
|
{/* Rules Dialog */}
|
||||||
<Dialog open={showRules} onOpenChange={setShowRules}>
|
<Dialog open={showRules} onOpenChange={setShowRules}>
|
||||||
<DialogContent className="max-w-2xl">
|
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>The Gold Coin Game Rules</DialogTitle>
|
<DialogTitle className="flex items-center gap-2">
|
||||||
|
<BookOpen className="w-5 h-5" />
|
||||||
|
The Gold Coin Game Rules
|
||||||
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4 text-sm">
|
<div className="space-y-6 text-sm">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-medium mb-2">Objective</h4>
|
<h4 className="font-semibold mb-2 text-lg">Objective</h4>
|
||||||
<p>Be the first player to acquire the gold coin and win the game!</p>
|
<p className="text-gray-700">Be the first player to acquire the gold coin and win the game!</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-medium mb-2">Setup</h4>
|
<h4 className="font-semibold mb-2 text-lg">Setup</h4>
|
||||||
<p>The game starts with coins placed on a track. The gold coin is positioned farthest to the right.</p>
|
<p className="text-gray-700">The game starts with coins placed on a 15-position track. The gold coin is positioned farthest to the right.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-medium mb-2">On Your Turn</h4>
|
<h4 className="font-semibold mb-2 text-lg">On Your Turn</h4>
|
||||||
<p>You have two options:</p>
|
<p className="text-gray-700 mb-3">You have two options:</p>
|
||||||
<ol className="list-decimal list-inside space-y-1 ml-4">
|
<ol className="list-decimal list-inside space-y-2 ml-4 text-gray-700">
|
||||||
<li><strong>Move a coin:</strong> Move any coin to the left by one or more spaces. A coin cannot jump over another coin.</li>
|
<li><strong>Move a coin:</strong> Move any coin to the left by one or more spaces. A coin cannot jump over another coin.</li>
|
||||||
<li><strong>Take a coin:</strong> Take the leftmost coin on the track into your possession.</li>
|
<li><strong>Take a coin:</strong> Take the leftmost coin on the track into your possession.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-medium mb-2">Winning</h4>
|
<h4 className="font-semibold mb-2 text-lg">Winning</h4>
|
||||||
<p>The player who successfully takes the gold coin is declared the winner!</p>
|
<p className="text-gray-700">The player who successfully takes the gold coin is declared the winner!</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-medium mb-2">Strategy Tips</h4>
|
<h4 className="font-semibold mb-2 text-lg">Strategy Tips</h4>
|
||||||
<ul className="list-disc list-inside space-y-1 ml-4">
|
<ul className="list-disc list-inside space-y-2 ml-4 text-gray-700">
|
||||||
<li>Try to control the position of the gold coin</li>
|
<li>Try to control the position of the gold coin</li>
|
||||||
<li>Use pennies to block your opponent's moves</li>
|
<li>Use pennies to block your opponent's moves</li>
|
||||||
<li>Plan several moves ahead</li>
|
<li>Plan several moves ahead</li>
|
||||||
<li>Don't always take the first available coin</li>
|
<li>Don't always take the first available coin</li>
|
||||||
|
<li>Consider the spacing between coins carefully</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -335,21 +397,24 @@ const GoldCoinGame: React.FC = () => {
|
||||||
|
|
||||||
{/* Game Over Dialog */}
|
{/* Game Over Dialog */}
|
||||||
<Dialog open={showGameOver} onOpenChange={setShowGameOver}>
|
<Dialog open={showGameOver} onOpenChange={setShowGameOver}>
|
||||||
<DialogContent>
|
<DialogContent className="max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Game Over!</DialogTitle>
|
<DialogTitle className="flex items-center justify-center gap-2">
|
||||||
|
<Trophy className="w-6 h-6 text-yellow-500" />
|
||||||
|
Game Over!
|
||||||
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="text-center space-y-4">
|
<div className="text-center space-y-6">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-3">
|
||||||
<Crown className="w-8 h-8 text-yellow-500" />
|
<Crown className="w-10 h-10 text-yellow-500" />
|
||||||
<span className="text-xl font-bold">
|
<span className="text-2xl font-bold text-green-600">
|
||||||
{playerNames[gameState.winner!]} wins!
|
{playerNames[gameState.winner!]} wins!
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-gray-600">
|
<p className="text-gray-600 text-lg">
|
||||||
Congratulations! {playerNames[gameState.winner!]} successfully acquired the gold coin.
|
Congratulations! {playerNames[gameState.winner!]} successfully acquired the gold coin.
|
||||||
</p>
|
</p>
|
||||||
<Button onClick={resetGame} className="w-full">
|
<Button onClick={resetGame} className="w-full" size="lg">
|
||||||
Play Again
|
Play Again
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue