// Test harness: the thin adapter the course tests call. It translates each // call into engine operations and holds no rules of its own. import { library } from "./content"; import { World, type Zone } from "./engine"; export type { Zone }; export type Id = number; export type Player = 0 | 1; export interface Game { summon(card: string, player?: Player): Id; // to right end of board addToHand(card: string, player?: Player): Id; addToDeck(card: string, player?: Player): Id; play(handId: Id): void; // Expansion Drop zoneOf(id: Id): Zone; board(player: Player): Id[]; // left to right hand(player: Player): Id[]; orderOfPlay(id: Id): number; nameOf(id: Id): string; } export function newGame(opts?: { decks?: [string[], string[]] }): Game { const world = new World(library()); opts?.decks?.forEach((deck, player) => { for (const card of deck) world.create(card, player as Player, "deck"); }); return { summon: (card, player = 0) => world.create(card, player, "board"), addToHand: (card, player = 0) => world.create(card, player, "hand"), addToDeck: (card, player = 0) => world.create(card, player, "deck"), // Module 1 Expansion Drop: see course/01-handles/expansion/README.md. play: () => { throw new Error("not implemented: Module 1 Expansion Drop"); }, zoneOf: (id) => world.zoneOf(id), board: (player) => [...world.zone(player, "board")], hand: (player) => [...world.zone(player, "hand")], orderOfPlay: (id) => { const order = world.orderOfPlay(id); if (order === undefined) throw new Error(`entity ${id} has not entered play`); return order; }, nameOf: (id) => world.cardName(id), }; }