anvilsign in

collin/mahjong

1import type { CSSProperties } from 'react';
2import type { GameState } from '../game/engine';
3
4/**
5 * How long the gold takes to run out. Nothing happens when it does — no tile is
6 * thrown for you, no seat is skipped, no move is forced. It is a table telling
7 * three people who are watching and one who is not that the game is on them,
8 * and seven seconds is about as long as a turn takes when somebody is paying
9 * attention to it.
10 */
11export const TURN_SECONDS = 7;
12
13/**
14 * One turn, told apart from the next. The clock is a CSS animation, and the
15 * only way to start one over is to hand React a different element — so this
16 * goes in the `key` and a new turn gets a full seven seconds.
17 *
18 * A turn begins in one of two ways: somebody drew (`drawnFront`/`drawnBack`
19 * move) or somebody claimed the tile on the table (the claimer's melds grow).
20 * The hand number covers the deal, and the seat covers the pass around the
21 * table — four seats drawing in turn are four different ids.
22 */
23export function turnId(s: GameState): string {
24 return `${s.handNumber}:${s.turn}:${s.drawnFront}:${s.drawnBack}:${s.players[s.turn].melds.length}`;
25}
26
27/**
28 * Seven seconds of gold, draining from both ends towards the middle — the same
29 * shape whichever edge of the table it is drawn along, since a strip that is
30 * upside down from where you are sitting should still read as running out.
31 *
32 * When it is gone the line it left behind breathes instead, which is the whole
33 * of what happens at zero: the table keeps waiting, and goes on saying so.
34 *
35 * Give it a `key` of `turnId(state)` wherever it is used, or it will keep
36 * counting down the turn before last.
37 */
38export function TurnClock() {
39 return (
40 // Both the drain and the breathing after it are timed off this, so the
41 // seconds are written down once and in one place.
42 <div className="turn-clock" style={{ '--turn-secs': `${TURN_SECONDS}s` } as CSSProperties}>
43 <i />
44 </div>
45 );
46}