@journey-to-code/games 0.0.0-stage → 0.1.1

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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/dist/backgammon.d.ts +146 -0
  3. package/dist/backgammon.js +1221 -0
  4. package/dist/backgammon.js.map +1 -0
  5. package/dist/blackjack.d.ts +66 -0
  6. package/dist/blackjack.js +452 -0
  7. package/dist/blackjack.js.map +1 -0
  8. package/dist/bluff.d.ts +60 -0
  9. package/dist/bluff.js +239 -0
  10. package/dist/bluff.js.map +1 -0
  11. package/dist/board.d.ts +387 -0
  12. package/dist/board.js +105 -0
  13. package/dist/board.js.map +1 -0
  14. package/dist/bridge.d.ts +86 -0
  15. package/dist/bridge.js +494 -0
  16. package/dist/bridge.js.map +1 -0
  17. package/dist/canasta.d.ts +88 -0
  18. package/dist/canasta.js +646 -0
  19. package/dist/canasta.js.map +1 -0
  20. package/dist/checkers.d.ts +108 -0
  21. package/dist/checkers.js +756 -0
  22. package/dist/checkers.js.map +1 -0
  23. package/dist/chess.d.ts +162 -0
  24. package/dist/chess.js +904 -0
  25. package/dist/chess.js.map +1 -0
  26. package/dist/chesscore.d.ts +136 -0
  27. package/dist/chesscore.js +1121 -0
  28. package/dist/chesscore.js.map +1 -0
  29. package/dist/combat.d.ts +102 -0
  30. package/dist/combat.js +772 -0
  31. package/dist/combat.js.map +1 -0
  32. package/dist/contractrummy.d.ts +77 -0
  33. package/dist/contractrummy.js +430 -0
  34. package/dist/contractrummy.js.map +1 -0
  35. package/dist/crazy8.d.ts +65 -0
  36. package/dist/crazy8.js +366 -0
  37. package/dist/crazy8.js.map +1 -0
  38. package/dist/cribbage.d.ts +75 -0
  39. package/dist/cribbage.js +428 -0
  40. package/dist/cribbage.js.map +1 -0
  41. package/dist/cuckoo.d.ts +43 -0
  42. package/dist/cuckoo.js +216 -0
  43. package/dist/cuckoo.js.map +1 -0
  44. package/dist/drinkingpyramid.d.ts +54 -0
  45. package/dist/drinkingpyramid.js +213 -0
  46. package/dist/drinkingpyramid.js.map +1 -0
  47. package/dist/drinks.d.ts +25 -0
  48. package/dist/drinks.js +40 -0
  49. package/dist/drinks.js.map +1 -0
  50. package/dist/dropfour.d.ts +103 -0
  51. package/dist/dropfour.js +577 -0
  52. package/dist/dropfour.js.map +1 -0
  53. package/dist/durak.d.ts +58 -0
  54. package/dist/durak.js +332 -0
  55. package/dist/durak.js.map +1 -0
  56. package/dist/euchre.d.ts +80 -0
  57. package/dist/euchre.js +453 -0
  58. package/dist/euchre.js.map +1 -0
  59. package/dist/fivedraw.d.ts +50 -0
  60. package/dist/fivedraw.js +289 -0
  61. package/dist/fivedraw.js.map +1 -0
  62. package/dist/fivehundred.d.ts +90 -0
  63. package/dist/fivehundred.js +504 -0
  64. package/dist/fivehundred.js.map +1 -0
  65. package/dist/freecell.d.ts +50 -0
  66. package/dist/freecell.js +327 -0
  67. package/dist/freecell.js.map +1 -0
  68. package/dist/fruitsalad.d.ts +69 -0
  69. package/dist/fruitsalad.js +427 -0
  70. package/dist/fruitsalad.js.map +1 -0
  71. package/dist/gin.d.ts +72 -0
  72. package/dist/gin.js +393 -0
  73. package/dist/gin.js.map +1 -0
  74. package/dist/go.d.ts +132 -0
  75. package/dist/go.js +659 -0
  76. package/dist/go.js.map +1 -0
  77. package/dist/goboard.d.ts +218 -0
  78. package/dist/goboard.js +880 -0
  79. package/dist/goboard.js.map +1 -0
  80. package/dist/gofish.d.ts +37 -0
  81. package/dist/gofish.js +235 -0
  82. package/dist/gofish.js.map +1 -0
  83. package/dist/golf.d.ts +64 -0
  84. package/dist/golf.js +343 -0
  85. package/dist/golf.js.map +1 -0
  86. package/dist/handfoot.d.ts +86 -0
  87. package/dist/handfoot.js +515 -0
  88. package/dist/handfoot.js.map +1 -0
  89. package/dist/hearts.d.ts +65 -0
  90. package/dist/hearts.js +390 -0
  91. package/dist/hearts.js.map +1 -0
  92. package/dist/holdem.d.ts +45 -0
  93. package/dist/holdem.js +286 -0
  94. package/dist/holdem.js.map +1 -0
  95. package/dist/horserace.d.ts +49 -0
  96. package/dist/horserace.js +207 -0
  97. package/dist/horserace.js.map +1 -0
  98. package/dist/index.d.ts +65 -0
  99. package/dist/index.js +66 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/kingscorner.d.ts +59 -0
  102. package/dist/kingscorner.js +374 -0
  103. package/dist/kingscorner.js.map +1 -0
  104. package/dist/kingscup.d.ts +44 -0
  105. package/dist/kingscup.js +185 -0
  106. package/dist/kingscup.js.map +1 -0
  107. package/dist/kit.d.ts +283 -0
  108. package/dist/kit.js +73 -0
  109. package/dist/kit.js.map +1 -0
  110. package/dist/klondike.d.ts +57 -0
  111. package/dist/klondike.js +314 -0
  112. package/dist/klondike.js.map +1 -0
  113. package/dist/liarspoker.d.ts +61 -0
  114. package/dist/liarspoker.js +298 -0
  115. package/dist/liarspoker.js.map +1 -0
  116. package/dist/memory.d.ts +36 -0
  117. package/dist/memory.js +181 -0
  118. package/dist/memory.js.map +1 -0
  119. package/dist/minigolf.d.ts +104 -0
  120. package/dist/minigolf.js +724 -0
  121. package/dist/minigolf.js.map +1 -0
  122. package/dist/minigolfcourse.d.ts +127 -0
  123. package/dist/minigolfcourse.js +470 -0
  124. package/dist/minigolfcourse.js.map +1 -0
  125. package/dist/offers.d.ts +136 -0
  126. package/dist/offers.js +279 -0
  127. package/dist/offers.js.map +1 -0
  128. package/dist/ohhell.d.ts +66 -0
  129. package/dist/ohhell.js +331 -0
  130. package/dist/ohhell.js.map +1 -0
  131. package/dist/oldmaid.d.ts +40 -0
  132. package/dist/oldmaid.js +186 -0
  133. package/dist/oldmaid.js.map +1 -0
  134. package/dist/pinochle.d.ts +94 -0
  135. package/dist/pinochle.js +466 -0
  136. package/dist/pinochle.js.map +1 -0
  137. package/dist/pitch.d.ts +77 -0
  138. package/dist/pitch.js +362 -0
  139. package/dist/pitch.js.map +1 -0
  140. package/dist/poker.d.ts +79 -0
  141. package/dist/poker.js +268 -0
  142. package/dist/poker.js.map +1 -0
  143. package/dist/president.d.ts +56 -0
  144. package/dist/president.js +339 -0
  145. package/dist/president.js.map +1 -0
  146. package/dist/pyramid.d.ts +39 -0
  147. package/dist/pyramid.js +200 -0
  148. package/dist/pyramid.js.map +1 -0
  149. package/dist/registry.d.ts +17 -0
  150. package/dist/registry.js +70 -0
  151. package/dist/registry.js.map +1 -0
  152. package/dist/reversi.d.ts +69 -0
  153. package/dist/reversi.js +584 -0
  154. package/dist/reversi.js.map +1 -0
  155. package/dist/ridethebus.d.ts +48 -0
  156. package/dist/ridethebus.js +257 -0
  157. package/dist/ridethebus.js.map +1 -0
  158. package/dist/rummy500.d.ts +89 -0
  159. package/dist/rummy500.js +474 -0
  160. package/dist/rummy500.js.map +1 -0
  161. package/dist/sevens.d.ts +48 -0
  162. package/dist/sevens.js +221 -0
  163. package/dist/sevens.js.map +1 -0
  164. package/dist/slapjack.d.ts +42 -0
  165. package/dist/slapjack.js +224 -0
  166. package/dist/slapjack.js.map +1 -0
  167. package/dist/speed.d.ts +44 -0
  168. package/dist/speed.js +201 -0
  169. package/dist/speed.js.map +1 -0
  170. package/dist/spider.d.ts +51 -0
  171. package/dist/spider.js +320 -0
  172. package/dist/spider.js.map +1 -0
  173. package/dist/spite.d.ts +75 -0
  174. package/dist/spite.js +372 -0
  175. package/dist/spite.js.map +1 -0
  176. package/dist/sport.d.ts +266 -0
  177. package/dist/sport.js +48 -0
  178. package/dist/sport.js.map +1 -0
  179. package/dist/switch.d.ts +69 -0
  180. package/dist/switch.js +393 -0
  181. package/dist/switch.js.map +1 -0
  182. package/dist/table.d.ts +284 -0
  183. package/dist/table.js +67 -0
  184. package/dist/table.js.map +1 -0
  185. package/dist/talk.d.ts +17 -0
  186. package/dist/talk.js +44 -0
  187. package/dist/talk.js.map +1 -0
  188. package/dist/thirtyone.d.ts +66 -0
  189. package/dist/thirtyone.js +372 -0
  190. package/dist/thirtyone.js.map +1 -0
  191. package/dist/tictactoe.d.ts +68 -0
  192. package/dist/tictactoe.js +541 -0
  193. package/dist/tictactoe.js.map +1 -0
  194. package/dist/tricks.d.ts +21 -0
  195. package/dist/tricks.js +48 -0
  196. package/dist/tricks.js.map +1 -0
  197. package/dist/war.d.ts +44 -0
  198. package/dist/war.js +185 -0
  199. package/dist/war.js.map +1 -0
  200. package/dist/whist.d.ts +52 -0
  201. package/dist/whist.js +218 -0
  202. package/dist/whist.js.map +1 -0
  203. package/dist/yacht.d.ts +96 -0
  204. package/dist/yacht.js +653 -0
  205. package/dist/yacht.js.map +1 -0
  206. package/package.json +41 -4
  207. package/README.md +0 -3
package/dist/gin.js ADDED
@@ -0,0 +1,393 @@
1
+ import { clone, FULL, GameError, makeDeck, markReady, nextRandom, rankLabel, rankSeats, shuffled, SYMBOL, thinkFor, who, } from "./kit.js";
2
+ export const classicGin = { id: "gin-classic", name: "Classic Gin (to 100)", playTo: 100, knockAt: 10, ginBonus: 25, undercutBonus: 25 };
3
+ export const quickGin = { ...classicGin, id: "gin-quick", name: "Quick Gin (to 50)", playTo: 50 };
4
+ export const straightGin = { ...classicGin, id: "gin-straight", name: "Gin only (no knocking)", knockAt: 0 };
5
+ const rank = (c) => c.rank;
6
+ const suitOf = (c) => c.suit;
7
+ /** Aces are low in Gin: A, 2, 3 is a run; Q, K, A isn't. */
8
+ const low = (c) => (rank(c) === 14 ? 1 : rank(c));
9
+ export const ginValue = (c) => Math.min(10, low(c));
10
+ // ---- Melds --------------------------------------------------------------------------------------
11
+ /** Every set and run these cards could make (including three-card parts of four-card sets). */
12
+ function possibleMelds(cards) {
13
+ const melds = [];
14
+ const byRank = new Map();
15
+ for (const c of cards)
16
+ byRank.set(low(c), [...(byRank.get(low(c)) ?? []), c]);
17
+ for (const group of byRank.values()) {
18
+ if (group.length >= 3)
19
+ melds.push(group);
20
+ if (group.length === 4)
21
+ for (let skip = 0; skip < 4; skip++)
22
+ melds.push(group.filter((_, i) => i !== skip));
23
+ }
24
+ for (const suit of ["spades", "hearts", "diamonds", "clubs"]) {
25
+ const run = cards.filter((c) => suitOf(c) === suit).sort((a, b) => low(a) - low(b));
26
+ for (let i = 0; i < run.length; i++) {
27
+ const seq = [run[i]];
28
+ for (let j = i + 1; j < run.length && low(run[j]) === low(seq[seq.length - 1]) + 1; j++) {
29
+ seq.push(run[j]);
30
+ if (seq.length >= 3)
31
+ melds.push([...seq]);
32
+ }
33
+ }
34
+ }
35
+ return melds;
36
+ }
37
+ /** The melds that leave the least deadwood. */
38
+ export function bestMelds(cards) {
39
+ const options = possibleMelds(cards);
40
+ let best = { melds: [], deadwood: cards.reduce((n, c) => n + ginValue(c), 0) };
41
+ const search = (from, used, chosen, melded) => {
42
+ const dead = cards.reduce((n, c) => n + ginValue(c), 0) - melded;
43
+ if (dead < best.deadwood)
44
+ best = { melds: [...chosen], deadwood: dead };
45
+ for (let i = from; i < options.length; i++) {
46
+ const m = options[i];
47
+ if (m.some((c) => used.has(c.id)))
48
+ continue;
49
+ for (const c of m)
50
+ used.add(c.id);
51
+ chosen.push(m);
52
+ search(i + 1, used, chosen, melded + m.reduce((n, c) => n + ginValue(c), 0));
53
+ chosen.pop();
54
+ for (const c of m)
55
+ used.delete(c.id);
56
+ }
57
+ };
58
+ search(0, new Set(), [], 0);
59
+ const inMelds = new Set(best.melds.flat().map((c) => c.id));
60
+ return { ...best, dead: cards.filter((c) => !inMelds.has(c.id)) };
61
+ }
62
+ /** Best deadwood after discarding the best card from 11 (and which card that is). */
63
+ function bestDiscard(cards, not) {
64
+ let best = null;
65
+ for (const c of cards) {
66
+ if (c.id === not)
67
+ continue;
68
+ const d = bestMelds(cards.filter((x) => x.id !== c.id)).deadwood;
69
+ if (!best || d < best.deadwood || (d === best.deadwood && ginValue(c) > ginValue(best.card)))
70
+ best = { card: c, deadwood: d };
71
+ }
72
+ return best;
73
+ }
74
+ /** Lay the defender's deadwood off on the knocker's melds where it fits (runs at either end, sets to four). */
75
+ export function layOff(knockerMelds, dead) {
76
+ const melds = knockerMelds.map((m) => [...m]);
77
+ const laid = [];
78
+ let left = [...dead];
79
+ let changed = true;
80
+ while (changed) {
81
+ changed = false;
82
+ for (const c of left) {
83
+ for (const m of melds) {
84
+ const isSet = m.every((x) => low(x) === low(m[0]));
85
+ const fits = isSet
86
+ ? m.length < 4 && low(c) === low(m[0])
87
+ : suitOf(c) === suitOf(m[0]) && (low(c) === Math.min(...m.map(low)) - 1 || low(c) === Math.max(...m.map(low)) + 1);
88
+ if (fits) {
89
+ m.push(c);
90
+ laid.push(c);
91
+ left = left.filter((x) => x.id !== c.id);
92
+ changed = true;
93
+ break;
94
+ }
95
+ }
96
+ if (changed)
97
+ break;
98
+ }
99
+ }
100
+ return { laid, left };
101
+ }
102
+ /** Sort a hand so its melds sit together, then the deadwood low to high. */
103
+ export function arrange(cards) {
104
+ const { melds, dead } = bestMelds(cards);
105
+ return [...melds.flatMap((m) => [...m].sort((a, b) => low(a) - low(b))), ...[...dead].sort((a, b) => low(a) - low(b) || suitOf(a).localeCompare(suitOf(b)))];
106
+ }
107
+ // ---- The game -----------------------------------------------------------------------------------
108
+ function deal(s) {
109
+ const rand = nextRandom(s);
110
+ const deck = shuffled(makeDeck({ ranks: FULL }), rand);
111
+ s.hands = [arrange(deck.slice(0, 10)), arrange(deck.slice(10, 20))];
112
+ s.discard = [deck[20]];
113
+ s.stock = deck.slice(21);
114
+ s.turn = (s.dealer + 1) % 2;
115
+ s.phase = "draw";
116
+ s.taken = null;
117
+ s.ready = [false, false];
118
+ s.narration = null;
119
+ }
120
+ export function newGin(rules, _seats, seed) {
121
+ const s = { game: "gin", rules, seats: 2, rng: seed >>> 0, hand: 0, dealer: seed % 2, scores: [0, 0], lastHand: null };
122
+ deal(s);
123
+ return s;
124
+ }
125
+ function apply(state, seat, move) {
126
+ const s = clone(state);
127
+ switch (move.type) {
128
+ case "next": {
129
+ if (s.phase !== "scored")
130
+ throw new GameError("The hand isn't over.");
131
+ if (markReady(s.ready, seat)) {
132
+ s.hand += 1;
133
+ s.dealer = s.lastHand?.winner ?? (s.dealer + 1) % 2;
134
+ deal(s);
135
+ }
136
+ return s;
137
+ }
138
+ case "draw":
139
+ case "take": {
140
+ if (s.phase !== "draw" || s.turn !== seat)
141
+ throw new GameError("It's not your turn to draw.");
142
+ const card = move.type === "draw" ? s.stock.pop() : s.discard.pop();
143
+ if (!card)
144
+ throw new GameError("There's nothing there.");
145
+ s.hands[seat] = arrange([...s.hands[seat], card]);
146
+ s.taken = move.type === "take" ? card.id : null;
147
+ s.phase = "discard";
148
+ s.narration = move.type === "take" ? `${who(seat)} took the ${rankLabel(rank(card))}${SYMBOL[suitOf(card)]}` : `${who(seat)} drew from the stock`;
149
+ return s;
150
+ }
151
+ case "discard":
152
+ case "knock": {
153
+ if (s.phase !== "discard" || s.turn !== seat)
154
+ throw new GameError("It's not your turn to discard.");
155
+ const id = Array.isArray(move.cards) && move.cards.length === 1 ? move.cards[0] : null;
156
+ const card = s.hands[seat].find((c) => c.id === id);
157
+ if (!card)
158
+ throw new GameError("Pick one card.");
159
+ if (card.id === s.taken)
160
+ throw new GameError("You can't throw back the card you just took.");
161
+ const rest = s.hands[seat].filter((c) => c.id !== card.id);
162
+ if (move.type === "knock") {
163
+ const { deadwood } = bestMelds(rest);
164
+ if (deadwood > s.rules.knockAt)
165
+ throw new GameError(s.rules.knockAt === 0 ? `Only gin goes out: you'd have ${deadwood} left.` : `That leaves ${deadwood} points of deadwood: you can knock with ${s.rules.knockAt} or less.`);
166
+ s.hands[seat] = rest;
167
+ s.discard.push(card);
168
+ settle(s, seat);
169
+ return s;
170
+ }
171
+ s.hands[seat] = arrange(rest);
172
+ s.discard.push(card);
173
+ s.taken = null;
174
+ // Two cards left in the stock and nobody knocked: the hand is a wash.
175
+ if (s.stock.length <= 2) {
176
+ s.lastHand = { knocker: null, gin: false, undercut: false, melds: [[], []], deadwood: [0, 0], deadCards: [[], []], laidOff: [], points: [0, 0], winner: null };
177
+ s.narration = "The stock ran down: nobody scores this hand";
178
+ s.ready = [false, false];
179
+ s.phase = "scored";
180
+ return s;
181
+ }
182
+ s.turn = (seat + 1) % 2;
183
+ s.phase = "draw";
184
+ s.narration = null;
185
+ return s;
186
+ }
187
+ default:
188
+ throw new GameError("That's not a move in Gin.");
189
+ }
190
+ }
191
+ /** Score a knock: gin, a plain knock, or an undercut. */
192
+ function settle(s, knocker) {
193
+ const other = (knocker + 1) % 2;
194
+ const mine = bestMelds(s.hands[knocker]);
195
+ const theirs = bestMelds(s.hands[other]);
196
+ const gin = mine.deadwood === 0;
197
+ const { laid, left } = gin ? { laid: [], left: theirs.dead } : layOff(mine.melds, theirs.dead);
198
+ const theirDead = left.reduce((n, c) => n + ginValue(c), 0);
199
+ const points = [0, 0];
200
+ let winner;
201
+ let undercut = false;
202
+ if (gin) {
203
+ winner = knocker;
204
+ points[knocker] = s.rules.ginBonus + theirDead;
205
+ }
206
+ else if (theirDead <= mine.deadwood) {
207
+ winner = other;
208
+ undercut = true;
209
+ points[other] = s.rules.undercutBonus + (mine.deadwood - theirDead);
210
+ }
211
+ else {
212
+ winner = knocker;
213
+ points[knocker] = theirDead - mine.deadwood;
214
+ }
215
+ s.scores = [s.scores[0] + points[0], s.scores[1] + points[1]];
216
+ const deadwood = [0, 0];
217
+ deadwood[knocker] = mine.deadwood;
218
+ deadwood[other] = theirDead;
219
+ const melds = [[], []];
220
+ melds[knocker] = mine.melds;
221
+ melds[other] = theirs.melds;
222
+ const deadCards = [[], []];
223
+ deadCards[knocker] = mine.dead;
224
+ deadCards[other] = left;
225
+ s.lastHand = { knocker, gin, undercut, melds, deadwood, deadCards, laidOff: laid, points, winner };
226
+ s.narration = gin ? `${who(knocker)} went gin! 🍸` : undercut ? `${who(knocker)} knocked, but ${who(other)} undercut! 😮` : `${who(knocker)} knocked with ${mine.deadwood}`;
227
+ s.ready = [false, false];
228
+ s.phase = s.scores.some((n) => n >= s.rules.playTo) ? "finished" : "scored";
229
+ }
230
+ function view(s, seat) {
231
+ const over = s.phase === "finished";
232
+ const mine = s.turn === seat;
233
+ const hand = s.hands[seat];
234
+ const now = bestMelds(hand);
235
+ // While discarding: could any discard knock (or go gin)?
236
+ const discarding = s.phase === "discard" && mine;
237
+ const after = discarding ? bestDiscard(hand, s.taken) : null;
238
+ const canKnock = !!after && after.deadwood <= s.rules.knockAt;
239
+ const shown = s.lastHand && (s.phase === "scored" || over);
240
+ const melds = shown
241
+ ? [0, 1].flatMap((p) => [
242
+ ...s.lastHand.melds[p].map((cards) => ({ owner: p, cards })),
243
+ ...(s.lastHand.deadCards[p].length ? [{ owner: p, label: `Deadwood ${s.lastHand.deadwood[p]}`, cards: s.lastHand.deadCards[p] }] : []),
244
+ ])
245
+ : [];
246
+ return {
247
+ game: "gin",
248
+ seats: 2,
249
+ me: seat,
250
+ teams: false,
251
+ phase: s.phase,
252
+ turn: s.phase === "draw" || s.phase === "discard" ? s.turn : null,
253
+ dealer: s.dealer,
254
+ // Once a hand is over, everyone's cards are laid out on the table as melds instead.
255
+ hand: shown ? [] : hand,
256
+ tap: null,
257
+ pick: discarding
258
+ ? {
259
+ min: 1,
260
+ max: 1,
261
+ prompt: canKnock ? (after.deadwood === 0 ? "Pick a card to discard: you can go gin!" : "Pick a card to discard, or knock") : "Pick a card to discard",
262
+ cards: hand.filter((c) => c.id !== s.taken).map((c) => c.id),
263
+ actions: [
264
+ { label: "Discard", type: "discard", primary: !canKnock },
265
+ ...(canKnock ? [{ label: after.deadwood === 0 ? "Gin! 🍸" : "Knock", type: "knock", primary: true }] : []),
266
+ ],
267
+ }
268
+ : null,
269
+ choices: s.phase === "scored" && !s.ready[seat] ? { prompt: "", options: [{ label: "Deal the next hand", move: { type: "next" }, primary: true }] } : null,
270
+ players: s.hands.map((h, i) => ({ cards: shown ? 0 : h.length, line: i === seat && !shown ? `Deadwood ${now.deadwood}` : "", dealer: i === s.dealer })),
271
+ center: {
272
+ kind: "piles",
273
+ stock: s.stock.length,
274
+ discard: s.discard.slice(-3),
275
+ discardCount: s.discard.length,
276
+ drawMove: s.phase === "draw" && mine ? { type: "draw" } : null,
277
+ takeMove: s.phase === "draw" && mine && s.discard.length ? { type: "take" } : null,
278
+ },
279
+ melds,
280
+ info: [
281
+ ...(!shown ? [`Your melds: ${now.melds.length} · deadwood ${now.deadwood}`] : []),
282
+ s.rules.knockAt > 0 ? `Knock with ${s.rules.knockAt} or less` : "Gin only",
283
+ `To ${s.rules.playTo}`,
284
+ ],
285
+ narration: s.narration ?? (s.phase === "draw" && mine ? "Draw from the stock, or take the top discard" : null),
286
+ scores: [
287
+ { seats: [0], value: s.scores[0] },
288
+ { seats: [1], value: s.scores[1] },
289
+ ],
290
+ result: shown
291
+ ? {
292
+ key: `gin-${s.hand}`,
293
+ title: s.lastHand.knocker === null ? "No score this hand" : s.lastHand.gin ? `${who(s.lastHand.knocker)} went gin! 🍸` : s.lastHand.undercut ? `Undercut! ${who(s.lastHand.winner)} wins the hand` : `${who(s.lastHand.knocker)} knocked and won`,
294
+ sides: [[0], [1]],
295
+ rows: [
296
+ { label: "Deadwood", values: s.lastHand.deadwood.map(String) },
297
+ { label: "This hand", values: s.lastHand.points.map((p) => (p > 0 ? `+${p}` : "0")), tone: "score" },
298
+ { label: "Score", values: s.scores.map(String), tone: "total" },
299
+ ],
300
+ }
301
+ : null,
302
+ over: over ? { winners: [s.scores[0] >= s.scores[1] ? 0 : 1], title: `${who(s.scores[0] >= s.scores[1] ? 0 : 1)} wins ${Math.max(...s.scores)} to ${Math.min(...s.scores)}` } : null,
303
+ };
304
+ }
305
+ // ---- Computer players --------------------------------------------------------------------------
306
+ function bot(s, seat, style) {
307
+ if (s.phase === "scored")
308
+ return s.ready[seat] ? null : { type: "next" };
309
+ if (s.turn !== seat)
310
+ return null;
311
+ const sloppy = Math.random() < (style.sloppy ?? 0) + (1 - (style.skill ?? 1)) * 0.3;
312
+ const hand = s.hands[seat];
313
+ if (s.phase === "draw") {
314
+ const top = s.discard[s.discard.length - 1];
315
+ if (!top || sloppy)
316
+ return { type: "draw" };
317
+ // Take the discard when it makes the hand better than it is now.
318
+ const now = bestMelds(hand).deadwood;
319
+ const withIt = bestDiscard([...hand, top], top.id).deadwood;
320
+ return withIt < now - 1 || bestMelds([...hand, top]).melds.some((m) => m.some((c) => c.id === top.id)) ? { type: "take" } : { type: "draw" };
321
+ }
322
+ if (s.phase !== "discard")
323
+ return null;
324
+ const best = sloppy ? { card: hand.filter((c) => c.id !== s.taken)[Math.floor(Math.random() * (hand.length - (s.taken ? 1 : 0)))], deadwood: 99 } : bestDiscard(hand, s.taken);
325
+ const deadwood = bestMelds(hand.filter((c) => c.id !== best.card.id)).deadwood;
326
+ // Knock right away with gin or a small count; with more, wait for a better hand while the stock is deep.
327
+ const knock = deadwood <= s.rules.knockAt && (deadwood === 0 || deadwood <= 4 || s.stock.length < 16 + (style.bold ?? 0) * 8);
328
+ return { type: knock ? "knock" : "discard", cards: [best.card.id] };
329
+ }
330
+ export const gin = {
331
+ id: "gin",
332
+ name: "Gin Rummy",
333
+ emoji: "🍸",
334
+ blurb: "Two players, melds and knocking",
335
+ tagline: "Make sets and runs. Knock with 10 or less, or go gin with none.",
336
+ seats: { min: 2, max: 2, default: 2 },
337
+ teams: false,
338
+ presets: [classicGin, quickGin, straightGin],
339
+ fields: [
340
+ { key: "playTo", label: "Game to", kind: "choice", options: [[50, "50"], [100, "100"], [150, "150"]] },
341
+ { key: "knockAt", label: "Knock with", kind: "choice", options: [[10, "10 or less"], [5, "5 or less"], [0, "Gin only"]] },
342
+ { key: "ginBonus", label: "Gin bonus", kind: "choice", options: [[20, "20"], [25, "25"], [31, "31"]] },
343
+ { key: "undercutBonus", label: "Undercut bonus", kind: "choice", options: [[10, "10"], [20, "20"], [25, "25"]] },
344
+ ],
345
+ normalize(rules) {
346
+ const given = (rules && typeof rules === "object" ? rules : {});
347
+ const base = [classicGin, quickGin, straightGin].find((p) => p.id === given.id) ?? classicGin;
348
+ return { ...base, ...given };
349
+ },
350
+ validate(r) {
351
+ const errors = [];
352
+ if (!(r.playTo >= 25 && r.playTo <= 500))
353
+ errors.push("Play to between 25 and 500.");
354
+ if (!(r.knockAt >= 0 && r.knockAt <= 10))
355
+ errors.push("Knock with 0 to 10.");
356
+ return errors;
357
+ },
358
+ describe(r) {
359
+ return [
360
+ "Two players, ten cards each. On your turn, draw from the stock or take the top discard, then discard one.",
361
+ "Make melds: three or four of a rank, or three or more in a row in one suit (ace is low). Cards not in a meld are deadwood: aces 1, faces 10, others their number.",
362
+ r.knockAt > 0 ? `Knock with ${r.knockAt} or less deadwood; the other player lays cards off on your melds. You score the difference. If they have as little as you, they undercut you for ${r.undercutBonus} plus the difference.` : "Only gin goes out.",
363
+ `Gin (no deadwood) scores ${r.ginBonus} plus the other player's deadwood. First to ${r.playTo} wins.`,
364
+ "Your melds are found for you: your hand is sorted with them together.",
365
+ ];
366
+ },
367
+ newGame: newGin,
368
+ apply,
369
+ view,
370
+ bot,
371
+ thinkingTime(s) {
372
+ if (s.phase === "scored")
373
+ return 900;
374
+ return s.phase === "draw" ? 1100 : thinkFor(6);
375
+ },
376
+ summary(s) {
377
+ const over = s.phase === "finished";
378
+ const w = s.scores[0] >= s.scores[1] ? 0 : 1;
379
+ return {
380
+ game: "gin",
381
+ rules: s.rules.name,
382
+ phase: s.phase,
383
+ over,
384
+ hand: s.hand + 1,
385
+ scoreLine: `${s.scores[0]} to ${s.scores[1]}`,
386
+ order: over ? rankSeats([{ seats: [0], score: s.scores[0] }, { seats: [1], score: s.scores[1] }]) : null,
387
+ winners: over ? [w] : null,
388
+ teams: false,
389
+ seats: 2,
390
+ };
391
+ },
392
+ };
393
+ //# sourceMappingURL=gin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gin.js","sourceRoot":"","sources":["../src/gin.ts"],"names":[],"mappings":"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"}
package/dist/go.d.ts ADDED
@@ -0,0 +1,132 @@
1
+ import type { BoardGame } from "./board.js";
2
+ import { type GoCount, type Stone } from "./goboard.js";
3
+ import { type BaseRules, type SummaryRow, type ThinkBudget } from "./table.js";
4
+ export interface GoRules extends BaseRules {
5
+ /** The board is size × size lines. */
6
+ size: number;
7
+ /** How the game is counted: "area" (Chinese: stones and surrounded points) or "territory" (Japanese: surrounded points and prisoners). */
8
+ scoring: "area" | "territory";
9
+ /** Points White is given for moving second. A whole number allows a drawn game. */
10
+ komi: number;
11
+ /** Stones Black starts with on the star points (2 to 9; 1 is just "no komi"). With any handicap White gets half a point and no more. */
12
+ handicap: number;
13
+ /** Who plays Black in the first game. */
14
+ black: "random" | "seat1" | "seat2";
15
+ /** What may not be repeated: any earlier position of the board ("superko"), or only the position before the last move ("simple"). */
16
+ ko: "superko" | "simple";
17
+ /** A move that leaves its own group without a liberty is allowed, and takes that group off. */
18
+ suicide: boolean;
19
+ /** Games in a match: most wins takes it. */
20
+ games: number;
21
+ }
22
+ export declare const smallGo: GoRules;
23
+ export declare const mediumGo: GoRules;
24
+ export declare const fullGo: GoRules;
25
+ export declare const japaneseGo: GoRules;
26
+ /** What White is actually given at a table: the komi, or half a point when Black has a handicap. */
27
+ export declare const komiOf: (r: Pick<GoRules, "komi" | "handicap">) => number;
28
+ export interface GoState {
29
+ game: "go";
30
+ rules: GoRules;
31
+ seats: number;
32
+ rng: number;
33
+ /** Which game of the match, from 1. */
34
+ round: number;
35
+ /** The seat playing Black in this game. */
36
+ black: number;
37
+ /** The board, a character a crossing, row by row from the top left: "." empty, "X" black, "O" white. */
38
+ board: string;
39
+ turn: number;
40
+ /** Stones and passes played in this game. */
41
+ moves: number;
42
+ /** Passes in a row just now. */
43
+ passes: number;
44
+ /** Somebody has passed in this game (the first pass is asked about before it is sent). */
45
+ passed: boolean;
46
+ /** Where the last stone went down; null at the start and after a pass. */
47
+ last: number | null;
48
+ /** The crossing that can't be played this turn because it would take a ko straight back. */
49
+ ko: number | null;
50
+ /** Stones each seat has captured. */
51
+ captured: number[];
52
+ /**
53
+ * The hash of every position this game's board has been in (see `GoBoard.hash`), for the superko
54
+ * rule. Hashes, not boards: a few bytes a move. Empty when the table plays simple ko.
55
+ */
56
+ seen: number[];
57
+ /**
58
+ * "counting": play has stopped and the players are agreeing which stones are dead.
59
+ * "scored": between games of a match. "finished": the match (or the one game) is over.
60
+ */
61
+ phase: "playing" | "counting" | "scored" | "finished";
62
+ /** While counting, and after: the stones marked dead, as cells. */
63
+ dead: number[];
64
+ /** While counting: who has agreed to the marking as it stands. */
65
+ agreed: boolean[];
66
+ /** How many times the counting has been broken off to play on, in this game. */
67
+ resumes: number;
68
+ /** The count each seat finished with, komi included; null while playing, and for a game that was resigned. */
69
+ score: number[] | null;
70
+ /** Who won the game just played; null for a draw (or while playing). */
71
+ roundWinner: number | null;
72
+ wins: number[];
73
+ draws: number;
74
+ ready: boolean[];
75
+ narration: string | null;
76
+ }
77
+ export type GoMove = {
78
+ type: "place";
79
+ cell: number;
80
+ } | {
81
+ type: "pass";
82
+ } | {
83
+ type: "toggle";
84
+ cell: number;
85
+ } | {
86
+ type: "agree";
87
+ } | {
88
+ type: "resume";
89
+ } | {
90
+ type: "next";
91
+ };
92
+ /** A crossing's name: "D4", "Q16". */
93
+ export declare const goPoint: (n: number, cell: number) => string;
94
+ /** Every crossing `seat` may play now. */
95
+ export declare function legalGoMoves(s: GoState, seat: number): number[];
96
+ /**
97
+ * The game's own view of which stones are dead: every group that ends up the other side's in most
98
+ * of a batch of games played out from here (goboard.ts). It depends on the position and nothing
99
+ * else, so it replays, and a computer player asked what it thinks gets the same answer.
100
+ */
101
+ export declare function proposedDead(s: Pick<GoState, "board" | "rules" | "ko" | "last">, toMove: Stone): number[];
102
+ export interface GoScore {
103
+ count: GoCount;
104
+ /** Each seat's total, komi included. */
105
+ totals: number[];
106
+ /** What each seat's total is made of, in the order it is read out. */
107
+ rows: SummaryRow[];
108
+ }
109
+ /** The count of a state's board with `dead` lifted off, under the table's scoring. */
110
+ export declare function scoreGo(s: Pick<GoState, "board" | "rules" | "black" | "captured">, dead: readonly number[]): GoScore;
111
+ export declare function newGo(rules: GoRules, _seats: number, seed: number): GoState;
112
+ /** How hard a computer player looks: the most games it plays out, and when it has to stop. */
113
+ export interface GoEffort {
114
+ playouts: number;
115
+ /** A `performance.now()` time; left out when only the count stops the search. */
116
+ deadline?: number;
117
+ }
118
+ /** A player at full skill gets the whole ration; one at no skill about an eightieth of it. */
119
+ export declare function goEffort(n: number, skill: number, budget?: ThinkBudget): GoEffort;
120
+ /**
121
+ * The computer player's move in a game being played: a crossing, or a pass. `effort` says how hard
122
+ * to look (tests and measurements give their own); the dice come from `rand`.
123
+ */
124
+ export declare function goBotMove(s: GoState, seat: number, effort: GoEffort, rand?: () => number, sloppy?: boolean): GoMove;
125
+ /**
126
+ * Go, with resigning (the usual way a game of Go ends), taking a move back, and draw offers (see
127
+ * offers.ts). A draw by agreement is not really a thing in Go, but the kit's house rule offers
128
+ * draws and take-backs together or not at all, and a family table wants the take-back: a table
129
+ * that wants neither sets Offers to "Neither". Only the last turn and the reply to it can be had
130
+ * back (`history: 2`): every position kept is another copy of the game's list of hashes.
131
+ */
132
+ export declare const go: BoardGame<GoRules & import("./offers.js").OfferRules, import("./offers.js").WithOffers<GoState>, import("./offers.js").OfferMove | GoMove>;