BoxedUp
- Description:
BoxedUp.js is a module to model and play "Boxed Up". Boxed Up is a turn-based game for two players (chefs), who take turns packing food-shaped pieces into a shared box. Pieces may be rotated, and may only cover empty cells of the box. Some cells hold garnish from the start; garnish may never be covered. A few cells are special: golden star cells reward whoever covers them, wasabi cells burn points from whoever covers them, and a matcha cell grants the chef who covers it another turn at once. The box is divided into 3×3 compartments; one of them may be the VIP order, which is worth extra when sealed, and the chef who packs the final piece earns a small closing bonus. When a compartment is fully covered it is sealed, and the chef with more food in it earns a bonus. When the chef to move cannot fit any piece anywhere in the box, the box is sealed and the chef with the higher score wins.
- Source:
- Version:
- 2025/26
Members
(static, constant) closing_bonus :number
- Description:
The points the chef who packs the final piece of the box earns for closing the lid.
- Source:
The points the chef who packs the final piece of the box earns for closing the lid.
Type:
- number
(static, constant) compartment_bonus :number
- Description:
The points a chef earns for each sealed compartment they own, on top of one point per covered cell. See
BoxedUp.sealed_compartmentsandBoxedUp.score.
- Source:
The points a chef earns for each sealed compartment they own,
on top of one point per covered cell.
See BoxedUp.sealed_compartments and BoxedUp.score.
Type:
- number
(static, constant) garnish_token :number
- Description:
The cell value marking garnish: decoration already in the box when a game begins. Garnish belongs to neither player, may never be covered, but does count towards sealing a compartment.
- Source:
The cell value marking garnish: decoration already in the box when a game begins. Garnish belongs to neither player, may never be covered, but does count towards sealing a compartment.
Type:
- number
(static) piece_shapes :BoxedUp.Shape
- Description:
The menu of pieces that either chef may pack on their turn. Each piece has a
BoxedUp.Shapegiven in its unrotated orientation.
- Source:
Properties:
| Name | Type | Description |
|---|---|---|
tamago |
BoxedUp.Shape | A 1×2 slice of rolled egg. |
cucumber |
BoxedUp.Shape | A 1×3 stick of cucumber. |
onigiri |
BoxedUp.Shape | A triangular rice ball: an upside-down T of four cells. |
rice |
BoxedUp.Shape | A 2×2 block of steamed rice. |
salmon |
BoxedUp.Shape | A 1×4 fillet of salmon. |
tempura |
BoxedUp.Shape | An L-shaped cluster of tempura (three cells). |
umeboshi |
BoxedUp.Shape | A single pickled plum (one cell). |
The menu of pieces that either chef may pack on their turn.
Each piece has a BoxedUp.Shape given in its unrotated orientation.
Type:
(static, constant) star_bonus :number
- Description:
The points a chef earns for covering a golden star cell. See
BoxedUp.covered_starsandBoxedUp.score.
- Source:
The points a chef earns for covering a golden star cell.
See BoxedUp.covered_stars and BoxedUp.score.
Type:
- number
(static) token_strings :Array.<string>
- Description:
A set of template token strings for
BoxedUp.to_string_with_tokens.
- Source:
Properties:
| Name | Type | Description |
|---|---|---|
default |
Array.<string> | ["0", "1", "2", "3"] Displays cells by their value. |
food |
Array.<string> | ["⬜", "🍣", "🍙", "🍥"] Displays player pieces and garnish as food in the box. |
A set of template token strings for
BoxedUp.to_string_with_tokens.
Type:
- Array.<string>
(static, constant) vip_bonus :number
- Description:
The extra points (on top of
BoxedUp.compartment_bonus) that the owner of the VIP order compartment earns when it is sealed.
- Source:
The extra points (on top of BoxedUp.compartment_bonus) that
the owner of the VIP order compartment earns when it is sealed.
Type:
- number
(static, constant) wasabi_penalty :number
- Description:
The points a chef loses for covering a wasabi cell. Sometimes the burn is worth it to steal a compartment! See
BoxedUp.covered_wasabiandBoxedUp.score.
- Source:
The points a chef loses for covering a wasabi cell.
Sometimes the burn is worth it to steal a compartment!
See BoxedUp.covered_wasabi and BoxedUp.score.
Type:
- number
Methods
(static) available_pieces(game) → {Array.<string>}
- Description:
Returns the names of the menu pieces that can still be packed somewhere in the box, in at least one orientation. This is the menu a chef can actually choose from on their turn: a game has ended (see
BoxedUp.is_ended) exactly when no pieces remain available.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to inspect. |
Returns:
The names of the pieces that still fit,
drawn from the keys of BoxedUp.piece_shapes.
- Type
- Array.<string>
(static) cells_covered(player, game) → {number}
- Description:
Returns the number of cells of the box covered by a player's pieces. Garnish counts to neither player.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
player |
BoxedUp.Player | The player whose cells to count. |
game |
BoxedUp.Game | The game to count cells in. |
Returns:
The number of cells the player has covered.
- Type
- number
(static) compartments(board) → {Array.<BoxedUp.Compartment>}
- Description:
Returns the compartments of a board: its 3×3 sections, aligned to multiples of three from the top-left.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
board |
BoxedUp.Board | The board to divide up. |
Returns:
The board's compartments.
- Type
- Array.<BoxedUp.Compartment>
(static) covered_stars(player, game) → {number}
- Description:
Returns how many golden star cells a player has covered.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
player |
BoxedUp.Player | The player to count stars for. |
game |
BoxedUp.Game | The game to inspect. |
Returns:
The number of stars the player covers.
- Type
- number
(static) covered_wasabi(player, game) → {number}
- Description:
Returns how many wasabi cells a player has covered.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
player |
BoxedUp.Player | The player to count wasabi for. |
game |
BoxedUp.Game | The game to inspect. |
Returns:
The number of wasabi cells the player covers.
- Type
- number
(static) empty_board(widthopt, heightopt) → {BoxedUp.Board}
- Description:
Create a new empty board. Optionally with a specified width and height, otherwise returns a standard 9 wide, 9 high board.
- Source:
Parameters:
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
width |
number |
<optional> |
9
|
The width of the new board. |
height |
number |
<optional> |
9
|
The height of the new board. |
Returns:
An empty board.
- Type
- BoxedUp.Board
(static) empty_cells(game) → {number}
- Description:
Returns how many cells of the box are still empty: cells holding neither a piece nor garnish, and so open to be packed. A measure of how much room is left in the box.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to inspect. |
Returns:
The number of empty cells remaining.
- Type
- number
(static) is_ended(game) → {boolean}
- Description:
Returns whether a game has ended. A game ends when the player to move cannot pack any piece from
BoxedUp.piece_shapes, in any orientation, anywhere in the box. Both players choose from the same menu of pieces, so this depends only on the contents of the box. Since the umeboshi covers a single cell, the game ends exactly when every cell of the box is covered.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to test. |
Returns:
Whether the game has ended.
- Type
- boolean
(static) is_legal_placement(shape, position, board) → {boolean}
- Description:
Returns whether a shape may be packed at a position on a board. A placement is legal if every cell the shape would cover lies inside the board and is currently empty. Cells holding pieces or garnish may not be covered.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape being placed. |
position |
BoxedUp.Position | The position of the shape's anchor. |
board |
BoxedUp.Board | The board to place the shape on. |
Returns:
Whether the placement is legal.
- Type
- boolean
(static) leader(game) → {BoxedUp.Player|0}
- Description:
Returns which player is currently ahead on
BoxedUp.score, whether or not the game has ended: the player with the higher score, or0if the scores are level. UnlikeBoxedUp.winner, this reports the standing of a game still in progress — useful, for example, to decide the result of a box whose play was cut short.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to check. |
Returns:
The player ahead, or 0 for a tie.
- Type
- BoxedUp.Player | 0
(static) legal_placements(shape, board) → {Array.<BoxedUp.Position>}
- Description:
Returns all the positions at which a shape may legally be packed.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape being placed. |
board |
BoxedUp.Board | The board to place the shape on. |
Returns:
The legal anchor positions for the shape.
- Type
- Array.<BoxedUp.Position>
(static) new_game(widthopt, heightopt, garnish_cellsopt, star_cellsopt, wasabi_cellsopt, matcha_cellsopt, vip_compartmentopt, starting_playeropt) → {BoxedUp.Game}
- Description:
Create a new game, ready for the first ply. The box starts empty, except for any garnish, and player 1 packs first. Optionally provide a width and height for the box, otherwise a standard 9×9 box is used.
- Source:
Parameters:
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
width |
number |
<optional> |
9
|
The width of the box. |
height |
number |
<optional> |
9
|
The height of the box. |
garnish_cells |
Array.<BoxedUp.Position> |
<optional> |
[]
|
Cells that start the game holding garnish, which may never be covered. |
star_cells |
Array.<BoxedUp.Position> |
<optional> |
[]
|
Empty cells holding a golden star. Garnish, star, and wasabi cells must not overlap. |
wasabi_cells |
Array.<BoxedUp.Position> |
<optional> |
[]
|
Empty cells holding a dab of wasabi. |
matcha_cells |
Array.<BoxedUp.Position> |
<optional> |
[]
|
Empty cells holding a bowl of matcha. Special cells must not overlap. |
vip_compartment |
BoxedUp.Position |
<optional> |
The origin of the compartment serving as this box's VIP order, if any. |
|
starting_player |
BoxedUp.Player |
<optional> |
1
|
The chef who packs the first piece of this box — alternate it between games for fairness, since packing first means first pick of the specials. |
Returns:
A new game.
- Type
- BoxedUp.Game
(static) orientations(shape) → {Array.<BoxedUp.Shape>}
- Description:
Returns all distinct orientations of a shape, i.e. its unique quarter-turn rotations. Symmetric shapes have fewer than four distinct orientations.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape to rotate. |
Returns:
An array of distinct orientations of the shape.
- Type
- Array.<BoxedUp.Shape>
(static) place(shape, position, game) → {BoxedUp.Game|undefined}
- Description:
A ply is one turn taken by one of the players: the current player packs one piece, in a chosen orientation, into the box at a chosen position. Returns a new game with the piece packed and the other player to play — unless the piece covered a matcha cell, in which case the energised chef immediately takes another turn.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape of the piece being packed,
one of |
position |
BoxedUp.Position | The position of the shape's anchor. |
game |
BoxedUp.Game | The game state that the ply is made on. |
Returns:
If the ply was legal,
return the new game state, otherwise return undefined.
- Type
- BoxedUp.Game | undefined
(static) placement_cells(shape, position) → {Array.<BoxedUp.Position>}
- Description:
Returns the coordinates of the cells a shape would cover when placed with its anchor at a given position.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape being placed. |
position |
BoxedUp.Position | The position of the shape's anchor. |
Returns:
The cells the placed shape would cover.
- Type
- Array.<BoxedUp.Position>
(static) player_to_ply(game) → {BoxedUp.Player}
- Description:
Returns which player is next to pack a piece into the box.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to check. |
Returns:
The player next to play.
- Type
- BoxedUp.Player
(static) rotated_shape(shape) → {BoxedUp.Shape}
- Description:
Returns a shape rotated a quarter turn clockwise. The returned shape is normalised, i.e. its offsets are relative to its own top-left corner.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape to rotate. |
Returns:
The rotated shape.
- Type
- BoxedUp.Shape
(static) score(player, game) → {number}
- Description:
Returns a player's score: one point per covered cell, plus
BoxedUp.compartment_bonusper sealed compartment owned (plusBoxedUp.vip_bonusmore if it is the VIP order), plusBoxedUp.star_bonusper covered golden star, minusBoxedUp.wasabi_penaltyper covered wasabi cell, plusBoxedUp.closing_bonusif the game has ended and this player packed the final piece.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
player |
BoxedUp.Player | The player whose score to compute. |
game |
BoxedUp.Game | The game to score. |
Returns:
The player's score.
- Type
- number
(static) score_gain(shape, position, game) → {number}
- Description:
Returns how many points the player to move would gain by packing a shape at a position: the change in their
BoxedUp.scoreonce the ply is made. A ply that is not legal gains nothing, so this returns0for it. Lets a chef weigh a move before committing.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
shape |
BoxedUp.Shape | The shape being placed. |
position |
BoxedUp.Position | The position of the shape's anchor. |
game |
BoxedUp.Game | The game the ply would be made on. |
Returns:
The points the player to move would gain.
- Type
- number
(static) sealed_compartments(game) → {Array.<Object>}
- Description:
Returns the sealed compartments of a game, with their owners. A compartment is sealed when none of its cells remain empty. Its owner is the player whose pieces cover more of its cells (garnish counts to neither player); if they cover it equally, the owner is
0and nobody earns its bonus.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to check. |
Returns:
An array of {origin, owner} records, one per sealed compartment.
- Type
- Array.<Object>
(static) size(board) → {Array.<number>}
- Description:
Returns the size of a board as an array of [width, height].
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
board |
BoxedUp.Board | The board to check the size of. |
Returns:
The width and height of the board, [width, height].
- Type
- Array.<number>
(static) to_string(board) → {string}
- Description:
Returns a string representation of a board. I.e. for printing to the console rather than serialisation.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
board |
BoxedUp.Board | The board to represent. |
Returns:
The string representation.
- Type
- string
(static) to_string_with_tokens(token_strings) → {function}
- Description:
Returns a
BoxedUp.to_stringlike function, mapping tokens to provided string representations.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
token_strings |
Array.<string> | Strings to represent tokens as. Examples are given in
|
Returns:
The string representation.
- Type
- function
(static) winner(game) → {BoxedUp.Player|0|undefined}
- Description:
Returns the winner of an ended game. The winner is the player with the higher
BoxedUp.score(i.e. theBoxedUp.leader). If both players have the same score, the game is a draw, signified by0.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
game |
BoxedUp.Game | The game to check for a winner. |
Returns:
The winning player,
0 for a draw, or undefined if the game has not ended.
- Type
- BoxedUp.Player | 0 | undefined
Type Definitions
Board
- Description:
A Board is the rectangular grid of cells that pieces are packed into. It is implemented as an array of rows of cells.
- Source:
A Board is the rectangular grid of cells that pieces are packed into. It is implemented as an array of rows of cells.
Type:
- Array.<Array.<BoxedUp.Cell>>
Cell
- Description:
A Cell of the board is either empty (
0), covered by a player's piece (1or2), or holds garnish (3, seeBoxedUp.garnish_token), which belongs to neither player and may never be covered.
- Source:
A Cell of the board is either empty (0),
covered by a player's piece (1 or 2),
or holds garnish (3, see BoxedUp.garnish_token),
which belongs to neither player and may never be covered.
Type:
- 0 | BoxedUp.Player | 3
Compartment
- Description:
A Compartment is one 3×3 section of the box, aligned to multiples of three from the top-left corner. Boards whose width or height is not a multiple of three have margin cells that belong to no compartment.
- Source:
Properties:
| Name | Type | Description |
|---|---|---|
origin |
BoxedUp.Position | The compartment's top-left cell. |
cells |
Array.<BoxedUp.Position> | The nine cells of the compartment. |
A Compartment is one 3×3 section of the box, aligned to multiples of three from the top-left corner. Boards whose width or height is not a multiple of three have margin cells that belong to no compartment.
Type:
- Object
Game
- Description:
A Game records everything needed to continue a game of Boxed Up: the contents of the box, and which player packs next. Game objects are never mutated;
BoxedUp.placereturns a new game object.
- Source:
Properties:
| Name | Type | Attributes | Description |
|---|---|---|---|
board |
BoxedUp.Board | The current contents of the box. |
|
player |
BoxedUp.Player | The player whose turn it is. |
|
star_cells |
Array.<BoxedUp.Position> |
<optional> |
Golden cells that award
|
wasabi_cells |
Array.<BoxedUp.Position> |
<optional> |
Fiery cells that cost
|
matcha_cells |
Array.<BoxedUp.Position> |
<optional> |
Energising cells that grant whoever covers them an immediate extra turn. |
vip_compartment |
BoxedUp.Position |
<optional> |
The origin of the
compartment that is this box's VIP order, worth
|
last_player |
BoxedUp.Player |
<optional> |
The chef who made the most
recent ply, who earns |
A Game records everything needed to continue a game of Boxed Up:
the contents of the box, and which player packs next.
Game objects are never mutated;
BoxedUp.place returns a new game object.
Type:
- Object
Player
- Description:
A Player token marks a cell covered by one of that player's pieces. Player 1 packs first unless
BoxedUp.new_gameis given a different starting player.
- Source:
A Player token marks a cell covered by one of that player's pieces.
Player 1 packs first unless BoxedUp.new_game is given a
different starting player.
Type:
- 1 | 2
Position
- Description:
A Position picks out a single cell of the board. It is a [row, column] pair of zero-based indices. Row 0 is the top of the board; column 0 is its left edge.
- Source:
A Position picks out a single cell of the board. It is a [row, column] pair of zero-based indices. Row 0 is the top of the board; column 0 is its left edge.
Type:
- Array.<number>
Shape
- Description:
A Shape is the footprint of a piece: an array of [row, column] offsets from the piece's anchor cell, which is the position the piece is placed at. The shapes of the standard pieces are listed in
BoxedUp.piece_shapes, and may be rotated withBoxedUp.rotated_shape.
- Source:
A Shape is the footprint of a piece:
an array of [row, column] offsets from the piece's anchor cell,
which is the position the piece is placed at.
The shapes of the standard pieces are listed in
BoxedUp.piece_shapes, and may be rotated with
BoxedUp.rotated_shape.
Type:
- Array.<Array.<number>>