The pack
boardingQueue
function boardingQueue(): Pack<{ boardingQueue: typeof kit; }>
Compose the boarding-queue public rules and generator helpers.
Helpers
createBoardingQueue
const createBoardingQueue = (config: BoardingConfig, solution?: BoardingAction[])=> …
Create a boarding puzzle. Throws on a configuration it refuses (out-of-range sizes, overlapping passengers, seats per colour that do not match passengers) or a solution that does not replay to a win.
generateBoardingQueue
function generateBoardingQueue(options: BoardingGenerateOptions): BoardingLevel
Generate a level whose solution is replayed before it is returned. Throws on out-of-range options, a crowd that does not fit its board (generation: requested groups exceed layout capacity) or a lot the traffic generator cannot build.
Classes
BoardingQueue
class BoardingQueue
A boarding puzzle's rules, with undo, redo and a bounded solver. Get one from createBoardingQueue.
constructor(config: BoardingConfig, solution: BoardingAction[] = [])get config(): BoardingConfig— A copy of the configuration.get state(): BoardingState— A copy of the current state.get solved(): boolean— True when every bus has filled up and left.get lost(): boolean— True when the puzzle is unfinished and no move is legal (seedeadlock()for why). A position can be hopeless before this turns true; onlysolvecan tell.activeVehicle(): BoardingVehicle | null— Passenger mode: the bus now loading (a copy), or null once all have left or in vehicle mode.accessible(): { id: string; path: Cell[]; }[]— Passenger mode: the passengers who can walk out now, each with its path from an entrance to the passenger (empty cells only).dispatchRoutes(id: string): string[]— Vehicle mode: the ids of the routes busidcan drive out by now (whole route clear); empty in passenger mode.preview(a: BoardingAction): ActionResult<BoardingEvent>— Whatapplywould return fora, without playing it.apply(a: BoardingAction): ActionResult<BoardingEvent>— Play a move. Returns{ valid: true, events }, or{ valid: false, reason, events: [] }and changes nothing; reasons includeinaccessible-passenger,waiting-full,bays-full,wrong-mode,unknown-item,already-completeand the traffic pack's route reasons (blocked).legalActions(): BoardingAction[]— Every legal move now, those that serve the wanted colour first.deadlock(): BoardingDeadlock— Why the player is stuck, ordeadlocked: false.solve(maxStates = 20000): SearchResult<BoardingAction>— A winning continuation from here, without changing anything: the rest of the creation certificate when it still applies, otherwise a depth-first search of at mostmaxStatespositions (default 20,000).unsolvableis a proof;budget-exhaustedis not.undo(): boolean— Take back the last move; false when there is none.redo(): boolean— Replay the move last taken back; false when there is none.reset(): void— Return to the start and clear the undo and redo history.
Types
BoardingAction
type BoardingAction = { type: 'passenger'; id: string; } | { type: 'dispatch'; id: string; route: string; }
A move: walk a passenger out (passenger mode), or drive bus id out by its route route (vehicle mode).
BoardingConfig
type BoardingConfig = PassengerBoardingConfig | VehicleBoardingConfig
A boarding puzzle: Bus Jam (mode: 'passengers') or Bus Out (mode: 'vehicles').
BoardingDeadlock
interface BoardingDeadlock
Why the player is stuck, from deadlock().
deadlocked: boolean— True when the puzzle is unfinished and no move is legal.reason: 'none' | 'waiting-full' | 'bays-full' | 'inaccessible-queue' | 'no-matching-vehicle'—waiting-full(every waiting space holds the wrong colour),inaccessible-queue(the needed passengers are walled in),bays-full(every bay holds a bus whose colour is not at the front),no-matching-vehicle(no bus of the front colour can get out), ornone.neededKey: string | null— The colour wanted now: the loading bus's (passenger mode) or the front passenger's (vehicle mode); null when none is.waiting: string[]— Ids of the passengers in the waiting spaces.bays: string[]— Ids of the buses in the loading bays.blocked: string[]— Ids that cannot move now: passengers with no free path to an entrance, or buses with no clear exit route.
BoardingDifficulty
type BoardingDifficulty = 'easy' | 'medium' | 'hard' | 'very-hard'
Generator tier: bigger crowds, more colours, fewer waiting spaces and more interleaving as it rises.
BoardingEvent
type BoardingEvent = { type: 'waiting' | 'boarded'; id: string; vehicle: string; } | { type: 'departed'; id: string; } | { type: 'dispatched'; id: string; route: string; }
What a move did, in order: a passenger took a waiting space (waiting) or a seat (boarded; in vehicle mode its id is line-<index>), a bus was dispatched to a bay (dispatched) or filled up and left (departed).
BoardingGenerateOptions
interface BoardingGenerateOptions
What generateBoardingQueue takes; everything but seed defaults from difficulty.
seed: number— Unsigned 32-bit seed (0 included); the same options give the same level.mode?: 'passengers' | 'vehicles'—'passengers'(Bus Jam, the default) or'vehicles'(Bus Out).difficulty?: BoardingDifficulty— Tier that sets the other defaults; default'medium'.layout?: BoardingLayout— Passenger mode: the floor plan; default'rectangle'. Ignored in vehicle mode.groups?: number— Passenger mode: how many buses, 2 to 32; default 4, 8, 12 or 18 by tier. Vehicle mode takes its fleet fromtraffic.colors?: number— Distinct colours, 2 to 8; default 3, 4, 6 or 8 by tier.seats?: number— Seats on every bus, 2 to 8; default 3.waitingCapacity?: number— Waiting spaces (passenger mode) or loading bays (vehicle mode), 1 to 12; default 7, 5, 3 or 2 by tier.lookahead?: number— How many later buses' passengers are mixed into each bus's turn, 0 to the smaller ofwaitingCapacityandcolors - 1(vehicle mode: belowwaitingCapacity); default 0, 1, 2, 2 (vehicles 0, 1, 2, 1) by tier. Higher means more of the waiting space is needed.traffic?: Omit<TrafficGenerateOptions, 'seed'>— Vehicle mode: options for the bus lot, passed togenerateTrafficRelease; default theparkingpreset at size 4, 6, 8 or 10 by tier and density 0.7. Hazards and mistakes are always off.
BoardingLayout
type BoardingLayout = 'rectangle' | 'aisles' | 'courtyard'
Generated Bus Jam floor plan: a solid rectangle, aisles (a free column every third) or a courtyard (a wall down the middle).
BoardingLevel
interface BoardingLevel
A generated level: its configuration, a winning solution and what was measured.
seed: number— The seed asked for.difficulty: BoardingDifficulty— The tier asked for.parameters: { /** \'passengers'` or `'vehicles'`. / mode: 'passengers' | 'vehicles'; /* The floor plan (passenger mode). / layout: BoardingLayout; /* Buses asked for (passenger mode). / groups: number; /* Distinct colours. / colors: number; /* Seats per bus. / seats: number; /* Waiting spaces or loading bays. / waitingCapacity: number; /* Later buses' passengers mixed into each turn. */ lookahead: number; }` — The settings used, defaults filled in.config: BoardingConfig— The level, ready forcreateBoardingQueue.solution: BoardingAction[]— A replay-checked winning sequence; pass it tocreateBoardingQueuesosolvecan use it.metrics: { /** Moves in the solution. */ items: number; /** Legal moves at the start. */ initialChoices: number; /** Most waiting spaces the solution fills at once. */ certificatePeakWaiting: number; /** Most loading bays the solution fills at once. */ certificatePeakBays: number; /** Buses. */ departures: number; /** Whether the solution really uses the interleaving: fills at least \lookahead` waiting spaces (Bus Out: has a bus waiting in a bay when `lookahead` > 0). Always true on easy. */ difficultyTargetMet: boolean; }` — What the solution needs, not how hard a person finds it; nothing here claims a shortest plan.
BoardingPassenger
interface BoardingPassenger extends Cell
A coloured passenger standing on a walkable cell (x column, y row, whole numbers from 0).
id: string— Unique non-empty id; actions and events name it.key: string— Colour key: the passenger boards only a vehicle with the same key. Non-empty.
BoardingState
interface BoardingState
Where a boarding puzzle stands.
remaining: string[]— Ids still on the board: passengers in the crowd (passenger mode) or buses still parked (vehicle mode).waiting: string[]— Passenger mode: ids of passengers in the waiting spaces, oldest first.bays: { /** The bus id. */ id: string; /** Seats taken so far. */ loaded: number; }[]— Vehicle mode: the buses in the loading bays, oldest first, with the seats taken on each.vehicleIndex: number— Passenger mode: index invehiclesof the bus now loading.loaded: number— Passenger mode: seats taken on the bus now loading.lineIndex: number— Vehicle mode: index inpassengerLineof the passenger at the front of the queue.departed: string[]— Ids of the buses that have filled up and left, in order.moves: number— Moves played.
BoardingVehicle
interface BoardingVehicle
A bus: its colour and how many passengers fill it.
id: string— Unique non-empty id. In vehicle mode it is also the id of its piece in the traffic layout.key: string— Colour key: only passengers with the same key board it. Non-empty.capacity: number— Seats, 1 to 16. The bus departs when every seat is taken.
PassengerBoardingConfig
interface PassengerBoardingConfig
Bus Jam: a crowd on a floor plan, buses arriving in order and a few waiting spaces.
mode: 'passengers'—'passengers': the player taps passengers.width: number— Board width in cells, 1 to 16.height: number— Board height in cells, 1 to 24.walkable: Cell[]— The floor: unique cells inside the board that passengers can stand on and walk through. Any shape.entrances: Cell[]— Walkable cells where walking paths start (the edge nearest the buses); at least one.passengers: BoardingPassenger[]— The crowd, 1 to 384 passengers, each on its own walkable cell.vehicles: BoardingVehicle[]— The buses, 1 to 128, in arrival order. Seats per colour must equal that colour's passengers exactly.waitingCapacity: number— Waiting spaces for passengers whose bus has not come yet, 0 to 12.
VehicleBoardingConfig
interface VehicleBoardingConfig
Bus Out: a packed lot of buses that must drive out, a few loading bays and one passenger queue.
mode: 'vehicles'—'vehicles': the player taps buses.traffic: TrafficConfig— The lot, as atraffic-releaselayout: one piece per bus, with its exit routes. No hazards and no mistake limit.vehicles: BoardingVehicle[]— One bus per traffic piece, matched by id; order does not matter.passengerLine: string[]— The passenger queue, front first, as colour keys. Seats per colour must equal that colour's passengers exactly.bayCapacity: number— Loading bays, 1 to 12: how many dispatched buses can wait for their passengers at once.


