Inspecting kind/hexboard · the kinds · the language · the modules
{name}
- id
- kind/hexboard
- called
- {name}
- kind chain
- kind/hexboard → record
- owner
- the town
- made by
- the town
- version
- 4
- pin
- pirom-vosog
- state
- 8366 bytes
Its spells
To cast them, come in.
Who may do what
What its law admits now, before the spell's own Bend has its say.
| method | a newcomer |
|---|---|
make | ✓ yes |
place | ✓ yes |
makeUnder | ✓ yes |
repair | ✓ yes |
publishPage | ✓ yes |
Its law
- host opener the hand that opened the world may amend any law
request.kind == 2 and request.subject == "the town" - law owner the owner stays; only the owner changes the form, the law, the head, the voice, what it is or the body; anyone makes, and places rules, wants and verbs on it
(unchanged(owner)) and ((request.subject == new.owner) or ((((((((request.kind == 0) or (request.kind == 4)) and (unchanged(form))) and (unchanged(law))) and (unchanged(head))) and (unchanged(voice))) and (unchanged(about))) and (unchanged(body)))) - law kind kinds's law holds
under "kinds"
Its Bend
what it runs: its entry module 18 lines
layer over ./Kind.obend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Form.obend as Form
import ./Rows.obend as Rows
type State = Super.State
form make:
name: text 1..64
size: natural 3..11
def make(state: State, input: MakeInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.cons({head: {name: "size", value: natText(input.size)}, tail: Lists.List.nil()})}), "", context)
form place:
name: text 1..64
size: natural 3..11
id: text 1..64
def place(state: State, input: PlaceInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.cons({head: {name: "size", value: natText(input.size)}, tail: Lists.List.cons({head: {name: "id", value: input.id}, tail: Lists.List.nil()})})}), "", context)
the body this kind lays on what it makes 116 lines
Each thing of this kind runs this layer over what the kind is of.
Amend it in the workshop
Its Bend is checked and amended by the workshop's own spell, with the Bend in its block. To send it, come in; the box is here then.
Its fields
- owner
- the town
- ownerHandle
- the town
- name
- hexboard
- of
- record
- form
name: text 1..64 (36 characters)
name: text 1..64 size: natural 3..11
- law
- empty
- head
- {name}
- voice
- a board of hexes on a table, colours set down one at a time and never lifted
- about
- a board of hexes anyone sets their colour on, one hex a turn, drawn live on its page
- body
layer over ./Record.obend (7982 characters)
layer over ./Record.obend edition ObjectiveBend 1 import ./Abi.obend as Abi import ./List.obend as Lists import ./Document.obend as Document import ./Form.obend as Form import ./Plan.obend as Plans import ./World.obend as World import ./Card.obend as Card import ./Scenes.obend as Scenes import ./Relation.obend as Relations import ./Rows.obend as Rows import ./Text.obend as Text import ./View.obend as View # The hexboard's body, over RECORD (docs/VIEWS.md, the first view that is a board): a board of `size` by `size` hexes # (its kind's form, 3 to 11, 7 when none was given), numbered from 0 along each row, top row first. A hand places its # colour on an empty hex (`place / cell: N`), once a hex: each placing is the record's mark `hex N`, by whoever placed # it, which RECORD's law keeps (a mark is only added). Each hand's colour is the one its first placing came to, in # the order hands came (View.player: red, blue, green, …). Its view is the board as hex tiles, an empty hex a button # that places the reader's colour there; its card the same board in letters. type State = Super.State form place: cell: natural 0..120 form lines: from: natural 1..1000000000 form door: label: text 1..32 to: text 1..128 form undoor: label: text 1..32 def lines(state: State, input: LinesInput, context: Abi.Context) -> Activity<Card.Replied>: Super.lines(state, {from: input.from}, context) def door(state: State, input: DoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.door(state, {label: input.label, to: input.to}, context) def undoor(state: State, input: UndoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.undoor(state, {label: input.label}, context) def actions(state: State, context: Abi.Context) -> Lists.List<String>: if context.principal == state.owner then Text.words("place lines door undoor") else Text.words("place lines") def methods() -> Lists.List<String>: Text.words("~made ~act") def views() -> Lists.List<String>: Text.words("view") def size(state: State) -> Nat: match Text.number(Super.field(state, "size")): case yes(n): if n.value < 3n then 3n else if n.value > 11n then 11n else n.value case no(_): 7n def cellName(n: Nat) -> String: "hex {natText(n)}" def columns() -> String: "ABCDEFGHIJK" # A hex as a person names it: its column's letter and its row from 1 (`D4`), and its number. def where(n: Nat, size: Nat) -> String: "{textTake(textDrop(columns(), n % size), 1n)}{natText(n / size + 1n)}" def placed(state: State, n: Nat) -> Lists.Maybe<Rows.Mark>: Relations.lookup(state.marks, {name: cellName(n)}) def place(state: State, input: PlaceInput, context: Abi.Context) -> Activity<Bool>: let id = Card.called(context, "hexboard") if input.cell >= size(state) * size(state) then Card.refusing(false, {clause: "offBoard", reading: "The board's hexes are 0 to {natText(size(state) * size(state) - 1n)}: delvetalk {id} place / cell: 0"}, context) else placing(state, input.cell, id, context) def placing(state: State, n: Nat, id: String, context: Abi.Context) -> Activity<Bool>: match placed(state, n): case some(m): Card.refusing(false, {clause: "taken", reading: "{where(n, size(state))} is {Card.shown(m.value.who, m.value.handle, context)}'s already; an empty hex is a dot on the card: delvetalk {id} ?"}, context) case none(_): placedNow(state, n, context) def placedNow(state: State, n: Nat, context: Abi.Context) -> Activity<Bool>: let written(_) = write {marks: insert {name: cellName(n), who: context.principal, handle: context.handle, at: context.height}, tended: set context.clock} Card.tell(true, Document.text("{toneOf(players(state), context.principal)} on {where(n, size(state))}.\n")) def isHex(mark: Rows.Mark) -> Bool: Text.starts(mark.name, "hex ") # The hands that have placed, in the order they first did (their colours' order). def players(state: State) -> Lists.List<Rows.Mark>: firsts(Relations.order(state.marks, fn(m: Rows.Mark) -> Nat: m.at), Lists.List.nil()) def firsts(marks: Lists.List<Rows.Mark>, seen: Lists.List<Rows.Mark>) -> Lists.List<Rows.Mark>: match marks: case nil(_): seen case cons(c): firsts(c.tail, if isHex(c.head) == false || Lists.any(seen, fn(p: Rows.Mark) -> Bool: p.who == c.head.who) then seen else Lists.append(seen, c.head)) # A hand's colour: its place among the players, or the next colour for one who has not placed yet. def toneOf(players: Lists.List<Rows.Mark>, who: String) -> String: match Lists.indexWhere(players, fn(p: Rows.Mark) -> Bool: p.who == who): case some(i): View.player(i.value) case none(_): View.player(Lists.length(players)) def name(state: State) -> String: if state.head == "" then "A HEXBOARD" else state.head def count(state: State) -> Nat: Lists.length(Lists.filter(Relations.rows(state.marks), isHex)) def headLine(state: State, context: Abi.Context, id: String) -> Document.Document: let n = size(state) let ps = players(state) Document.Document.sequence({items: Document.Documents.cons({head: Document.text("{name(state)}, {natText(n)} by {natText(n)} hexes: {natText(count(state))} placed by {Text.countWord(Lists.length(ps))} hands. Your colour {yours(ps, context)}. Place it on an empty hex (a dot), numbered from 0 along each row: delvetalk {id} place / cell: <0 to {natText(n * n - 1n)}>\n"), tail: Document.Documents.cons({head: Document.text(board(state, ps, n, 0n)), tail: Document.Documents.cons({head: Document.text(Super.inactiveLine(state, id)), tail: Document.Documents.nil()})})})}) def yours(players: Lists.List<Rows.Mark>, context: Abi.Context) -> String: if Lists.any(players, fn(p: Rows.Mark) -> Bool: p.who == context.principal) then "is {toneOf(players, context.principal)}" else "will be {toneOf(players, context.principal)}" # The board in letters, each placed hex its colour's first letter and an empty one a dot, odd rows set in by one. def board(state: State, players: Lists.List<Rows.Mark>, n: Nat, y: Nat) -> String: if y >= n then "" else "{indent(y)}{rowText(state, players, n, y * n, n)}\n{board(state, players, n, y + 1n)}" def indent(y: Nat) -> String: if y % 2n == 1n then " " else "" def rowText(state: State, players: Lists.List<Rows.Mark>, n: Nat, at: Nat, left: Nat) -> String: if left == 0n then "" else "{glyph(state, players, at)}{gap(left)}{rowText(state, players, n, at + 1n, left - 1n)}" def gap(left: Nat) -> String: if left > 1n then " " else "" def glyph(state: State, players: Lists.List<Rows.Mark>, at: Nat) -> String: match placed(state, at): case some(m): textTake(toneOf(players, m.value.who), 1n) case none(_): "." # What the page draws: the board as hex tiles, an empty one a button placing the reader's colour, and who is which. def view(state: State, context: Abi.Context) -> View.View: let n = size(state) let ps = players(state) View.stack(View.three(View.heading(name(state)), View.hexes(n, View.tiles(0n, n * n, fn(i: Nat) -> View.Tile: tileAt(state, ps, n, i, context))), View.small(legend(state, ps, context)))) def tileAt(state: State, players: Lists.List<Rows.Mark>, n: Nat, i: Nat, context: Abi.Context) -> View.Tile: match placed(state, i): case some(m): View.tile("leaf", toneOf(players, m.value.who), "", "{where(i, n)}: {Card.shown(m.value.who, m.value.handle, context)}{Card.mine(m.value.who, context)}", View.nothing()) case none(_): View.tile("leaf", "", "", "{where(i, n)}: place {toneOf(players, context.principal)} here", View.act("place", View.given("cell", natText(i)))) def legend(state: State, players: Lists.List<Rows.Mark>, context: Abi.Context) -> String: let hands = textJoin(Lists.map(players, fn(p: Rows.Mark) -> String: "{toneOf(players, p.who)}: {Card.shown(p.who, p.handle, context)}{Card.mine(p.who, context)}"), " · ") "Your colour {yours(players, context)}. {natText(count(state))} of {natText(size(state) * size(state))} placed{semi(hands)}{hands}." def semi(hands: String) -> String: if hands == "" then "" else "; "- made
1 rows
- object
- hexboard
- n
- 1
- about
- empty
- count
- 1