|
|
@@ -1,4 +1,4 @@
|
|
|
-import type { GameStats, SolverReplay } from '@wordle/shared';
|
|
|
+import type { GameStats, SolverReplay, GuessEntry } from '@wordle/shared';
|
|
|
import { getMessages } from '../messages/index.js';
|
|
|
import { LangSwitch } from '../components/LangSwitch.js';
|
|
|
|
|
|
@@ -6,6 +6,7 @@ interface Screen3ResultsProps {
|
|
|
won: boolean;
|
|
|
attemptCount: number;
|
|
|
revealedWord: string | null;
|
|
|
+ guesses: GuessEntry[];
|
|
|
stats: GameStats;
|
|
|
replays?: SolverReplay[];
|
|
|
onPlayAgain?: () => void;
|
|
|
@@ -46,6 +47,34 @@ function computeFeedback(target: string, guess: string): string[] {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+/** Read-only mini grid showing the player's guesses with their feedback colors. */
|
|
|
+function GameGrid({ guesses }: { guesses: GuessEntry[] }) {
|
|
|
+ return (
|
|
|
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '2px', alignItems: 'center' }}>
|
|
|
+ {guesses.map((entry, rowIdx) => (
|
|
|
+ <div key={rowIdx} style={{ display: 'flex', gap: '2px' }}>
|
|
|
+ {entry.guess.split('').map((letter, colIdx) => {
|
|
|
+ const c = entry.colors[colIdx];
|
|
|
+ return (
|
|
|
+ <div key={colIdx} style={{
|
|
|
+ width: '20px', height: '20px',
|
|
|
+ backgroundColor: MINI_COLORS[c] ?? '#d3d6da',
|
|
|
+ color: '#fff',
|
|
|
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
|
+ fontSize: '0.55rem', fontWeight: 'bold',
|
|
|
+ textTransform: 'uppercase', fontFamily: 'monospace',
|
|
|
+ borderRadius: '2px',
|
|
|
+ }}>
|
|
|
+ {letter}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
function MiniBoard({ replay, targetWord }: { replay: SolverReplay; targetWord: string }) {
|
|
|
return (
|
|
|
<div style={{ marginBottom: '12px' }}>
|
|
|
@@ -103,15 +132,17 @@ function Histogram({ stats }: { stats: GameStats }) {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
-export function Screen3Results({ won, attemptCount, revealedWord, stats, replays, onPlayAgain }: Screen3ResultsProps) {
|
|
|
+export function Screen3Results({ won, attemptCount, revealedWord, guesses, stats, replays, onPlayAgain }: Screen3ResultsProps) {
|
|
|
const r = getMessages().results;
|
|
|
|
|
|
return (
|
|
|
- <div style={{ maxWidth: '400px', margin: '24px auto', padding: '16px', fontFamily: 'sans-serif', textAlign: 'center', position: 'relative' }}>
|
|
|
- <LangSwitch />
|
|
|
- <h1 style={{ fontSize: '1.6rem', marginBottom: '12px' }}>
|
|
|
- {won ? r.congratulations : r.betterLuck}
|
|
|
- </h1>
|
|
|
+ <div style={{ maxWidth: '400px', margin: '24px auto', padding: '16px', fontFamily: 'sans-serif', textAlign: 'center' }}>
|
|
|
+ <div style={{ display: 'flex', alignItems: 'center', marginBottom: '12px' }}>
|
|
|
+ <h1 style={{ flex: 1, textAlign: 'center', fontSize: '1.6rem', margin: 0 }}>
|
|
|
+ {won ? r.congratulations : r.betterLuck}
|
|
|
+ </h1>
|
|
|
+ <LangSwitch inline />
|
|
|
+ </div>
|
|
|
|
|
|
{won ? (
|
|
|
<p style={{ fontSize: '1.1rem', marginBottom: '8px' }}>{r.solvedIn(attemptCount)}</p>
|
|
|
@@ -119,16 +150,12 @@ export function Screen3Results({ won, attemptCount, revealedWord, stats, replays
|
|
|
revealedWord && <p style={{ fontSize: '1.1rem', marginBottom: '8px' }}>{r.theWordWas(revealedWord)}</p>
|
|
|
)}
|
|
|
|
|
|
- <div style={{ margin: '24px 0' }}>
|
|
|
- <h2 style={{ fontSize: '1.1rem', marginBottom: '12px' }}>{r.statistics}</h2>
|
|
|
- <div style={{ display: 'flex', justifyContent: 'center', gap: '24px', marginBottom: '16px' }}>
|
|
|
- <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.played}</div></div>
|
|
|
- <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed > 0 ? Math.round((stats.wins / stats.gamesPlayed) * 100) : 0}%</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.winRate}</div></div>
|
|
|
- <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.currentStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.streak}</div></div>
|
|
|
- <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.maxStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.maxStreak}</div></div>
|
|
|
+ {/* Game grid — read-only replay of the guesses */}
|
|
|
+ {guesses.length > 0 && (
|
|
|
+ <div style={{ margin: '16px 0' }}>
|
|
|
+ <GameGrid guesses={guesses} />
|
|
|
</div>
|
|
|
- <Histogram stats={stats} />
|
|
|
- </div>
|
|
|
+ )}
|
|
|
|
|
|
{replays && replays.length > 0 && revealedWord && (
|
|
|
<div style={{ margin: '24px 0' }}>
|
|
|
@@ -162,6 +189,18 @@ export function Screen3Results({ won, attemptCount, revealedWord, stats, replays
|
|
|
{r.playAgain}
|
|
|
</button>
|
|
|
)}
|
|
|
+
|
|
|
+ {/* Statistics — at the very bottom */}
|
|
|
+ <div style={{ margin: '24px 0' }}>
|
|
|
+ <h2 style={{ fontSize: '1.1rem', marginBottom: '12px' }}>{r.statistics}</h2>
|
|
|
+ <div style={{ display: 'flex', justifyContent: 'center', gap: '24px', marginBottom: '16px' }}>
|
|
|
+ <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.played}</div></div>
|
|
|
+ <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed > 0 ? Math.round((stats.wins / stats.gamesPlayed) * 100) : 0}%</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.winRate}</div></div>
|
|
|
+ <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.currentStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.streak}</div></div>
|
|
|
+ <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.maxStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>{r.maxStreak}</div></div>
|
|
|
+ </div>
|
|
|
+ <Histogram stats={stats} />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
);
|
|
|
}
|