code wiki / (root) / nx_folkgame_lib.nx

nx_folkgame_lib.nx

buildroot/runtime/nx_folkgame_lib.nx

47516 B1133 linesdepth 3pulls 3 transitivereach 7 importersview sourcekind librarytopic folkgame
docsdependenciesstructsconstsfunctions

about

nx_folkgame_lib.nx -- THE LUDEME SUBSTRATE: one shared board-game core that reads a game as DATA and plays it, so a new folk game is a SPEC and never a new organ. Named for the ludeme -- Browne's unit of game rule -- because the deliverable is the VOCABULARY, not the game list: the 117 rows of knowledge/compare/folkgames.registry exist to prove the vocabulary spans real human game design well enough that novel games can later be SEARCHED out of it (the Ludi/Yavalath result). A game that needs a new organ is a hole in the vocabulary and must be reported as one. NO CAPS, BY CONSTRUCTION. Every array here is sized from the spec itself in a MEASURE pass and filled in a SECOND pass, so there is no FG_MAX_CELLS to guess and none to raise later. This is the estate law that a ceiling which has to be guessed is a defect generator in both directions: too small truncates in silence, too large wastes memory, and raising it only moves the guess. THE SPEC (rows, pipe-delimited, '#' comments). Every key is OPTIONAL except cells and linelen; an unknown key is REFUSED BY NAME rather than ignored, because a silently-dropped rule is a game that plays wrongly while looking parsed. name|<slug>|<Title> family|align cells|<n> board size. REQUIRED. linelen|<n> how many in a row makes a line. REQUIRED. hand|<n> pieces each side places before movement. ABSENT = place until full. win|line forming a line wins outright (Tic-Tac-Toe, Gomoku) win|reduce|<n> reducing the opponent below <n> pieces wins (the Morris family) capture|onmill completing a line removes one enemy piece move|adj after hands are empty, step to an ADJACENT empty cell fly|<n> at or below <n> pieces a side may move to ANY empty cell lines|grid|<w>|<h>|<len> GENERATE every line on a w x h grid -- the generator, not 572 rows line|a,b,c[,...] one explicit line (the Morris boards, which are not grids) adj|grid|<w>|<h>|<mode> GENERATE grid adjacency. mode 0 orthogonal, 1 diagonal, 2 both adj|<cell>|<n1,n2,...> one explicit adjacency row xy|<cell>|<x>|<y> explicit draw position for a non-grid board license_tier: ORIGINAL No hw writes (Rule 26). Sovereign syscalls only, integer only, no float.

dependencies 2 imports · 5 importers

nx_syscalls.nx nx_estate_path.nx nx_folkgame_lib.nx nx_folkgame_ai_lib.nx nx_folkgame_align_gate.nx nx_folkgame_play.nx nx_folkgame_race_lib.nx nx_folkgame_sow_lib.nx

imports: nx_syscalls.nxnx_estate_path.nx

imported by: nx_folkgame_ai_lib.nxnx_folkgame_align_gate.nxnx_folkgame_play.nxnx_folkgame_race_lib.nxnx_folkgame_sow_lib.nx

structs

none

consts

43const FG_PATHCAP: i64 = 1024
47const FG_HASH: i64 = 35
48const FG_NL: i64 = 10
49const FG_CR: i64 = 13
50const FG_PIPE: i64 = 124
51const FG_COMMA: i64 = 44
52const FG_MINUS: i64 = 45
53const FG_ZERO: i64 = 48
54const FG_NINE: i64 = 57
55const FG_DECIMAL: i64 = 10
56const FG_WORD: i64 = 8
59const FG_NUMSCRATCH: i64 = 28
60const FG_MISS: i64 = 0 - 999999
63const FG_H_CELLS: i64 = 0
64const FG_H_HAND: i64 = 1
65const FG_H_LINELEN: i64 = 2
66const FG_H_WINMODE: i64 = 3
67const FG_H_REDUCE: i64 = 4
68const FG_H_CAPTURE: i64 = 5
69const FG_H_MOVEADJ: i64 = 6
70const FG_H_FLYAT: i64 = 7
71const FG_H_NLINES: i64 = 8
72const FG_H_LINEW: i64 = 9
73const FG_H_ADJW: i64 = 10
74const FG_H_OFF_LINES: i64 = 11
75const FG_H_OFF_ADJ: i64 = 12
76const FG_H_OFF_ADJN: i64 = 13
77const FG_H_OFF_XY: i64 = 14
78const FG_H_OFF_STATE: i64 = 15
79const FG_H_OFF_SCAL: i64 = 16
80const FG_H_BYTES: i64 = 17
83const FG_H_GRIDW: i64 = 18
84const FG_H_GRIDH: i64 = 19
93const FG_H_FAMILY: i64 = 20
94const FG_H_PERSIDE: i64 = 21
95const FG_H_SEEDS: i64 = 22
96const FG_H_STORE: i64 = 23
97const FG_H_LAP: i64 = 24
98const FG_H_CAPMODE: i64 = 25
99const FG_H_CAPA: i64 = 26
100const FG_H_CAPB: i64 = 27
112const FG_H_TRACK: i64 = 28
113const FG_H_PIECES: i64 = 29
114const FG_H_DICEN: i64 = 30
115const FG_H_DICESIDES: i64 = 31
116const FG_H_ENTRY: i64 = 32
117const FG_H_BEAROFF: i64 = 33
118const FG_H_HIT: i64 = 34
119const FG_H_BLOCK: i64 = 35
124const FG_H_OFF_START: i64 = 36
125const FG_H_N: i64 = 40
127const FG_FAM_RACE: i64 = 2
129const FG_FAM_ALIGN: i64 = 0
130const FG_FAM_SOW: i64 = 1
133const FG_CAP_NONE: i64 = 0
134const FG_CAP_COUNT: i64 = 1
135const FG_CAP_EMPTY: i64 = 2
138const FG_S_SIDE: i64 = 0
139const FG_S_HAND1: i64 = 1
140const FG_S_HAND2: i64 = 2
141const FG_S_ON1: i64 = 3
142const FG_S_ON2: i64 = 4
143const FG_S_PHASE: i64 = 5
144const FG_S_WINNER: i64 = 6
145const FG_S_PLIES: i64 = 7
152const FG_S_N: i64 = 16
154const FG_PH_PLACE: i64 = 0
155const FG_PH_MOVE: i64 = 1
156const FG_PH_CAPTURE: i64 = 2
158const FG_WIN_LINE: i64 = 0
159const FG_WIN_REDUCE: i64 = 1
161const FG_MK_PLACE: i64 = 0
162const FG_MK_MOVE: i64 = 1
163const FG_MK_REMOVE: i64 = 2
164const FG_MV_KIND_SH: i64 = 32
165const FG_MV_FROM_SH: i64 = 16
166const FG_MV_MASK: i64 = 65535
169const FG_T_ONGOING: i64 = 0
170const FG_T_P1: i64 = 1
171const FG_T_P2: i64 = 2
172const FG_T_DRAW: i64 = 3
174const FG_ADJ_ORTH: i64 = 0
175const FG_ADJ_DIAG: i64 = 1
176const FG_ADJ_BOTH: i64 = 2
181const FG_LINE_ORTH: i64 = 0
182const FG_LINE_ALL: i64 = 1
183const FG_DEG_ORTH: i64 = 4
184const FG_DEG_BOTH: i64 = 8

functions

186func fg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 }
189func fg_num2(v: i64) -> i64
206func fg_lineend(buf: *u8, n: i64, i: i64) -> i64
214func fg_keyis(buf: *u8, ls: i64, le: i64, key: *u8) -> i64
225func fg_fieldoff(buf: *u8, ls: i64, le: i64, k: i64) -> i64
238func fg_wordis(buf: *u8, o: i64, le: i64, w: *u8) -> i64
248func fg_int_at(buf: *u8, o: i64, le: i64) -> i64
267func fg_field_int(buf: *u8, ls: i64, le: i64, k: i64) -> i64
called by 1: fg_parse_arena calls 2: fg_int_atfg_fieldoff
271func fg_listn(buf: *u8, o: i64, le: i64) -> i64
called by 1: fg_parse_arena
282func fg_listat(buf: *u8, o: i64, le: i64, k: i64) -> i64
called by 1: fg_parse_arena calls 1: fg_int_at
295func fg_gridlines_n(w: i64, h: i64, l: i64, mode: i64) -> i64
called by 2: mainfg_parse_arena
305func fg_hdr(base: i64) -> *i64 { return base as *i64 }
306func fg_cells(base: i64) -> i64 { let hd: *i64 = fg_hdr(base); return hd[FG_H_CELLS] }
307func fg_linelen(base: i64) -> i64 { let hd: *i64 = fg_hdr(base); return hd[FG_H_LINELEN] }
calls 1: fg_hdr
308func fg_nlines(base: i64) -> i64 { let hd: *i64 = fg_hdr(base); return hd[FG_H_NLINES] }
called by 1: main calls 1: fg_hdr
309func fg_bytes(base: i64) -> i64 { let hd: *i64 = fg_hdr(base); return hd[FG_H_BYTES] }
calls 1: fg_hdr
310func fg_state(base: i64) -> *i64 { let hd: *i64 = fg_hdr(base); return (base + hd[FG_H_OFF_STATE]) as *i64 }
311func fg_scal(base: i64) -> *i64 { let hd: *i64 = fg_hdr(base); return (base + hd[FG_H_OFF_SCAL]) as *i64 }
312func fg_at(base: i64, c: i64) -> i64 { let s: *i64 = fg_state(base); return s[c] }
313func fg_side(base: i64) -> i64 { let s: *i64 = fg_scal(base); return s[FG_S_SIDE] }
314func fg_phase(base: i64) -> i64 { let s: *i64 = fg_scal(base); return s[FG_S_PHASE] }
called by 2: mainmain calls 1: fg_scal
315func fg_line_cell(base: i64, li: i64, k: i64) -> i64
called by 1: fg_forms_line calls 1: fg_hdr
320func fg_adj_n(base: i64, c: i64) -> i64
called by 1: fg_moves calls 1: fg_hdr
325func fg_adj_at(base: i64, c: i64, k: i64) -> i64
called by 1: fg_moves calls 1: fg_hdr
330func fg_xy_x(base: i64, c: i64) -> i64
called by 1: fgp_render calls 1: fg_hdr
335func fg_xy_y(base: i64, c: i64) -> i64
called by 2: fgp_renderfgp_render_ids calls 1: fg_hdr
343func fg_setphase(base: i64) -> i64
called by 2: fg_resetfg_apply calls 2: fg_hdrfg_scal
357func fg_reset(base: i64) -> i64
374func fg_count(base: i64, side: i64) -> i64
389func fg_forms_line(base: i64, cell: i64, side: i64) -> i64
411func fg_maxmoves(base: i64) -> i64
416func fg_moves(base: i64, out: *i64) -> i64
489func fg_mv_kind(mv: i64) -> i64 { return mv >> FG_MV_KIND_SH }
called by 2: fg_applymain
490func fg_mv_to(mv: i64) -> i64 { return mv & FG_MV_MASK }
called by 2: fg_applymain
491func fg_mv_from(mv: i64) -> i64 { return (mv >> FG_MV_FROM_SH) & FG_MV_MASK }
called by 2: fg_applymain
493func fg_apply(base: i64, mv: i64) -> i64
529func fg_terminal(base: i64, scratch: *i64) -> i64
557func fg_fill_gridlines(base: i64, gw: i64, gh: i64, gl: i64, mode: i64, at: i64) -> i64
called by 1: fg_parse_arena calls 1: fg_hdr
611func fg_fill_gridadj(base: i64, gw: i64, gh: i64, mode: i64) -> i64
called by 1: fg_parse_arena calls 1: fg_hdr
662func fg_parse_arena(buf: *u8, n: i64, arena: i64, cap: i64) -> i64
999func fg_parse(buf: *u8, n: i64) -> i64 { return fg_parse_arena(buf, n, 0, 0) }
1005func fg_read_spec(path: *u8, lp: *i64) -> *u8
1017func fg_parse_file(path: *u8) -> i64
1026func fg_snapwords(base: i64) -> i64
called by 3: mainmainmain calls 1: fg_hdr
1030func fg_save(base: i64, out: *i64) -> i64
1040func fg_load(base: i64, inp: *i64) -> i64
1053func fg_name_is(buf: *u8, ls: i64, le: i64, slug: *u8) -> i64
1072func fg_parse_named_at(buf: *u8, n: i64, slug: *u8, depth: i64) -> i64
1125func fg_parse_named(buf: *u8, n: i64, slug: *u8) -> i64
1128func fg_parse_named_file(path: *u8, slug: *u8) -> i64