-
Notifications
You must be signed in to change notification settings - Fork 0
/
lore.fnl
104 lines (85 loc) · 3.58 KB
/
lore.fnl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(local lume (require :lume))
;; for dev
(local view (require "fennel.view"))
(local pp (fn [x] (print (view x))))
;; Setting up random seed
(math.randomseed (os.time))
(fn randomseed [seed]
(math.randomseed seed))
(lambda smart-val [tbl]
(if (= (type tbl) "table")
(. tbl 1)
tbl))
(lambda random-grammar-match [rule]
(if (= (type rule) "table")
(lume.randomchoice rule)
rule))
(lambda generate-one [grammar ?target]
(let [target-key (or ?target "#origin#")]
(var target-val-copy (random-grammar-match (. grammar target-key)))
(each [key val (pairs grammar)]
(when (string.find target-val-copy key)
(set target-val-copy
(string.gsub target-val-copy key (lume.randomchoice val)))))
target-val-copy))
;; Might be a useful utility function to keep around. If not, delete it:
(lambda smart-concat [tbl potential-list]
(if (= (type potential-list) "string") (table.insert tbl potential-list)
(= (type potential-list) "table") (lume.concat tbl potential-list)))
(lambda table-contains [list item]
(lume.any list (fn [list-item] (= list-item item))))
(lambda arrays-all-items-match [lista listb]
(if (= (# lista) (# listb))
(lume.all lista (fn [item] (table-contains listb item)))))
(lambda validate-actions [actions]
(each [_ action (ipairs actions)]
(assert action.filter-fn "Must have a filter function.")
))
(lambda validate-nouns [nouns] nouns)
;; Simplest one for now, more complex later:
(lambda filter-function-tags-for [filter-tags]
(fn [e]
(let [entity-keys (lume.keys e)]
(lume.all filter-tags (fn [filter-key] (table-contains entity-keys filter-key))))))
(lambda prepare-actions [scene]
(each [_ action (ipairs scene.actions)]
(tset action :scene scene)
(tset action :nouns scene.nouns)
(when (not action.filter-fn)
(when action.filter-tags
(tset action :filter-fn (filter-function-tags-for action.filter-tags))))))
(lambda prepare-scene [scene]
;; link each noun back up to the scene so that we can use that association in filter functions
(each [_ noun (ipairs scene.nouns)]
(tset noun :scene scene))
(validate-nouns scene.nouns)
(prepare-actions scene)
(validate-actions scene.actions)
(tset scene :lines [])
scene)
(lambda tick [scene]
(each [_ action (ipairs scene.actions)]
(var matched-entities [])
(each [_ entity (ipairs scene.nouns)]
(when (action.filter-fn entity)
;; filter matches for this entity, perform action:
(let [lines (action.update action entity)]
(when lines
(table.insert scene.lines lines)))))))
(lambda entity-merge-grammar [grammar entity]
(var tmp-table {})
(each [k v (pairs entity)]
(tset tmp-table (string.format "#%s#" k) [v]))
(lume.merge grammar tmp-table))
(lambda line-for [action entity ?key]
(let [key (or ?key "#origin#")
combined-grammar (entity-merge-grammar action.grammar entity)]
(generate-one combined-grammar)))
(lambda expand-template [action goal mappings]
(generate-one (entity-merge-grammar action.grammar mappings) goal))
;; Exports
{:randomseed randomseed
:generate-one generate-one
:tick tick
:prepare-scene prepare-scene
:expand-template expand-template}