diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | dist/.gitkeep | 0 | ||||
| -rw-r--r-- | doc/README.md | 12 | ||||
| -rw-r--r-- | doc/tilde30.t | 23 | ||||
| -rw-r--r-- | justfile | 7 | ||||
| -rw-r--r-- | src/story/README.md | 110 | ||||
| -rw-r--r-- | src/story/cards.dat | 46 | ||||
| -rw-r--r-- | src/story/story.dat | 19 | ||||
| -rw-r--r-- | src/story/story.fnl | 58 | ||||
| -rw-r--r-- | src/story/story.test.dat | 80 | ||||
| -rw-r--r-- | src/story/story.test.fnl | 16 | ||||
| -rw-r--r-- | test/README.md (renamed from test/README) | 9 | 
12 files changed, 375 insertions, 6 deletions
| @@ -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 @@ -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? | 
