@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Tally } from "./drinks.js";
|
|
2
|
+
import { type BaseRules, type CardGame, type KCard } from "./kit.js";
|
|
3
|
+
export interface BusRules extends BaseRules {
|
|
4
|
+
/** Wrong guesses on the bus before it lets you off anyway. */
|
|
5
|
+
busLimit: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const classicBus: BusRules;
|
|
8
|
+
export declare const longBus: BusRules;
|
|
9
|
+
export interface BusState {
|
|
10
|
+
game: "ridethebus";
|
|
11
|
+
rules: BusRules;
|
|
12
|
+
seats: number;
|
|
13
|
+
rng: number;
|
|
14
|
+
hand: number;
|
|
15
|
+
dealer: number;
|
|
16
|
+
phase: "guess" | "pyramid" | "bus" | "finished";
|
|
17
|
+
hands: KCard[][];
|
|
18
|
+
deck: KCard[];
|
|
19
|
+
/** Round one: which question (0–3) everyone is on. */
|
|
20
|
+
question: number;
|
|
21
|
+
turn: number;
|
|
22
|
+
/** The pyramid: 4, 3, 2, 1 cards from the bottom; null not turned yet. */
|
|
23
|
+
pyramid: (KCard | null)[];
|
|
24
|
+
hidden: KCard[];
|
|
25
|
+
flipped: number;
|
|
26
|
+
rider: number | null;
|
|
27
|
+
/** The bus: the cards so far this try, and wrong guesses. */
|
|
28
|
+
bus: KCard[];
|
|
29
|
+
wrongs: number;
|
|
30
|
+
tally: Tally;
|
|
31
|
+
last: KCard | null;
|
|
32
|
+
narration: string | null;
|
|
33
|
+
}
|
|
34
|
+
export declare const QUESTIONS: string[];
|
|
35
|
+
export declare function newBus(rules: BusRules, seats: number, seed: number): BusState;
|
|
36
|
+
/** Is the guess right for the next card, given the cards so far? */
|
|
37
|
+
export declare function guessRight(so: KCard[], guess: string, c: KCard): boolean;
|
|
38
|
+
type Move = {
|
|
39
|
+
type: "guess";
|
|
40
|
+
guess: string;
|
|
41
|
+
} | {
|
|
42
|
+
type: "flip";
|
|
43
|
+
} | {
|
|
44
|
+
type: "give";
|
|
45
|
+
to: number;
|
|
46
|
+
};
|
|
47
|
+
export declare const rideTheBus: CardGame<BusRules, BusState, Move>;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { botGiveTarget, drink, DRINK_NOTE, giveChoices, giveTo, newTally } from "./drinks.js";
|
|
2
|
+
import { clone, FULL, GameError, makeDeck, nextRandom, rankLabel, rankSeats, shuffled, SUITS, SYMBOL, who } from "./kit.js";
|
|
3
|
+
export const classicBus = { id: "bus-classic", name: "Ride the Bus", busLimit: 8 };
|
|
4
|
+
export const longBus = { ...classicBus, id: "bus-long", name: "No mercy (the bus doesn't stop)", busLimit: 30 };
|
|
5
|
+
const rank = (c) => c.rank;
|
|
6
|
+
const suitOf = (c) => c.suit;
|
|
7
|
+
const red = (c) => suitOf(c) === "hearts" || suitOf(c) === "diamonds";
|
|
8
|
+
const label = (c) => `${rankLabel(rank(c))}${SYMBOL[suitOf(c)]}`;
|
|
9
|
+
const ROW = [1, 1, 1, 1, 2, 2, 2, 3, 3, 4];
|
|
10
|
+
export const QUESTIONS = ["Red or black?", "Higher or lower?", "Inside or outside?", "Which suit?"];
|
|
11
|
+
function draw(s) {
|
|
12
|
+
if (!s.deck.length) {
|
|
13
|
+
const held = new Set([...s.hands.flat(), ...s.bus, ...s.pyramid.filter(Boolean), ...s.hidden].map((c) => c.id));
|
|
14
|
+
s.deck = shuffled(makeDeck({ ranks: FULL }).filter((c) => !held.has(c.id)), nextRandom(s));
|
|
15
|
+
}
|
|
16
|
+
return s.deck.pop();
|
|
17
|
+
}
|
|
18
|
+
export function newBus(rules, seats, seed) {
|
|
19
|
+
const s = { game: "ridethebus", rules, seats, rng: seed >>> 0, hand: 0, dealer: seed % seats, phase: "guess", question: 0, pyramid: Array(10).fill(null), hidden: [], flipped: 0, rider: null, bus: [], wrongs: 0, last: null, narration: null };
|
|
20
|
+
s.deck = shuffled(makeDeck({ ranks: FULL }), nextRandom(s));
|
|
21
|
+
s.hands = Array.from({ length: seats }, () => []);
|
|
22
|
+
s.tally = newTally(seats);
|
|
23
|
+
s.turn = (s.dealer + 1) % seats;
|
|
24
|
+
s.narration = `Round one: ${QUESTIONS[0]}`;
|
|
25
|
+
return s;
|
|
26
|
+
}
|
|
27
|
+
/** Is the guess right for the next card, given the cards so far? */
|
|
28
|
+
export function guessRight(so, guess, c) {
|
|
29
|
+
switch (so.length) {
|
|
30
|
+
case 0:
|
|
31
|
+
return guess === (red(c) ? "red" : "black");
|
|
32
|
+
case 1:
|
|
33
|
+
return guess === "higher" ? rank(c) > rank(so[0]) : rank(c) < rank(so[0]);
|
|
34
|
+
case 2: {
|
|
35
|
+
const lo = Math.min(rank(so[0]), rank(so[1]));
|
|
36
|
+
const hi = Math.max(rank(so[0]), rank(so[1]));
|
|
37
|
+
return guess === "inside" ? rank(c) > lo && rank(c) < hi : rank(c) < lo || rank(c) > hi;
|
|
38
|
+
}
|
|
39
|
+
default:
|
|
40
|
+
return guess === suitOf(c);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const optionsFor = (n) => n === 0
|
|
44
|
+
? [{ label: "Red", move: { type: "guess", guess: "red" } }, { label: "Black", move: { type: "guess", guess: "black" } }]
|
|
45
|
+
: n === 1
|
|
46
|
+
? [{ label: "Higher", move: { type: "guess", guess: "higher" } }, { label: "Lower", move: { type: "guess", guess: "lower" } }]
|
|
47
|
+
: n === 2
|
|
48
|
+
? [{ label: "Inside", move: { type: "guess", guess: "inside" } }, { label: "Outside", move: { type: "guess", guess: "outside" } }]
|
|
49
|
+
: SUITS.map((x) => ({ label: SYMBOL[x], move: { type: "guess", guess: x } }));
|
|
50
|
+
function startPyramid(s) {
|
|
51
|
+
s.phase = "pyramid";
|
|
52
|
+
s.hidden = Array.from({ length: 10 }, () => draw(s));
|
|
53
|
+
s.turn = s.dealer;
|
|
54
|
+
s.narration = "Round two: the pyramid. Match a card and hand out drinks";
|
|
55
|
+
}
|
|
56
|
+
function startBus(s) {
|
|
57
|
+
const most = Math.max(...s.hands.map((h) => h.length));
|
|
58
|
+
const riders = s.hands.flatMap((h, i) => (h.length === most ? [i] : []));
|
|
59
|
+
s.rider = riders[nextRandom(s)() * riders.length | 0];
|
|
60
|
+
s.phase = "bus";
|
|
61
|
+
s.turn = s.rider;
|
|
62
|
+
s.bus = [];
|
|
63
|
+
s.wrongs = 0;
|
|
64
|
+
s.narration = `${who(s.rider)} has the most cards left and rides the bus! 🚌`;
|
|
65
|
+
}
|
|
66
|
+
function apply(state, seat, move) {
|
|
67
|
+
const s = clone(state);
|
|
68
|
+
if (s.phase === "finished")
|
|
69
|
+
throw new GameError("The game is over.");
|
|
70
|
+
if (move.type === "give") {
|
|
71
|
+
if (!s.tally.give.length || s.tally.give[0].from !== seat)
|
|
72
|
+
throw new GameError("You have no drinks to hand out.");
|
|
73
|
+
try {
|
|
74
|
+
s.narration = giveTo(s.tally, seat, Number(move.to), s.seats);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
throw new GameError("Pick someone else to drink.");
|
|
78
|
+
}
|
|
79
|
+
if (s.phase === "pyramid" && !s.tally.give.length && s.flipped === 10)
|
|
80
|
+
startBus(s);
|
|
81
|
+
return s;
|
|
82
|
+
}
|
|
83
|
+
if (s.tally.give.length)
|
|
84
|
+
throw new GameError(`Waiting for ${who(s.tally.give[0].from)} to hand out drinks.`);
|
|
85
|
+
if (s.turn !== seat)
|
|
86
|
+
throw new GameError("It's not your turn.");
|
|
87
|
+
if (move.type === "guess") {
|
|
88
|
+
if (s.phase === "guess") {
|
|
89
|
+
const so = s.hands[seat];
|
|
90
|
+
const c = draw(s);
|
|
91
|
+
const right = guessRight(so, String(move.guess), c);
|
|
92
|
+
so.push(c);
|
|
93
|
+
s.last = c;
|
|
94
|
+
const n = s.question + 1;
|
|
95
|
+
if (right) {
|
|
96
|
+
s.tally.give.push({ from: seat, n, why: `Right (${label(c)})` });
|
|
97
|
+
s.narration = `${who(seat)} called it: the ${label(c)}!`;
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
s.narration = `${who(seat)} guessed wrong: the ${label(c)} · ${drink(s.tally, [seat], n)}`;
|
|
101
|
+
// Next player; after everyone, the next question.
|
|
102
|
+
s.turn = (seat + 1) % s.seats;
|
|
103
|
+
if (s.turn === (s.dealer + 1) % s.seats) {
|
|
104
|
+
s.question += 1;
|
|
105
|
+
if (s.question === 4)
|
|
106
|
+
startPyramid(s);
|
|
107
|
+
else
|
|
108
|
+
s.narration += ` · Next: ${QUESTIONS[s.question]}`;
|
|
109
|
+
}
|
|
110
|
+
return s;
|
|
111
|
+
}
|
|
112
|
+
if (s.phase === "bus") {
|
|
113
|
+
const c = draw(s);
|
|
114
|
+
const right = guessRight(s.bus, String(move.guess), c);
|
|
115
|
+
s.last = c;
|
|
116
|
+
if (right) {
|
|
117
|
+
s.bus.push(c);
|
|
118
|
+
if (s.bus.length === 4) {
|
|
119
|
+
s.phase = "finished";
|
|
120
|
+
s.narration = `${who(seat)} got off the bus! 🎉`;
|
|
121
|
+
}
|
|
122
|
+
else
|
|
123
|
+
s.narration = `Right: the ${label(c)}. ${QUESTIONS[s.bus.length]}`;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const n = s.bus.length + 1;
|
|
127
|
+
s.wrongs += 1;
|
|
128
|
+
s.bus = [];
|
|
129
|
+
s.narration = `Wrong: the ${label(c)} · ${drink(s.tally, [seat], n)} · back to the start`;
|
|
130
|
+
if (s.wrongs >= s.rules.busLimit) {
|
|
131
|
+
s.phase = "finished";
|
|
132
|
+
s.narration += `. That's ${s.wrongs} wrong: the driver lets ${who(seat)} off 😅`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return s;
|
|
136
|
+
}
|
|
137
|
+
throw new GameError("It's not time to guess.");
|
|
138
|
+
}
|
|
139
|
+
if (move.type === "flip") {
|
|
140
|
+
if (s.phase !== "pyramid")
|
|
141
|
+
throw new GameError("It's not time to turn the pyramid.");
|
|
142
|
+
const k = s.flipped;
|
|
143
|
+
const c = s.hidden[k];
|
|
144
|
+
s.pyramid[k] = c;
|
|
145
|
+
s.flipped += 1;
|
|
146
|
+
s.last = c;
|
|
147
|
+
const n = ROW[k];
|
|
148
|
+
const parts = [];
|
|
149
|
+
for (let i = 0; i < s.seats; i++) {
|
|
150
|
+
const matches = s.hands[i].filter((x) => rank(x) === rank(c));
|
|
151
|
+
if (!matches.length)
|
|
152
|
+
continue;
|
|
153
|
+
s.hands[i] = s.hands[i].filter((x) => rank(x) !== rank(c));
|
|
154
|
+
s.tally.give.push({ from: i, n: n * matches.length, why: `Matched the ${rankLabel(rank(c))}` });
|
|
155
|
+
parts.push(who(i));
|
|
156
|
+
}
|
|
157
|
+
s.narration = `Row ${n}: the ${label(c)}${parts.length ? ` · ${parts.join(" and ")} hand${parts.length === 1 ? "s" : ""} out drinks` : " · no matches"}`;
|
|
158
|
+
if (s.flipped === 10 && !s.tally.give.length)
|
|
159
|
+
startBus(s);
|
|
160
|
+
return s;
|
|
161
|
+
}
|
|
162
|
+
throw new GameError("That's not a move in Ride the Bus.");
|
|
163
|
+
}
|
|
164
|
+
function view(s, seat) {
|
|
165
|
+
const over = s.phase === "finished";
|
|
166
|
+
const give = giveChoices(s.tally, s.seats, seat);
|
|
167
|
+
const waiting = s.tally.give.length > 0;
|
|
168
|
+
let choices = give;
|
|
169
|
+
if (!waiting && !over && s.turn === seat) {
|
|
170
|
+
if (s.phase === "guess")
|
|
171
|
+
choices = { prompt: QUESTIONS[s.question], options: optionsFor(s.question), layout: "row" };
|
|
172
|
+
else if (s.phase === "bus")
|
|
173
|
+
choices = { prompt: `On the bus: ${QUESTIONS[s.bus.length]}`, options: optionsFor(s.bus.length), layout: "row" };
|
|
174
|
+
else if (s.phase === "pyramid")
|
|
175
|
+
choices = { prompt: "", options: [{ label: "Turn the next card", move: { type: "flip" }, primary: true }] };
|
|
176
|
+
}
|
|
177
|
+
// The pyramid, top row first: 1, 2, 3, 4 cards.
|
|
178
|
+
const rows = [[9], [7, 8], [4, 5, 6], [0, 1, 2, 3]].map((row) => row.map((pos) => s.pyramid[pos] ?? "back"));
|
|
179
|
+
const nobody = s.phase !== "pyramid" && s.flipped === 0;
|
|
180
|
+
return {
|
|
181
|
+
game: "ridethebus",
|
|
182
|
+
seats: s.seats,
|
|
183
|
+
me: seat,
|
|
184
|
+
teams: false,
|
|
185
|
+
phase: s.phase,
|
|
186
|
+
turn: over ? null : waiting ? s.tally.give[0].from : s.turn,
|
|
187
|
+
dealer: s.dealer,
|
|
188
|
+
hand: seat === s.rider && s.phase === "bus" ? s.bus : s.hands[seat],
|
|
189
|
+
tap: null,
|
|
190
|
+
pick: null,
|
|
191
|
+
choices,
|
|
192
|
+
players: s.hands.map((h, i) => ({ cards: i === seat ? (seat === s.rider && s.phase === "bus" ? s.bus.length : h.length) : h.length, line: `🍺 ${s.tally.drank[i]}${i === s.rider ? " · on the bus 🚌" : ""}`, dealer: i === s.dealer })),
|
|
193
|
+
center: nobody
|
|
194
|
+
? { kind: "piles", stock: s.deck.length, discard: s.last ? [s.last] : [], discardCount: s.last ? 1 : 0, drawMove: null, takeMove: null, discardLabel: s.last ? "Last card" : "" }
|
|
195
|
+
: { kind: "pyramid", rows, tap: null, held: null, stock: 0, waste: null, drawMove: null, stockLabel: "", noStock: true },
|
|
196
|
+
melds: s.phase === "guess" ? s.hands.flatMap((h, i) => (i !== seat && h.length ? [{ owner: i, label: "", cards: h }] : [])) : s.phase === "bus" && seat !== s.rider ? [{ owner: s.rider, label: "On the bus", cards: s.bus }] : [],
|
|
197
|
+
info: [s.phase === "guess" ? `Round one, question ${s.question + 1} of 4` : s.phase === "pyramid" ? `The pyramid: ${s.flipped} of 10 turned` : s.phase === "bus" ? `${who(s.rider)} is on the bus: ${s.bus.length} of 4 right` : "Done!", DRINK_NOTE],
|
|
198
|
+
narration: s.narration,
|
|
199
|
+
scores: s.tally.drank.map((value, i) => ({ seats: [i], value })),
|
|
200
|
+
result: null,
|
|
201
|
+
over: over ? { winners: s.hands.map((_, i) => i).filter((i) => i !== s.rider), title: `${who(s.rider)} rode the bus. Everyone else wins!` } : null,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function bot(s, seat, _style) {
|
|
205
|
+
if (s.phase === "finished")
|
|
206
|
+
return null;
|
|
207
|
+
if (s.tally.give.length)
|
|
208
|
+
return s.tally.give[0].from === seat ? { type: "give", to: botGiveTarget(s.tally, seat, s.seats) } : null;
|
|
209
|
+
if (s.turn !== seat)
|
|
210
|
+
return null;
|
|
211
|
+
if (s.phase === "pyramid")
|
|
212
|
+
return { type: "flip" };
|
|
213
|
+
const so = s.phase === "bus" ? s.bus : s.hands[seat];
|
|
214
|
+
const n = so.length;
|
|
215
|
+
if (n === 0)
|
|
216
|
+
return { type: "guess", guess: Math.random() < 0.5 ? "red" : "black" };
|
|
217
|
+
if (n === 1)
|
|
218
|
+
return { type: "guess", guess: rank(so[0]) >= 8 ? "lower" : "higher" };
|
|
219
|
+
if (n === 2)
|
|
220
|
+
return { type: "guess", guess: Math.abs(rank(so[0]) - rank(so[1])) >= 7 ? "inside" : "outside" };
|
|
221
|
+
const counts = SUITS.map((x) => ({ x, n: so.filter((c) => suitOf(c) === x).length }));
|
|
222
|
+
return { type: "guess", guess: counts.sort((a, b) => a.n - b.n)[0].x };
|
|
223
|
+
}
|
|
224
|
+
export const rideTheBus = {
|
|
225
|
+
id: "ridethebus",
|
|
226
|
+
name: "Ride the Bus",
|
|
227
|
+
emoji: "🚌",
|
|
228
|
+
blurb: "Drinking game: guess, match, and don't ride the bus",
|
|
229
|
+
tagline: "A drinking game. Guess your four cards, match the pyramid, and whoever's left holding the most rides the bus.",
|
|
230
|
+
seats: { min: 2, max: 8, default: 4 },
|
|
231
|
+
teams: false,
|
|
232
|
+
presets: [classicBus, longBus],
|
|
233
|
+
fields: [{ key: "busLimit", label: "The bus lets you off after", kind: "choice", options: [[5, "5 wrong guesses"], [8, "8 wrong guesses"], [30, "Never (no mercy)"]] }],
|
|
234
|
+
normalize(rules) {
|
|
235
|
+
const given = (rules && typeof rules === "object" ? rules : {});
|
|
236
|
+
const base = [classicBus, longBus].find((p) => p.id === given.id) ?? classicBus;
|
|
237
|
+
const r = { ...base, ...given };
|
|
238
|
+
return { ...r, busLimit: Math.max(1, Number(r.busLimit) || 8) };
|
|
239
|
+
},
|
|
240
|
+
validate: () => [],
|
|
241
|
+
describe: (r) => [
|
|
242
|
+
`${DRINK_NOTE} Adults only.`,
|
|
243
|
+
"Round one, four times round the table: red or black? Higher or lower than your first card? Inside or outside your first two? Which suit? Right: hand out that many drinks (1, 2, 3, 4). Wrong: drink them.",
|
|
244
|
+
"Round two: a pyramid of ten cards is turned over, bottom row first. Hold a card of the same rank? Hand out drinks: 1 a card on the bottom row, up to 4 at the top. The card goes on the pyramid.",
|
|
245
|
+
`Whoever has the most cards left rides the bus: the four guesses again with new cards. Every wrong guess, drink and start over, until all four in a row are right${r.busLimit < 30 ? ` (or ${r.busLimit} wrong guesses, when the driver takes pity)` : ""}.`,
|
|
246
|
+
],
|
|
247
|
+
newGame: newBus,
|
|
248
|
+
apply,
|
|
249
|
+
view,
|
|
250
|
+
bot,
|
|
251
|
+
thinkingTime: (s) => (s.tally.give.length ? 1200 : s.phase === "pyramid" ? 1500 : 1300),
|
|
252
|
+
summary(s) {
|
|
253
|
+
const over = s.phase === "finished";
|
|
254
|
+
return { game: "ridethebus", rules: s.rules.name, phase: s.phase, over, hand: 1, scoreLine: s.tally.drank.join(" · ") + " drinks", order: over ? rankSeats(s.tally.drank.map((score, i) => ({ seats: [i], score })), true) : null, winners: over ? s.hands.map((_, i) => i).filter((i) => i !== s.rider) : null, teams: false, seats: s.seats };
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=ridethebus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ridethebus.js","sourceRoot":"","sources":["../src/ridethebus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type BaseRules, type CardGame, type KCard } from "./kit.js";
|
|
2
|
+
export interface Rummy500Rules extends BaseRules {
|
|
3
|
+
playTo: number;
|
|
4
|
+
/** Taking only the top card of the pile still means melding it this turn. */
|
|
5
|
+
topMustMeld: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const classicRummy500: Rummy500Rules;
|
|
8
|
+
export declare const quickRummy500: Rummy500Rules;
|
|
9
|
+
export declare const strictRummy500: Rummy500Rules;
|
|
10
|
+
type Phase = "draw" | "meld" | "scored" | "finished";
|
|
11
|
+
/** A meld on the table, with who put each card down (they score it). */
|
|
12
|
+
export interface TableMeld {
|
|
13
|
+
kind: "set" | "run";
|
|
14
|
+
owner: number;
|
|
15
|
+
cards: {
|
|
16
|
+
card: KCard;
|
|
17
|
+
by: number;
|
|
18
|
+
}[];
|
|
19
|
+
}
|
|
20
|
+
export interface Rummy500State {
|
|
21
|
+
game: "rummy500";
|
|
22
|
+
rules: Rummy500Rules;
|
|
23
|
+
seats: number;
|
|
24
|
+
rng: number;
|
|
25
|
+
hand: number;
|
|
26
|
+
dealer: number;
|
|
27
|
+
phase: Phase;
|
|
28
|
+
hands: KCard[][];
|
|
29
|
+
stock: KCard[];
|
|
30
|
+
/** The discard pile, oldest first: it's spread out so every card shows. */
|
|
31
|
+
pile: KCard[];
|
|
32
|
+
melds: TableMeld[];
|
|
33
|
+
turn: number;
|
|
34
|
+
/**
|
|
35
|
+
* A card taken from the pile that must be melded this turn, and how to put things back. The way
|
|
36
|
+
* back stays open until that card is melded, so a card that turns out to fit nowhere never ends
|
|
37
|
+
* the game for you: putting it back also lifts anything melded since.
|
|
38
|
+
*/
|
|
39
|
+
mustUse: string | null;
|
|
40
|
+
/** How to put a pile take back: the pile, hand and melds as they were before it. Kept until
|
|
41
|
+
* the owed card is melded, so melding other cards first doesn't strand the player. */
|
|
42
|
+
undo: {
|
|
43
|
+
pile: KCard[];
|
|
44
|
+
hand: KCard[];
|
|
45
|
+
melds?: TableMeld[];
|
|
46
|
+
} | null;
|
|
47
|
+
/** A pile card put back this turn: it isn't taken again until the turn is over. */
|
|
48
|
+
declined: string | null;
|
|
49
|
+
scores: number[];
|
|
50
|
+
lastHand: {
|
|
51
|
+
melded: number[];
|
|
52
|
+
inHand: number[];
|
|
53
|
+
out: number | null;
|
|
54
|
+
} | null;
|
|
55
|
+
ready: boolean[];
|
|
56
|
+
narration: string | null;
|
|
57
|
+
}
|
|
58
|
+
export declare function meldKind(cards: KCard[]): "set" | "run" | null;
|
|
59
|
+
export declare function newRummy500(rules: Rummy500Rules, seats: number, seed: number): Rummy500State;
|
|
60
|
+
/** Where these cards can go: a new meld, or onto a meld on the table (its index). */
|
|
61
|
+
export declare function placement(s: Rummy500State, cards: KCard[]): {
|
|
62
|
+
kind: "set" | "run";
|
|
63
|
+
onto: number;
|
|
64
|
+
} | null;
|
|
65
|
+
type Move = {
|
|
66
|
+
type: "draw";
|
|
67
|
+
} | {
|
|
68
|
+
type: "take";
|
|
69
|
+
card?: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: "meld";
|
|
72
|
+
cards: string[];
|
|
73
|
+
} | {
|
|
74
|
+
type: "discard";
|
|
75
|
+
cards?: string[];
|
|
76
|
+
card?: string;
|
|
77
|
+
} | {
|
|
78
|
+
type: "putback";
|
|
79
|
+
} | {
|
|
80
|
+
type: "next";
|
|
81
|
+
};
|
|
82
|
+
/** A way to use this card now: a new meld with hand cards, or a lay-off. */
|
|
83
|
+
/**
|
|
84
|
+
* A way to meld this card from the hand now, or null if there's none: alone or with others onto a
|
|
85
|
+
* meld on the table, in a set with cards of its rank, or in a run with neighbours of its suit.
|
|
86
|
+
*/
|
|
87
|
+
export declare function homeFor(s: Rummy500State, hand: KCard[], card: KCard): KCard[] | null;
|
|
88
|
+
export declare const rummy500: CardGame<Rummy500Rules, Rummy500State, Move>;
|
|
89
|
+
export {};
|