Reference
Rules, maps and records
import { … } from "@johnmorrisdotca/tenka";
14.9 kB minified and gzipped, with everything it imports (measured with esbuild)
Tenka 天下: the classic world-conquest game on a map of the modern world, for two to six players, as plain functions over plain data.
A game is a value. startTenka deals one from a seed, playTenka makes a
move and returns the next game (or null for a move the rules refuse), and
every shuffle, deal and die is drawn from the game's own seeded random, so
a game replays exactly from its seed and its moves (encodeTenka,
decodeTenka). Nothing here touches the DOM, a clock or Math.random.
The map's outlines, which only a board drawing the world needs, are their
own entry, @johnmorrisdotca/tenka/shapes, and so is the table that
draws and plays a game in plain DOM, @johnmorrisdotca/tenka/ui.
Exports
| Name | Kind | What it is |
|---|---|---|
areNeighbours | function | Whether two territories are neighbours, by land or by sea. |
armiesHeld | function | How many armies an owner has on the map. |
attacksOpen | function | Every attack open now: from each territory of theirs with armies to spare, on each neighbour somebody else holds, with each number of dice — and the same attack again and again until it is decided. |
battleLosses | function | WHO LOSES WHAT: the highest die of each side compared, then the next highest, as many pairs as the side with fewer dice threw. |
beginTurn | function | A turn starting for seat: its armies worked out, nothing yet taken, nothing rolled. |
boardOf | function | The map an argument names, and the world for anything that is not one: these functions are handed to an array's map and filter (deck.map(cardKind)), which pass an index where the map would go. |
cardKind | function | What a card shows: land, sea or air for a territory's card, in turn round the map; wild for a wild card. |
cardTerritory | function | The territory a card shows, or null for a wild card. |
choiceNow | function | A choice made on an earlier map, read against this one: only what still stands, and a number of armies the move can take. |
cleanTenkaName | function | A name as the table typed it, tidied: spaces run together, trimmed, cut to TENKA_NAME_MOST. |
connectedOwn | function | Every territory of the same owner reachable from this one through that owner's own territories, in order; never the territory itself. |
continentNameIn | function | A continent's name in a table of strings, by its key ("northAmerica", "asia"…). |
continentsHeld | function | The continents a seat holds every territory of. |
counted | function | THE COUNT, when the last round is over: whoever holds the most territories wins; level on territories, whoever has more armies on the map; level on both, they share the win. |
decodeTenka | function | A kept game read back, or null for nothing kept, or for text that is not a game these rules can play out again: a browser's storage is somebody's to edit, and a half-understood game is worse than none. |
defendDice | function | The dice a defender holding armies throws: as many as allowed, since more never hurts the defence. |
encodeTenka | function | A game as text to keep: its table and its moves. |
endOfTurn | function | THE END OF A TURN: a card for a player who took a territory in it, then the next player still in. |
finished | function | The game ended, with these seats winning. |
isSet | function | Whether three cards make a set: three of one kind, one of each kind, or any two with a wild card (a wild card stands for whatever the set needs). |
isTenkaSeed | function | Whether a number is a seed a game can be dealt from: a whole number from 0 to TENKA_SEED_MOST. |
isTenkaTable | function | Whether a game this long for this many players is one Tenka is offered for. |
isTerritory | function | Whether a number is a territory of the map. |
isWild | function | Whether a card is one of the two wild cards. |
marksFor | function | What the map lights up for a choice. |
mostAttackDice | function | The most dice an attacker may throw from a territory holding armies: one army always stays behind. |
mustTrade | function | Whether the player to move must trade cards before anything else: five or more in hand while reinforcing. |
nextRandom | function | The next number from the random at state, in [0, 1), and the state after it. |
nextSeatIn | function | The next player still in after seat, round the table; the neutral army never takes a turn. |
NO_CHOICE | constant | Nothing chosen: where a turn, and a table, start. |
playTenka | function | The game after the player to move makes move, or null when they may not: a move for another phase, a territory not theirs, a neighbour that is not one, dice they have not the armies for, a set that is not a set. |
randomBelow | function | A whole number from 0 to below - 1, and the state after it. |
readTenkaMove | function | A kept move read back, or null for anything that is not one. |
reinforcementFor | function | THE ARMIES A TURN BRINGS: one for every three territories held, never fewer than three, and each continent held whole adds its bonus. |
replayTenka | function | A game made again from its table and its moves, or null if any move could not have been made when it was. |
sensibleTenkaMove | function | The computer player's move: one the rules accept, chosen as a person might. |
setsIn | function | Every set a hand holds, each as its three cards smallest first, in order. |
shuffled | function | A list in a random order (Fisher and Yates), and the state after it; the list given is left alone. |
startTenka | function | A NEW GAME, all of it drawn from seed: who goes first; the territories shuffled and dealt round the table one at a time from that player, each with one army on it (at a table of two, dealt three ways, the neutral army taking every third); the cards shuffled; and each player's starting armies (TENKA_STARTING_ARMIES) less the ones already on their territories — scattered at random when placing is auto, or left to be placed by hand, one at a time round the table. |
tapTerritory | function | What tapping territory does now: a new choice, and the move to make at once, if the tap is one. |
TENKA_ATTACK_DICE | constant | The most dice an attacker throws. |
TENKA_CARD_KINDS | constant | The three kinds a territory's card shows, in turn round the map, and the wild card that is any of them. |
TENKA_CONTINENTS | constant | The world's six continents, each with the territories in it. |
TENKA_CSV_COLUMNS | constant | The columns of the CSV export, in order. |
TENKA_DECK | constant | Every card in the game: the territories' cards, then the wild cards. |
TENKA_DEFEND_DICE | constant | The most dice a defender throws. |
TENKA_EXPORT_FORMAT | constant | The shape of the JSON this package writes. |
TENKA_FEWEST_PLAYERS | constant | The fewest at a table: two, joined by the neutral army. |
TENKA_LEAST_REINFORCEMENT | constant | The fewest armies a turn brings, however little is held. |
TENKA_LENGTHS | constant | The lengths of game startTenka takes, in rounds: 10, 20 and 60. |
TENKA_MAP_LIST | constant | The maps in the order a set-up offers them: the world first, the usual one. |
TENKA_MAPS | constant | Every map a game may be played on, by key. |
TENKA_MEDIUM_ROUNDS | constant | The medium game: twenty rounds, then the count. |
TENKA_MOST_PLAYERS | constant | The most at a table: six. |
TENKA_MOVES | constant | The kinds of move, by name: what goes in a move's kind. |
TENKA_MUST_TRADE_AT | constant | With this many cards in hand a player must trade before placing; after knocking somebody out, down to fewer than this. |
TENKA_NAME_MOST | constant | The longest name a seat keeps. |
TENKA_NEUTRAL | constant | The owner of the territories nobody at a table of two holds: the neutral army, which never takes a turn. |
TENKA_PHASES | constant | The phases of a turn, by name: compare game.phase with these rather than with text typed out. |
TENKA_PLACING | constant | How the starting armies are placed: scattered at random (auto), or by the players in turn (hand). |
TENKA_SEED_MOST | constant | The largest seed a game keeps: the random's state is one 32-bit number. |
TENKA_SHORT_ROUNDS | constant | The short game: ten rounds, then the count. |
TENKA_STARTING_ARMIES | constant | THE ARMIES EACH PLAYER STARTS WITH, by how many are playing: the standard table. |
TENKA_STRINGS | constant | The package's words in each language it speaks: TENKA_STRINGS.en, TENKA_STRINGS.ja. |
TENKA_TERRITORIES | constant | The world's territories: the map a game is played on unless it says otherwise. |
TENKA_TERRITORIES_PER_ARMY | constant | How many territories held bring one army each turn: three. |
TENKA_TERRITORY_CARD_BONUS | constant | The armies placed straight onto a territory the trader holds, when a card of the set shows it. |
TENKA_TERRITORY_COUNT | constant | How many territories the world has: forty-two. |
TENKA_TRADE_STEP | constant | How much more each set is worth than the last, once TENKA_TRADE_VALUES runs out: 20, 25, 30… |
TENKA_TRADE_VALUES | constant | WHAT A SET OF CARDS IS WORTH, by how many sets anybody has traded in before it: 4, 6, 8, 10, 12, 15, and five more for every set after that — the escalating standard schedule. |
TENKA_VERSION | constant | The version of this package, as package.json has it. |
TENKA_WILD | constant | The kind of a wild card, which stands for whatever a set needs. |
TENKA_WILD_CARDS | constant | How many wild cards are in the deck. |
TENKA_WORLD_ROUNDS | constant | The whole world: played to the last player standing, and counted after sixty rounds if nobody is. |
tenkaAgain | function | The same table again, from nothing, with a new seed: a new deal, a new first player, new dice. |
TenkaCard | type | A territory's card (0–41) or a wild card (42, 43). |
TenkaCardKind | type | What a card shows: one of three kinds, or a wild card that stands for any of them. |
TenkaChoice | type | A choice made on the map and not yet a move: where from, where to, and how many armies (tapTerritory). |
tenkaContinent | function | A continent of a map by its key. |
TenkaContinent | type | A continent: its name, the armies holding all of it is worth each turn, and its territories. |
TenkaContinentKey | type | A continent of any map, by key: the world's continents and Europe's regions. |
tenkaDailySeed | function | Today's seed, the date as a number: 2026-10-01 is 20261001. |
tenkaDay | function | The day a moment falls on, in UTC, written YYYY-MM-DD. |
tenkaDeckFor | function | Every card of a game on this map: a card for each territory, numbered as the territories are, then the wild cards. |
TenkaEuropeRegionKey | type | Europe's eleven regions, by key: the continents of the Europe map. |
tenkaExported | function | A game as the JSON export's object: its table, its moves, and where it stands. |
TenkaExported | type | A whole JSON export of one game: what tenkaToJSON writes and tenkaFromJSON reads. |
tenkaFromJSON | function | A game from JSON that tenkaToJSON wrote, or text that encodeTenka did. |
TenkaGame | type | A game, as its moves make it. |
TenkaLocale | type | The languages the package speaks: English and Japanese. |
TenkaMap | type | A map as the rules read it: its territories, its continents and each territory's neighbours by land and by sea. |
TenkaMapKey | type | The maps a game may be played on. |
TenkaMapMarks | type | What the map lights up for a choice (marksFor): the territory chosen, what it can reach, and the target. |
tenkaMapOf | function | The map a game is played on: the one it was started on, and the world for a game saved before there was a choice. |
TenkaMove | type | A move, as playTenka takes it. |
TenkaMoveKind | type | The kinds of move, by name. |
tenkaMoves | function | Every move the player to move may make now, each one playTenka accepts. |
tenkaNeighbours | function | A territory's neighbours, by land and by sea. |
tenkaOver | function | Whether the game is over. |
TenkaOwner | type | Who holds a territory: a seat, or TENKA_NEUTRAL. |
TenkaPhase | type | Where a turn is. |
TenkaPlacing | type | Starting armies placed at random, or by hand in turn. |
tenkaPlayerName | function | A seat's name as the table reads it: the one given, or "Player 3". |
tenkaRecord | function | THE RECORD OF A GAME, move by move, with the dice and everything else each move brought: made by playing the game again from its seed. |
TenkaRecordEntry | type | One move of a game's record, with what came of it: what the text and the CSV are written from. |
TenkaRoll | type | One roll of the dice — or the last of a run of them (blitz) — what each side threw, highest first, and what each lost in all. |
tenkaSay | function | A line from a table of strings with its braces filled in: tenkaSay(strings.moveIn, { n: 3 }) is "Move 3 in". |
TenkaSeat | type | A player's place round the table: 0 for the first name given, up to 5. |
TenkaShapes | type | How the world is drawn, in map units (tenkaShapes.data.ts, written by scripts/map.mjs). |
tenkaStrings | function | The table of strings for a locale with a page's own words laid over it. |
TenkaStrings | type | Every table word, including local embed error feedback. |
TenkaTerritoryData | type | One territory as the map script writes it: neighbours by land and by sea are indices into the same list. |
tenkaToCSV | function | A game as CSV, a row to a move, for a spreadsheet: TENKA_CSV_COLUMNS. |
tenkaToJSON | function | A game as JSON, two spaces deep, with the format's number first. |
tenkaToText | function | A game as plain text, a line to a move, for a chat or a log: who placed what where, every throw of the dice, every territory taken, and how it ended. |
TenkaTrade | type | The last set of cards traded in, for the table to see: by whom, for how many, and the territory that got two more. |
TenkaWorldContinentKey | type | The world's six continents, by key. |
territoriesHeld | function | How many territories an owner holds. |
territoryNameIn | function | A territory's name in a table of strings, by its key (TENKA_TERRITORIES[n].key, such as "alaska"); "" for a key that is no territory's. |
throwDice | function | count dice, highest first, and the state after them. |
tradeValue | function | What the next set traded in is worth, when trades sets have been traded before it: 4, 6, 8, 10, 12, 15, 20, 25… |
writeTenkaMove | function | A move as the short list it is kept as — and sent as, to the other devices at a table played on several. |