summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--dist/.gitkeep0
-rw-r--r--doc/README.md12
-rw-r--r--doc/tilde30.t23
-rw-r--r--justfile7
-rw-r--r--src/story/README.md110
-rw-r--r--src/story/cards.dat46
-rw-r--r--src/story/story.dat19
-rw-r--r--src/story/story.fnl58
-rw-r--r--src/story/story.test.dat80
-rw-r--r--src/story/story.test.fnl16
-rw-r--r--test/README.md (renamed from test/README)9
12 files changed, 375 insertions, 6 deletions
diff --git a/.gitignore b/.gitignore
index ae062d0..0f00ec3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 test/*.expect
+dist/nmm
diff --git a/dist/.gitkeep b/dist/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dist/.gitkeep
diff --git a/doc/README.md b/doc/README.md
index 0452038..bc998a5 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -38,7 +38,8 @@ Here's what it looks like:
 
 ## BACKGROUND
 
-9mm is legit a great game.
+Nine Mens Morris is legit a great game,
+and I like it a lot.
 
 One time i wrote an essay about the social contract implicit to nine mens morris:
 https://write.tildeverse.org/dozens/nine-mens-morris-cultural-meanings-and-social-contracts
@@ -49,3 +50,12 @@ https://en.wikipedia.org/wiki/Morabaraba
 also look at these round cows
 https://en.wikipedia.org/wiki/Spherical_cow
 
+## USAGE
+
+1. If you have fennel installed,
+   run `fennel main.fnl`
+
+2. If you have fennel installed,
+   you can compile a binary
+   using `fennel --compile-binary`.
+   (See `justfile` for an example of how I do it.)
diff --git a/doc/tilde30.t b/doc/tilde30.t
index 8a6911a..c17d27d 100644
--- a/doc/tilde30.t
+++ b/doc/tilde30.t
@@ -310,6 +310,29 @@ for the client to interpret.
 I'm still interested in the Result / Either monad option
 but I think I'm doing to first try the conventional lua way
 and throw an error, and then 'pcall' the function and handle the error politely.
+.
+.
+.IP "WEEK FOUR REVIEW"
+Today is the end of tilde30!
+I didn't get too much done this week
+on account of the surgery.
+At least,
+I wasn't able to keep up with the daily updates.
+I did end up writing a tracery-lite
+type templating thing
+that you can find
+in `src/story`.
+I did not succeed in
+actually incorporating it into the game.
+But it's there.
 
+tilde30 on the whole was a fun exercise
+and a success.
+I had a lot of fun working on my project,
+and I especially had a lot of fun hearing about other people's projects.
+Even if they didn't complete them.
+I am planning to do it again in September,
+and am planning to continue working on 9mm
+in the meantime!
 
 .pl \n[nl]u
diff --git a/justfile b/justfile
index 825aa93..be64e85 100644
--- a/justfile
+++ b/justfile
@@ -2,10 +2,15 @@
 default:
   just --list --unsorted
 
+build:
+  fennel --compile-binary main.fnl dist/nmm \
+  /usr/local/lib/liblua.a \
+  /usr/local/include/lua5.4
+
 # run tests
 test:
   #!/bin/zsh
-  for f in **/*.test.fnl; do fennel $f | faucet; done
+  for f in lib/**/*.test.fnl; do fennel $f | faucet; done
 
 # build expect scripts
 expects:
diff --git a/src/story/README.md b/src/story/README.md
new file mode 100644
index 0000000..0cb81f4
--- /dev/null
+++ b/src/story/README.md
@@ -0,0 +1,110 @@
+## Format
+
+Here is a list of lists
+representing a slightly augmented
+deck of cards
+(basically the heckadeck):
+
+
+```
+:: suit
+spades
+hearts
+clubs
+diamonds
+acorns
+clouds
+swords
+planets
+
+:: face
+beast
+thief
+jack
+queen
+king
+
+:: number
+zero
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+twelve
+
+:: special
+crone
+joker
+watcher
+traveler
+
+:: card
+[[number]]
+[[face]]
+
+:: draw
+[[card]] of [[suit]]
+[[special]]
+```
+
+A list title appears on a line by itself,
+preceded by a double colon (::)
+and at least one space.
+A list title can contain alphabet characters and a dash.
+
+Following the list title are list items,
+each on its own line.
+A list item may be (or contain) a reference
+to a list title in double brackets.
+e.g. [[list-title]]
+
+Blank lines are ignored.
+
+## Usage
+
+Pass the filename of a file of lists formatted in this way
+to `create_corpus`
+and get a "corpus" in return.
+A corpus is just a deserialized fennel table
+of list titles and list items.
+
+Then pass the corpus to `flatten`
+along with a string or a list to serve as the "origin".
+In this case if you pass `corpus.draw`,
+then `flatten` will return a random selection from `:draw`,
+expanding references along the way:
+
+- beast of spades
+- five of hearts
+- jack of acorns
+- watcher
+- three of planets
+- beast of clubs
+ 
+Read and run `story.test.fnl` for an example.
+
+## Inspiration
+
+This is inspired by [tracery][1]
+and [perchance][4]
+and the [List to HTML Generator][5],
+and is similar to [twee][2] format.
+In fact,
+with just a little modification,
+you can use this story file 
+to generate tracery output
+in a twine story
+using [trice][3].
+
+[1]: https://github.com/galaxykate/tracery
+[2]: https://twinery.org/cookbook/terms/terms_twee.html
+[3]: https://github.com/incobalt/Trice
+[4]: https://perchance.org/
+[5]: https://slightadjustments.blogspot.com/p/generator.html
diff --git a/src/story/cards.dat b/src/story/cards.dat
new file mode 100644
index 0000000..12a1a8f
--- /dev/null
+++ b/src/story/cards.dat
@@ -0,0 +1,46 @@
+:: suit
+spades
+hearts
+clubs
+diamonds
+acorns
+clouds
+swords
+planets
+
+:: face
+beast
+thief
+jack
+queen
+king
+
+:: number
+zero
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+twelve
+
+:: special
+crone
+joker
+watcher
+traveler
+
+:: card
+[[number]]
+[[face]]
+
+:: draw
+[[card]] of [[suit]]
+[[special]]
+
diff --git a/src/story/story.dat b/src/story/story.dat
new file mode 100644
index 0000000..7c48d1a
--- /dev/null
+++ b/src/story/story.dat
@@ -0,0 +1,19 @@
+:: origin
+[[you]] [[need]] [[go]] [[search]] [[find]] [[take]] [[return]] [[change]]
+
+:: you
+[[beginning]]
+
+:: beginning
+Once upon a time
+I've told you before but I'll tell you again
+Once there was
+One day, a long time ago
+There was and there was not
+East of the sun and west of the moon
+In the beginning
+Back in the day
+I remember when
+On an old day, in the old times
+Back when tigers used to smoke tobacco
+That time then and once again
diff --git a/src/story/story.fnl b/src/story/story.fnl
new file mode 100644
index 0000000..f1ca812
--- /dev/null
+++ b/src/story/story.fnl
@@ -0,0 +1,58 @@
+(fn lines [filename callback]
+  (case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
+    (false err) (print (string.format "Error: Could not open file %s\n%s" filename err))))
+
+(fn _create-corpus [lines data]
+  (var current-key nil)
+  (var corpus {})
+  (lines data
+    #(let [key (string.match $1 "^::%s+([%a-]+)")
+           blank (or (= nil $1) (= "" $1))]
+      (when (not blank)
+        (if (not key)
+          (let [list (. corpus current-key)]
+            (table.insert list $1)
+            (tset corpus current-key list))
+          (do
+            (set current-key key)
+            (tset corpus current-key []))))))
+  corpus)
+(local create-corpus (partial _create-corpus lines))
+
+(fn one-of [t]
+  "returns a random element of a sequential or non-sequential table"
+  (let [len (accumulate [l 0 _ _ (pairs t)] (+ l 1)) ;; do it the hard way
+                                                     ;; because nonseq tables
+                                                     ;; have no length?
+        handle (io.popen "echo $RANDOM")
+        output (handle:read "*a")
+        random (output:gsub "[\n\r]" "")
+        seed (math.randomseed random) ;; SIDE EFFECT
+        whatever (handle:close)       ;; SIDE EFFECT
+        idx (math.random len)
+        keys (accumulate [acc [] k v (pairs t)] (do (table.insert acc k) acc))
+        rndkey (. keys idx)
+        it (. t rndkey)]
+    it))
+
+(fn flatten [corpus origin]
+  (let [str (if (= "string" (type origin))
+              origin
+              (if (= "table" (type origin))
+                (one-of origin)
+                (error "Origin must be a table or a string")))
+        template-pattern "%[%[[%a-]+%]%]" ; [[word]]
+        word-pattern "%[%[([%a-]+)%]%]"   ; word
+        (i j) (string.find str template-pattern) ; indices
+        word (string.match str word-pattern)]    ; the actual keyword
+    (if (not i)
+      str
+      (let [next-str (string.format "%s%s%s"
+              (string.sub str 1 (- i 1))
+              (one-of (. corpus word))
+              (string.sub str (+ j 1)))]
+        (flatten corpus next-str j))))) ;; this is a tail call!
+
+{: create-corpus
+ : flatten
+ }
diff --git a/src/story/story.test.dat b/src/story/story.test.dat
new file mode 100644
index 0000000..e28ad44
--- /dev/null
+++ b/src/story/story.test.dat
@@ -0,0 +1,80 @@
+:: start
+To [[do]] in the [[place]] [[preposition]] the [[color]] [[celestial]]
+
+:: do
+[[walk]]
+[[feel]]
+
+:: place
+[[biome]]
+[[weather]] [[biome]]
+[[weather]] [[biome]]
+
+:: feel
+brood
+go to pieces
+wallow
+percolate
+ferment
+pine
+waste away
+ponder
+wonder
+
+:: preposition
+beneath
+amongst
+betwixt
+below
+between
+through
+around
+despite
+
+:: walk
+walk
+stroll
+jaunt
+wander
+meander
+amble
+stalk
+ambulate
+
+:: weather
+blistering
+undulating
+weeping
+mourning
+hidden
+secret
+wistful
+taciturn
+sticky
+
+:: biome
+woods
+dunes
+forest
+plains
+hills
+mountains
+ocean
+bog
+lake
+
+:: color
+chartreuse
+opalescent
+verdant
+vermilion
+aquamarine
+copper
+
+:: celestial
+skies
+moon
+stars
+planets
+clouds
+sun
diff --git a/src/story/story.test.fnl b/src/story/story.test.fnl
new file mode 100644
index 0000000..e4fce4d
--- /dev/null
+++ b/src/story/story.test.fnl
@@ -0,0 +1,16 @@
+(let [{
+  : flatten
+  : create-corpus 
+  } (require :src.story.story)]
+
+  (let [corpus (create-corpus "src/story/story.test.dat")
+        get-story (partial flatten corpus corpus.start)]
+      (print "\n== POEMS ==")
+      (for [_ 1 10] (print (get-story))))
+
+  (let [corpus (create-corpus "src/story/cards.dat")
+        get-story (partial flatten corpus corpus.draw)]
+      (print "\n== CARDS ==")
+      (for [_ 1 10] (print (get-story)))))
+
+
diff --git a/test/README b/test/README.md
index 11b09a4..a9602fa 100644
--- a/test/README
+++ b/test/README.md
@@ -1,6 +1,7 @@
-== ABOUT ==
+## ABOUT
 
-these files are to help me test the ui
+these files are to help me test the ui.
+actually, just the game state really.
 
 moves are recorded in `<file>.dat`.
 then you can `awk -f test.awk file.dat > file.expect`.
@@ -8,11 +9,11 @@ then you can `awk -f test.awk file.dat > file.expect`.
 then you can `expect file.expect`
 to have expect play the game for you up to a certain point.
 
-== REQUIREMENTS ==
+## REQUIREMENTS
 
 - awk
 - expect
 
-== FUTURE PLANS ==
+## FUTURE PLANS
 
 have actual integration tests?