@journey-to-code/games 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/backgammon.d.ts +146 -0
- package/dist/backgammon.js +1221 -0
- package/dist/backgammon.js.map +1 -0
- package/dist/blackjack.d.ts +66 -0
- package/dist/blackjack.js +452 -0
- package/dist/blackjack.js.map +1 -0
- package/dist/bluff.d.ts +60 -0
- package/dist/bluff.js +239 -0
- package/dist/bluff.js.map +1 -0
- package/dist/board.d.ts +387 -0
- package/dist/board.js +105 -0
- package/dist/board.js.map +1 -0
- package/dist/bridge.d.ts +86 -0
- package/dist/bridge.js +494 -0
- package/dist/bridge.js.map +1 -0
- package/dist/canasta.d.ts +88 -0
- package/dist/canasta.js +646 -0
- package/dist/canasta.js.map +1 -0
- package/dist/checkers.d.ts +108 -0
- package/dist/checkers.js +756 -0
- package/dist/checkers.js.map +1 -0
- package/dist/chess.d.ts +162 -0
- package/dist/chess.js +904 -0
- package/dist/chess.js.map +1 -0
- package/dist/chesscore.d.ts +136 -0
- package/dist/chesscore.js +1121 -0
- package/dist/chesscore.js.map +1 -0
- package/dist/combat.d.ts +102 -0
- package/dist/combat.js +772 -0
- package/dist/combat.js.map +1 -0
- package/dist/contractrummy.d.ts +77 -0
- package/dist/contractrummy.js +430 -0
- package/dist/contractrummy.js.map +1 -0
- package/dist/crazy8.d.ts +65 -0
- package/dist/crazy8.js +366 -0
- package/dist/crazy8.js.map +1 -0
- package/dist/cribbage.d.ts +75 -0
- package/dist/cribbage.js +428 -0
- package/dist/cribbage.js.map +1 -0
- package/dist/cuckoo.d.ts +43 -0
- package/dist/cuckoo.js +216 -0
- package/dist/cuckoo.js.map +1 -0
- package/dist/drinkingpyramid.d.ts +54 -0
- package/dist/drinkingpyramid.js +213 -0
- package/dist/drinkingpyramid.js.map +1 -0
- package/dist/drinks.d.ts +25 -0
- package/dist/drinks.js +40 -0
- package/dist/drinks.js.map +1 -0
- package/dist/dropfour.d.ts +103 -0
- package/dist/dropfour.js +577 -0
- package/dist/dropfour.js.map +1 -0
- package/dist/durak.d.ts +58 -0
- package/dist/durak.js +332 -0
- package/dist/durak.js.map +1 -0
- package/dist/euchre.d.ts +80 -0
- package/dist/euchre.js +453 -0
- package/dist/euchre.js.map +1 -0
- package/dist/fivedraw.d.ts +50 -0
- package/dist/fivedraw.js +289 -0
- package/dist/fivedraw.js.map +1 -0
- package/dist/fivehundred.d.ts +90 -0
- package/dist/fivehundred.js +504 -0
- package/dist/fivehundred.js.map +1 -0
- package/dist/freecell.d.ts +50 -0
- package/dist/freecell.js +327 -0
- package/dist/freecell.js.map +1 -0
- package/dist/fruitsalad.d.ts +69 -0
- package/dist/fruitsalad.js +427 -0
- package/dist/fruitsalad.js.map +1 -0
- package/dist/gin.d.ts +72 -0
- package/dist/gin.js +393 -0
- package/dist/gin.js.map +1 -0
- package/dist/go.d.ts +132 -0
- package/dist/go.js +659 -0
- package/dist/go.js.map +1 -0
- package/dist/goboard.d.ts +218 -0
- package/dist/goboard.js +880 -0
- package/dist/goboard.js.map +1 -0
- package/dist/gofish.d.ts +37 -0
- package/dist/gofish.js +235 -0
- package/dist/gofish.js.map +1 -0
- package/dist/golf.d.ts +64 -0
- package/dist/golf.js +343 -0
- package/dist/golf.js.map +1 -0
- package/dist/handfoot.d.ts +86 -0
- package/dist/handfoot.js +515 -0
- package/dist/handfoot.js.map +1 -0
- package/dist/hearts.d.ts +65 -0
- package/dist/hearts.js +390 -0
- package/dist/hearts.js.map +1 -0
- package/dist/holdem.d.ts +45 -0
- package/dist/holdem.js +286 -0
- package/dist/holdem.js.map +1 -0
- package/dist/horserace.d.ts +49 -0
- package/dist/horserace.js +207 -0
- package/dist/horserace.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/kingscorner.d.ts +59 -0
- package/dist/kingscorner.js +374 -0
- package/dist/kingscorner.js.map +1 -0
- package/dist/kingscup.d.ts +44 -0
- package/dist/kingscup.js +185 -0
- package/dist/kingscup.js.map +1 -0
- package/dist/kit.d.ts +283 -0
- package/dist/kit.js +73 -0
- package/dist/kit.js.map +1 -0
- package/dist/klondike.d.ts +57 -0
- package/dist/klondike.js +314 -0
- package/dist/klondike.js.map +1 -0
- package/dist/liarspoker.d.ts +61 -0
- package/dist/liarspoker.js +298 -0
- package/dist/liarspoker.js.map +1 -0
- package/dist/memory.d.ts +36 -0
- package/dist/memory.js +181 -0
- package/dist/memory.js.map +1 -0
- package/dist/minigolf.d.ts +104 -0
- package/dist/minigolf.js +724 -0
- package/dist/minigolf.js.map +1 -0
- package/dist/minigolfcourse.d.ts +127 -0
- package/dist/minigolfcourse.js +470 -0
- package/dist/minigolfcourse.js.map +1 -0
- package/dist/offers.d.ts +136 -0
- package/dist/offers.js +279 -0
- package/dist/offers.js.map +1 -0
- package/dist/ohhell.d.ts +66 -0
- package/dist/ohhell.js +331 -0
- package/dist/ohhell.js.map +1 -0
- package/dist/oldmaid.d.ts +40 -0
- package/dist/oldmaid.js +186 -0
- package/dist/oldmaid.js.map +1 -0
- package/dist/pinochle.d.ts +94 -0
- package/dist/pinochle.js +466 -0
- package/dist/pinochle.js.map +1 -0
- package/dist/pitch.d.ts +77 -0
- package/dist/pitch.js +362 -0
- package/dist/pitch.js.map +1 -0
- package/dist/poker.d.ts +79 -0
- package/dist/poker.js +268 -0
- package/dist/poker.js.map +1 -0
- package/dist/president.d.ts +56 -0
- package/dist/president.js +339 -0
- package/dist/president.js.map +1 -0
- package/dist/pyramid.d.ts +39 -0
- package/dist/pyramid.js +200 -0
- package/dist/pyramid.js.map +1 -0
- package/dist/registry.d.ts +17 -0
- package/dist/registry.js +70 -0
- package/dist/registry.js.map +1 -0
- package/dist/reversi.d.ts +69 -0
- package/dist/reversi.js +584 -0
- package/dist/reversi.js.map +1 -0
- package/dist/ridethebus.d.ts +48 -0
- package/dist/ridethebus.js +257 -0
- package/dist/ridethebus.js.map +1 -0
- package/dist/rummy500.d.ts +89 -0
- package/dist/rummy500.js +474 -0
- package/dist/rummy500.js.map +1 -0
- package/dist/sevens.d.ts +48 -0
- package/dist/sevens.js +221 -0
- package/dist/sevens.js.map +1 -0
- package/dist/slapjack.d.ts +42 -0
- package/dist/slapjack.js +224 -0
- package/dist/slapjack.js.map +1 -0
- package/dist/speed.d.ts +44 -0
- package/dist/speed.js +201 -0
- package/dist/speed.js.map +1 -0
- package/dist/spider.d.ts +51 -0
- package/dist/spider.js +320 -0
- package/dist/spider.js.map +1 -0
- package/dist/spite.d.ts +75 -0
- package/dist/spite.js +372 -0
- package/dist/spite.js.map +1 -0
- package/dist/sport.d.ts +266 -0
- package/dist/sport.js +48 -0
- package/dist/sport.js.map +1 -0
- package/dist/switch.d.ts +69 -0
- package/dist/switch.js +393 -0
- package/dist/switch.js.map +1 -0
- package/dist/table.d.ts +284 -0
- package/dist/table.js +67 -0
- package/dist/table.js.map +1 -0
- package/dist/talk.d.ts +17 -0
- package/dist/talk.js +44 -0
- package/dist/talk.js.map +1 -0
- package/dist/thirtyone.d.ts +66 -0
- package/dist/thirtyone.js +372 -0
- package/dist/thirtyone.js.map +1 -0
- package/dist/tictactoe.d.ts +68 -0
- package/dist/tictactoe.js +541 -0
- package/dist/tictactoe.js.map +1 -0
- package/dist/tricks.d.ts +21 -0
- package/dist/tricks.js +48 -0
- package/dist/tricks.js.map +1 -0
- package/dist/war.d.ts +44 -0
- package/dist/war.js +185 -0
- package/dist/war.js.map +1 -0
- package/dist/whist.d.ts +52 -0
- package/dist/whist.js +218 -0
- package/dist/whist.js.map +1 -0
- package/dist/yacht.d.ts +96 -0
- package/dist/yacht.js +653 -0
- package/dist/yacht.js.map +1 -0
- package/package.json +41 -4
- package/README.md +0 -3
package/dist/sport.d.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import type { Body, Point, Shape, Shot, World } from "@journey-to-code/physics";
|
|
2
|
+
import type { BaseRules, Choices, GameOver, RoundResult, Scores, ScoreSheet, SportGameId, TableGame } from "./table.js";
|
|
3
|
+
/**
|
|
4
|
+
* Lengths in a sport's world are tenths of a millimetre, as in the physics core's examples, so a
|
|
5
|
+
* table can say "1.2 m from the cup" to someone who can't see it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const UNITS_PER_METRE = 10000;
|
|
8
|
+
/** What a patch of the table is, for drawing: the table screen decides what each looks like. */
|
|
9
|
+
export type SportSurface = "green" | "rough" | "sand" | "water" | "slope" | "felt" | "wood" | "lane" | "lawn" | "gravel" | "paving" | "soil" | "deck";
|
|
10
|
+
/** What a rail, a block or a ledge is made of. */
|
|
11
|
+
export type SportMaterial = "timber" | "brick" | "stone";
|
|
12
|
+
/** A patch of ground: scenery round the table or the surface that is played on. */
|
|
13
|
+
export interface SportGround {
|
|
14
|
+
shape: Shape;
|
|
15
|
+
surface: SportSurface;
|
|
16
|
+
/**
|
|
17
|
+
* How far above the ground round the table this patch stands (a terrace, a raised bed), in world
|
|
18
|
+
* units. Left out: it lies on whatever was laid under it, and if it is water or sand, the
|
|
19
|
+
* screen may sink it a little.
|
|
20
|
+
*/
|
|
21
|
+
level?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A wall of the world that is a rail: a border with thickness, standing beside the line a ball
|
|
25
|
+
* stops at. `side` is where the rail's body lies as you walk along the wall's points (with y down
|
|
26
|
+
* the screen): to the left of the line, to the right, or astride it.
|
|
27
|
+
*/
|
|
28
|
+
export interface SportRail {
|
|
29
|
+
wall: string;
|
|
30
|
+
material: SportMaterial;
|
|
31
|
+
side: "left" | "right" | "both";
|
|
32
|
+
/** Across, and how high it stands, in world units. */
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
}
|
|
36
|
+
/** A closed wall of the world that is a solid thing standing on the table. */
|
|
37
|
+
export interface SportBlock {
|
|
38
|
+
wall: string;
|
|
39
|
+
kind: "rock" | "brick" | "timber" | "planter" | "pot" | "stone" | "castle" | "crate";
|
|
40
|
+
/** How high it stands, in world units. */
|
|
41
|
+
height: number;
|
|
42
|
+
}
|
|
43
|
+
/** A one-way wall of the world that is a step down: the ground on its open side is `drop` higher. */
|
|
44
|
+
export interface SportLedge {
|
|
45
|
+
wall: string;
|
|
46
|
+
drop: number;
|
|
47
|
+
material: SportMaterial;
|
|
48
|
+
}
|
|
49
|
+
/** A tunnel of the world: what it is, and where its pipe runs if any of it shows. */
|
|
50
|
+
export interface SportTunnel {
|
|
51
|
+
id: string;
|
|
52
|
+
/** A pipe with open ends, a garden hose, or a burrow: a hole in the ground and a mound where it comes up. */
|
|
53
|
+
kind: "pipe" | "hose" | "burrow";
|
|
54
|
+
/** The way a ball rolls into the mouth, in hundredths of a degree: which way the opening faces. */
|
|
55
|
+
enter: number;
|
|
56
|
+
/** Where the pipe can be seen lying between its two ends. Left out when it runs underground or through something. */
|
|
57
|
+
path?: Point[];
|
|
58
|
+
/** Where the far opening is, when that isn't quite where the ball is let go (a pipe's end set in a rock face). */
|
|
59
|
+
out?: Point;
|
|
60
|
+
}
|
|
61
|
+
/** The colours a ball can take. */
|
|
62
|
+
export type SportTone = "white" | "red" | "blue" | "gold" | "green" | "purple" | "orange" | "pink" | "maroon" | "black";
|
|
63
|
+
/** How one body is drawn and who it belongs to. Bodies without an entry are drawn plain. */
|
|
64
|
+
export interface SportBody {
|
|
65
|
+
/** The body's id in the world (or a ghost's own id). */
|
|
66
|
+
id: string;
|
|
67
|
+
/** Whose it is (a seat), or null for something that is nobody's: an object ball, a pin, a bumper. */
|
|
68
|
+
owner: number | null;
|
|
69
|
+
/** What it is, in the game's own words: "ball", "cue", "striker", "pin", "toadstool". */
|
|
70
|
+
kind: string;
|
|
71
|
+
tone: SportTone;
|
|
72
|
+
/** What a screen reader says: "your ball", "the 8 ball". */
|
|
73
|
+
label: string;
|
|
74
|
+
/** Drawn on it: a pool ball's number, a player's initial. */
|
|
75
|
+
mark?: string;
|
|
76
|
+
/** A striped pool ball. */
|
|
77
|
+
striped?: boolean;
|
|
78
|
+
/** How high it stands, in world units, for something that isn't a ball. */
|
|
79
|
+
height?: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Something drawn on the table that the physics of this view knows nothing about: in mini golf
|
|
83
|
+
* played all at once, the other players' balls (which never collide with yours), and in turn, a
|
|
84
|
+
* ball lifted out of the way of the one about to be struck. It can't be struck or hit.
|
|
85
|
+
*/
|
|
86
|
+
export interface SportGhost extends SportBody {
|
|
87
|
+
x: number;
|
|
88
|
+
y: number;
|
|
89
|
+
r: number;
|
|
90
|
+
}
|
|
91
|
+
/** Scenery, in world units. None of it touches the ball. */
|
|
92
|
+
export interface SportDecor {
|
|
93
|
+
kind: "tee" | "flag" | "bush" | "flowers" | "rock" | "tree" | "gnome" | "flowerpot" | "wateringcan" | "wheelbarrow" | "steppingstone" | "lilypad" | "fish" | "reeds" | "duck" | "bucket" | "spade" | "bricks" | "bench" | "birdbath" | "molehill" | "poolring" | "doormat" | "hosereel" | "plank" | "shell";
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
/** Size, for the things that have one. */
|
|
97
|
+
r?: number;
|
|
98
|
+
/** Which way it faces, in hundredths of a degree (0 along +x), for the things that face a way. */
|
|
99
|
+
angle?: number;
|
|
100
|
+
/** A length, for the things that are longer than they are wide (a plank, a bench). */
|
|
101
|
+
length?: number;
|
|
102
|
+
/** How high it stands, in world units. Left out: as high as such a thing usually is. */
|
|
103
|
+
height?: number;
|
|
104
|
+
tone?: SportTone;
|
|
105
|
+
}
|
|
106
|
+
/** How the world is drawn. The world says where things are; this says what they are. */
|
|
107
|
+
export interface SportLook {
|
|
108
|
+
/** The rectangle the screen fits and centres: the table and a margin round it. */
|
|
109
|
+
frame: {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
w: number;
|
|
113
|
+
h: number;
|
|
114
|
+
};
|
|
115
|
+
/** What lies under and around everything else, as far as the screen goes. */
|
|
116
|
+
base: SportSurface;
|
|
117
|
+
/** Patches of ground, laid in order: the scenery first, then what is played on (the green of a hole, the cloth of a pool table). */
|
|
118
|
+
ground: SportGround[];
|
|
119
|
+
/**
|
|
120
|
+
* What each region of the world is drawn as, in drawing order. A region left out is not drawn.
|
|
121
|
+
* `rise` is for a slope: how much higher its top is than its foot, in world units.
|
|
122
|
+
*/
|
|
123
|
+
regions: {
|
|
124
|
+
id: string;
|
|
125
|
+
surface: SportSurface;
|
|
126
|
+
rise?: number;
|
|
127
|
+
}[];
|
|
128
|
+
/** The walls that are rails. A wall named nowhere in the look is not drawn. */
|
|
129
|
+
rails: SportRail[];
|
|
130
|
+
/** Closed walls that are solid things standing on the table (a rock, a planter). */
|
|
131
|
+
blocks: SportBlock[];
|
|
132
|
+
ledges: SportLedge[];
|
|
133
|
+
tunnels: SportTunnel[];
|
|
134
|
+
/** Pockets are drawn as golf cups (with a flag) or as the pockets of a pool table. */
|
|
135
|
+
pockets: "cup" | "pocket";
|
|
136
|
+
decor: SportDecor[];
|
|
137
|
+
}
|
|
138
|
+
/** What a seat may strike now. Later additions sit beside these: `place` for a ball in hand, `spin`. */
|
|
139
|
+
export interface SportShoot {
|
|
140
|
+
/** The body to strike. */
|
|
141
|
+
body: string;
|
|
142
|
+
/** The power may be anything from here… */
|
|
143
|
+
minPower: number;
|
|
144
|
+
/** …to here (1000 is the world's full shot speed). */
|
|
145
|
+
maxPower: number;
|
|
146
|
+
}
|
|
147
|
+
/** Where one body stopped when the physics came to rest, before the game's rules moved anything. */
|
|
148
|
+
export interface SportRest {
|
|
149
|
+
id: string;
|
|
150
|
+
x: number;
|
|
151
|
+
y: number;
|
|
152
|
+
pocketed?: string;
|
|
153
|
+
out?: string;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The shot just taken, enough for a browser to play it again: put `from` in place of the bodies
|
|
157
|
+
* of the view's world (see `worldBefore`), run the shot, and it ends at `rest`. After that the
|
|
158
|
+
* screen shows the view's world as it is, which is `rest` with the game's rules applied (in mini
|
|
159
|
+
* golf, a ball that went in the water is back where it was struck from).
|
|
160
|
+
*/
|
|
161
|
+
export interface SportShot {
|
|
162
|
+
/** Counts the shots of a game from 1, so each is animated once. */
|
|
163
|
+
n: number;
|
|
164
|
+
seat: number;
|
|
165
|
+
shot: Shot;
|
|
166
|
+
/** The bodies as they were when the shot was struck. */
|
|
167
|
+
from: Body[];
|
|
168
|
+
rest: SportRest[];
|
|
169
|
+
/** How many steps of the world's tick the shot took. */
|
|
170
|
+
ticks: number;
|
|
171
|
+
/** The PHYSICS_VERSION that played it. A browser on another version shows the result without stepping. */
|
|
172
|
+
physics: number;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* A score sheet with a column per hole (or frame, or rack) and a row per player. It is the kit-wide
|
|
176
|
+
* `ScoreSheet` (table.ts), which the board kit uses too.
|
|
177
|
+
*/
|
|
178
|
+
export type SportCard = ScoreSheet;
|
|
179
|
+
export interface SportSeat {
|
|
180
|
+
/** A short line under the name: "2 strokes", "Holed in 3". */
|
|
181
|
+
line: string;
|
|
182
|
+
/** What this seat plays with, shown beside the name. */
|
|
183
|
+
body?: SportBody;
|
|
184
|
+
/** Partners: 0 or 1 (seats 0 and 2 are team 0). */
|
|
185
|
+
team?: 0 | 1;
|
|
186
|
+
/** Finished with this table for now: holed out, or picked up. */
|
|
187
|
+
done?: boolean;
|
|
188
|
+
badge?: string;
|
|
189
|
+
}
|
|
190
|
+
export interface SportView {
|
|
191
|
+
game: SportGameId;
|
|
192
|
+
seats: number;
|
|
193
|
+
me: number;
|
|
194
|
+
teams: boolean;
|
|
195
|
+
phase: string;
|
|
196
|
+
/** Whose shot it is, or null when everyone may shoot (each at their own ball) or nobody may. */
|
|
197
|
+
turn: number | null;
|
|
198
|
+
table: {
|
|
199
|
+
/** Changes when the table is a different one (the next hole), so the screen fits it afresh. */
|
|
200
|
+
key: string;
|
|
201
|
+
/** "Hole 3: The Elbow". */
|
|
202
|
+
name: string;
|
|
203
|
+
/** The table at rest, as this seat's next shot would find it. */
|
|
204
|
+
world: World;
|
|
205
|
+
look: SportLook;
|
|
206
|
+
/** How the world's bodies are drawn, by id. */
|
|
207
|
+
bodies: SportBody[];
|
|
208
|
+
ghosts: SportGhost[];
|
|
209
|
+
};
|
|
210
|
+
/** What this seat may strike now, or null. */
|
|
211
|
+
shoot: SportShoot | null;
|
|
212
|
+
/** The last shot on this table that this seat should see played, or null. */
|
|
213
|
+
last: SportShot | null;
|
|
214
|
+
card: SportCard | null;
|
|
215
|
+
/** Buttons: "Next hole", "Rack them up". */
|
|
216
|
+
choices: Choices | null;
|
|
217
|
+
players: SportSeat[];
|
|
218
|
+
/** Small facts for the table: "Par 3", "Stroke 2". */
|
|
219
|
+
info: string[];
|
|
220
|
+
/** What just happened, in words. */
|
|
221
|
+
narration: string | null;
|
|
222
|
+
scores: Scores;
|
|
223
|
+
/** After a hole or a frame, until everyone moves on; and with `over`, the final summary. */
|
|
224
|
+
result: RoundResult | null;
|
|
225
|
+
/** `winners` is every seat when it's a tie. */
|
|
226
|
+
over: GameOver | null;
|
|
227
|
+
}
|
|
228
|
+
/** A table sport: an engine whose seats see a `SportView`, and whose moves are shots and buttons. */
|
|
229
|
+
export interface SportGame<R extends BaseRules = BaseRules, S = unknown, M = Record<string, unknown>> extends TableGame<R, S, M, SportView> {
|
|
230
|
+
id: SportGameId;
|
|
231
|
+
/**
|
|
232
|
+
* Work worth doing once before the first table opens. A JavaScript engine runs the simulation
|
|
233
|
+
* slowly until it has seen it a few hundred times, and a game may keep maps of its tables; a
|
|
234
|
+
* server calls this as it starts, so the first shot of the day isn't the slow one.
|
|
235
|
+
*/
|
|
236
|
+
warmUp?(): void;
|
|
237
|
+
}
|
|
238
|
+
/** A shot as a move. The numbers are the physics core's: whole, and checked again by the engine. */
|
|
239
|
+
export interface ShotMove {
|
|
240
|
+
type: "shot";
|
|
241
|
+
body: string;
|
|
242
|
+
/** Whole hundredths of a degree, 0 to 35999. 0 is along +x, 9000 along +y (down the screen). */
|
|
243
|
+
angle: number;
|
|
244
|
+
/** A whole number within the view's `shoot` range. */
|
|
245
|
+
power: number;
|
|
246
|
+
}
|
|
247
|
+
/** The world as it was when the view's last shot was struck: what a browser simulates from. */
|
|
248
|
+
export declare function worldBefore(view: Pick<SportView, "table" | "last">): World | null;
|
|
249
|
+
/** Where the bodies of a resting world are, in the short form a view carries. */
|
|
250
|
+
export declare function restOf(world: World): SportRest[];
|
|
251
|
+
/** Whether a locally stepped world ended exactly where the server said it would. */
|
|
252
|
+
export declare function sameRest(world: World, rest: SportRest[]): boolean;
|
|
253
|
+
/** The angle (in the physics core's hundredths of a degree) from one point towards another. */
|
|
254
|
+
export declare function angleTo(from: {
|
|
255
|
+
x: number;
|
|
256
|
+
y: number;
|
|
257
|
+
}, to: {
|
|
258
|
+
x: number;
|
|
259
|
+
y: number;
|
|
260
|
+
}): number;
|
|
261
|
+
/**
|
|
262
|
+
* Some of what a seat can send from a view, as moves: every button, and when it may shoot, a
|
|
263
|
+
* spread of shots across the range it is offered. (There are 36 million shots; the shared tests
|
|
264
|
+
* play from these.)
|
|
265
|
+
*/
|
|
266
|
+
export declare function sportMovesOffered(view: SportView): Record<string, unknown>[];
|
package/dist/sport.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lengths in a sport's world are tenths of a millimetre, as in the physics core's examples, so a
|
|
3
|
+
* table can say "1.2 m from the cup" to someone who can't see it.
|
|
4
|
+
*/
|
|
5
|
+
export const UNITS_PER_METRE = 10000;
|
|
6
|
+
// ---- Helpers for engines, tables and tests ------------------------------------------------------
|
|
7
|
+
/** The world as it was when the view's last shot was struck: what a browser simulates from. */
|
|
8
|
+
export function worldBefore(view) {
|
|
9
|
+
return view.last ? { ...view.table.world, bodies: view.last.from } : null;
|
|
10
|
+
}
|
|
11
|
+
/** Where the bodies of a resting world are, in the short form a view carries. */
|
|
12
|
+
export function restOf(world) {
|
|
13
|
+
return world.bodies.map((b) => ({ id: b.id, x: b.x, y: b.y, ...(b.pocketed !== undefined ? { pocketed: b.pocketed } : {}), ...(b.out !== undefined ? { out: b.out } : {}) }));
|
|
14
|
+
}
|
|
15
|
+
/** Whether a locally stepped world ended exactly where the server said it would. */
|
|
16
|
+
export function sameRest(world, rest) {
|
|
17
|
+
if (world.bodies.length !== rest.length)
|
|
18
|
+
return false;
|
|
19
|
+
return world.bodies.every((b, i) => {
|
|
20
|
+
const r = rest[i];
|
|
21
|
+
return b.id === r.id && b.x === r.x && b.y === r.y && b.pocketed === r.pocketed && b.out === r.out;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** The angle (in the physics core's hundredths of a degree) from one point towards another. */
|
|
25
|
+
export function angleTo(from, to) {
|
|
26
|
+
// Aiming is free to use any maths: only the rounded whole number is ever sent or simulated.
|
|
27
|
+
const a = Math.round((Math.atan2(to.y - from.y, to.x - from.x) * 18000) / Math.PI);
|
|
28
|
+
return ((a % 36000) + 36000) % 36000;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Some of what a seat can send from a view, as moves: every button, and when it may shoot, a
|
|
32
|
+
* spread of shots across the range it is offered. (There are 36 million shots; the shared tests
|
|
33
|
+
* play from these.)
|
|
34
|
+
*/
|
|
35
|
+
export function sportMovesOffered(view) {
|
|
36
|
+
const out = [];
|
|
37
|
+
if (view.shoot) {
|
|
38
|
+
const { body, minPower, maxPower } = view.shoot;
|
|
39
|
+
const mid = Math.round((minPower + maxPower) / 2);
|
|
40
|
+
for (const angle of [0, 4500, 9000, 13500, 18000, 22500, 27000, 31500, 35999])
|
|
41
|
+
for (const power of [minPower, mid, maxPower])
|
|
42
|
+
out.push({ type: "shot", body, angle, power });
|
|
43
|
+
}
|
|
44
|
+
for (const o of view.choices?.options ?? [])
|
|
45
|
+
out.push(o.move);
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=sport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sport.js","sourceRoot":"","sources":["../src/sport.ts"],"names":[],"mappings":"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"}
|
package/dist/switch.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Suit } from "@journey-to-code/rules";
|
|
2
|
+
import { type BaseRules, type CardGame, type KCard } from "./kit.js";
|
|
3
|
+
export interface SwitchRules extends BaseRules {
|
|
4
|
+
/** Draw one and pass, or draw until you can play. */
|
|
5
|
+
draw: "until" | "one";
|
|
6
|
+
/** One hand (first out wins) or points: the winner scores what's left in everyone's hands. */
|
|
7
|
+
scoring: "single" | "points";
|
|
8
|
+
playTo: number;
|
|
9
|
+
/** You must call "Last card!" before going down to one card, or pick up two. */
|
|
10
|
+
lastCard: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const classicSwitch: SwitchRules;
|
|
13
|
+
export declare const pointsSwitch: SwitchRules;
|
|
14
|
+
export declare const easySwitch: SwitchRules;
|
|
15
|
+
type Phase = "playing" | "suit" | "scored" | "finished";
|
|
16
|
+
export interface SwitchState {
|
|
17
|
+
game: "switch";
|
|
18
|
+
rules: SwitchRules;
|
|
19
|
+
seats: number;
|
|
20
|
+
rng: number;
|
|
21
|
+
hand: number;
|
|
22
|
+
dealer: number;
|
|
23
|
+
phase: Phase;
|
|
24
|
+
hands: KCard[][];
|
|
25
|
+
stock: KCard[];
|
|
26
|
+
discard: KCard[];
|
|
27
|
+
/** The suit to match: the top card's, or the one named with an eight. */
|
|
28
|
+
suit: Suit;
|
|
29
|
+
turn: number;
|
|
30
|
+
direction: 1 | -1;
|
|
31
|
+
/** Cards the next player must draw (from 2s). */
|
|
32
|
+
owed: number;
|
|
33
|
+
/** This turn's player has drawn (under draw-one they may then pass). */
|
|
34
|
+
drew: boolean;
|
|
35
|
+
/** Turns in a row where nobody could play or draw anything: a full round ends the hand. */
|
|
36
|
+
stuck: number;
|
|
37
|
+
/** How often the discards have been shuffled into a new stock this hand (at most twice). */
|
|
38
|
+
reshuffles: number;
|
|
39
|
+
/** Who has called "Last card!" (and still holds two or fewer). */
|
|
40
|
+
called: boolean[];
|
|
41
|
+
scores: number[];
|
|
42
|
+
lastHand: {
|
|
43
|
+
winner: number;
|
|
44
|
+
points: number;
|
|
45
|
+
left: number[];
|
|
46
|
+
} | null;
|
|
47
|
+
ready: boolean[];
|
|
48
|
+
narration: string | null;
|
|
49
|
+
}
|
|
50
|
+
export declare function newSwitch(rules: SwitchRules, seats: number, seed: number): SwitchState;
|
|
51
|
+
/** Cards this seat may play now: matching suit or rank, or an ace. Facing twos, only another two. */
|
|
52
|
+
export declare function switchLegal(s: SwitchState, seat: number): KCard[];
|
|
53
|
+
type Move = {
|
|
54
|
+
type: "play";
|
|
55
|
+
card: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: "suit";
|
|
58
|
+
suit: Suit;
|
|
59
|
+
} | {
|
|
60
|
+
type: "draw";
|
|
61
|
+
} | {
|
|
62
|
+
type: "pass";
|
|
63
|
+
} | {
|
|
64
|
+
type: "last";
|
|
65
|
+
} | {
|
|
66
|
+
type: "next";
|
|
67
|
+
};
|
|
68
|
+
export declare const switchGame: CardGame<SwitchRules, SwitchState, Move>;
|
|
69
|
+
export {};
|