commit d08a76b7ff30bb4ea543ccb9587cb65c84658ae2 Author: dozens Date: Sat Oct 2 14:47:53 2021 -0600 init config diff --git a/README.md b/README.md new file mode 100644 index 0000000..744e608 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Ceelo + +This is a fun dice game + + + +## Getting started + +1. write fennel + +2. run the justfile + +## TODO + +1. Don't allow player to go into negative (Game over at zero dollars) + +2. Abstract common parts of `bank-roll` and `player-roll` + +3. I/O: Persist cash amt to player.fnl diff --git a/justfile b/justfile new file mode 100644 index 0000000..c4b0b2d --- /dev/null +++ b/justfile @@ -0,0 +1,7 @@ +# see what recipes are available +default: + just -l + +# watch for changes +watch: + fd -e fnl | entr -c fennel main.fnl diff --git a/lib/parser.fnl b/lib/parser.fnl new file mode 100644 index 0000000..220d4b2 --- /dev/null +++ b/lib/parser.fnl @@ -0,0 +1,39 @@ +;; a map of return value meanings for `parse` +(local dict { + 0 :no-value + 1 :lose + 2 :point-value + 3 :point-value + 4 :point-value + 5 :point-value + 6 :win + }) + +;; returns a code (see `dict`) and an annotation +(fn parse [t] + "parse :: [ x y z ] -> [ n str ]" + (match (doto t (table.sort)) + [ x x x ] [ 6 "trips! instawin" ] + [ 4 5 6 ] [ 6 "hi str8 instawin" ] + [ x x 6 ] [ 6 "6pt instawin" ] + [ 1 2 3 ] [ 1 "lo str8 instalose" ] + [ 1 x x ] [ 1 "1pt instalose" ] + [ x x y ] [ y (.. y "point") ] + [ y x x ] [ y (.. y "point") ] + _ [ 0 "nothing" ] + ) + ) + +;; Usage: +;(local {: rolls} (require :dice-roller)) +;(let [t (rolls) +; [ n str ] (parse t) +; pp (fn [x] (table.concat x " ")) +; ] +; (print (pp t) n (. dict n) str) +; ) + +{ + : parse + : dict + } diff --git a/lib/roller.fnl b/lib/roller.fnl new file mode 100644 index 0000000..1b122ff --- /dev/null +++ b/lib/roller.fnl @@ -0,0 +1,18 @@ +;; dice-roller.fnl +(math.randomseed (os.time)) + +(fn roll [] + "Return a random number between 1 and 6" + (math.random 1 6) + ) + +(fn rolls [] + "Return a table of 3 random numbers" + (local t []) + (for [i 1 3] + (table.insert t (roll)) + ) + t + ) + +{: rolls } diff --git a/lib/wrapper.fnl b/lib/wrapper.fnl new file mode 100644 index 0000000..001de39 --- /dev/null +++ b/lib/wrapper.fnl @@ -0,0 +1,32 @@ +(fn wrap [str limit indent indent1] + (let [indent (or indent "") + indent1 (or indent1 indent) + limit (or limit 72) + ] + (var here (- 1 (# indent1))) + (fn check [sp st word fi] + (when (> (- fi here) limit) + (set here (- st (# indent))) + (.. "\n" indent word))) + (.. indent1 (: str :gsub "(%s+)()(%S+)()" check)) + ) + ) + + +(fn reflow [str limit indent indent1] + (doto (str:gsub "%s*\n%s+" "\n") + (: :gsub "%s%s+" " ") + (: :gsub "[^\n]+" (fn [line] (wrap line limit indent indent1))) + ) + ) + + +(local words "Okay ceelo is a fun dice game. It is a point-set gambling game, kind of like craps, but is more simple, and you play it with three six-sided dice.\n\n== ROLLS ==\n\nFirst, here's what the rolls mean.\n\n1. Win conditions:\n\n- n n n (triples) = instant win.\n example: 3 3 3\n\n- 4 5 6 = instant win\n\n- n n 6 (any doubles + 6) = instant win. e.g.\n example: 2 2 6\n\n2. Loss conditions:\n\n- n n 1 (any doubles + 1) = instant loss\n example: 6 6 1\n\n- 1 2 3 = instant loss\n\n3. Points:\n\n- n n x (doubles + not 6, not 1) = establish a POINT\n example: 3 3 4\n\n\nReroll:\n\n- anything else = reroll\n\n== PLAY ==\n\nNow, here's how to play.\n\n1. Make a bet against the Bank.\n\n2. The Bank will roll and will either win, lose, or establish a point.\n\n3. If a point is established, you get to roll until you win outright or beat the point, or lose, or draw.\n\nThat's it! Go play!\n\nPress Enter to continue.\n") + +(print (wrap words)) + + +{ + :wrap wrap + :reflow reflow +} diff --git a/main.fnl b/main.fnl new file mode 100644 index 0000000..da69f43 --- /dev/null +++ b/main.fnl @@ -0,0 +1,17 @@ +;; main.fnl +(local player (require :player)) +(var mode (require :mode.menu)) +(var quit false) + +(fn set-mode [m] + (set mode (require m)) + ) + +(while (not quit) + (os.execute :clear) + (mode.display player) + (local cmd (io.read)) + (if (= cmd "q") (set quit true)) + (mode.key-pressed player cmd set-mode) + ) + diff --git a/mode/bet.fnl b/mode/bet.fnl new file mode 100644 index 0000000..80d0306 --- /dev/null +++ b/mode/bet.fnl @@ -0,0 +1,19 @@ +{ + :name "bet" + + :display (fn [p] + (print (string.format "You have $%d." p.cash)) + (print (string.format "Your current bet is $%d." p.bet)) + (print "Enter a new bet.\n") + (io.write "> ") +) + + :key-pressed (fn key-pressed [p amt set-mode] + (let [valid? (<= (tonumber amt) p.cash)] + (when valid? + (set p.bet amt) + (set-mode :mode.menu) + ) + ) + ) + } diff --git a/mode/menu.fnl b/mode/menu.fnl new file mode 100644 index 0000000..24e50c8 --- /dev/null +++ b/mode/menu.fnl @@ -0,0 +1,22 @@ +{ + :name "menu" + + :display (fn [player] + (print "== Ceelo Game ==\n") + (print (string.format "You have $%d." player.cash)) + (print (string.format "Your current bet is $%d.\n" player.bet)) + (print "(b)et") + (print "(p)lay") + (print "(r)ules") + (print "(q)uit\n") + (io.write "> ") +) + + :key-pressed (fn key-pressed [p k set-mode] + (match k + "p" (set-mode :mode.play) + "b" (set-mode :mode.bet) + "r" (set-mode :mode.rules) + ) + ) + } diff --git a/mode/play.fnl b/mode/play.fnl new file mode 100644 index 0000000..fb793a3 --- /dev/null +++ b/mode/play.fnl @@ -0,0 +1,71 @@ +(local {: rolls} (require :lib.roller)) +(local {: parse } (require :lib.parser)) + +(fn game-over [p m s] + (set p.cash (+ p.cash (* p.bet m))) + (set p.turn false) + (print (string.format s p.bet)) + (print "\nEnter 'm' to return to menu or just press Enter to play again") + ) + +(fn lose [p] + (game-over p -1 "You lose $%d")) + +(fn win [p] + (game-over p 1 "You win $%d!")) + +(fn set-point [player pt] + (set player.point pt) + (print (string.format "Point set to %d." pt)) + ) + +(fn bank-roll [p] + (let [t (rolls) + [ n str ] (parse t) + pp (fn [x] (table.concat x " ")) + ] + (print (pp t) str) + (match n + 6 (lose p) + 1 (win p) + 0 (bank-roll p) + x (set-point p x) + ) + ) + ) + +(fn player-roll [p] + (let [t (rolls) + [ n str ] (parse t) + pp (fn [x] (table.concat x " ")) + ] + (print (pp t) str) + (match n + 6 (win p) + 1 (lose p) + (where x (> x p.point)) (win p) + _ (player-roll p) + ) + ) + ) + +{ + :name "play" + + :display (fn [p] + (set p.turn true) + (print "Bank rolls first..") + (print (bank-roll p)) + (when p.turn + (print "Player's turn") + (player-roll p) + ) + ) + + :key-pressed (fn key-pressed [p k set-mode] + (match k + "m" (set-mode :mode.menu) + "p" (set-mode :mode.play) + ) + ) + } diff --git a/mode/rules.fnl b/mode/rules.fnl new file mode 100644 index 0000000..2277cbd --- /dev/null +++ b/mode/rules.fnl @@ -0,0 +1,17 @@ +(fn dump-contents [filename] + (let [f (assert (io.open filename)) + contents (f:read "*all")] + (f:close) + contents)) + +{ + :name "rules" + + :display (fn [p] + (print (dump-contents "mode/rules.txt")) + ) + + :key-pressed (fn key-pressed [p k set-mode] + (set-mode :mode.menu) + ) + } diff --git a/mode/rules.txt b/mode/rules.txt new file mode 100644 index 0000000..7f0d2ef --- /dev/null +++ b/mode/rules.txt @@ -0,0 +1,54 @@ +Okay ceelo is a fun dice game. It is a point-set gambling game, kind of like +craps, but is more simple, and you play it with three six-sided dice. + +== ROLLS == + +First, here's what the rolls mean. + +1. Win conditions: + +- n n n (triples) = instant win. + + example: 3 3 3 + +- 4 5 6 = instant win + +- n n 6 (any doubles + 6) = instant win. e.g. + + example: 2 2 6 + +2. Loss conditions: + +- n n 1 (any doubles + 1) = instant loss + + example: 6 6 1 + +- 1 2 3 = instant loss + +3. Points: + +- n n x (doubles + not 6, not 1) = establish a POINT + + example: 3 3 4 + + +Reroll: + +- anything else = reroll + +== PLAY == + +Now, here's how to play. + +1. Make a bet against the Bank. + +2. The Bank will roll and will either win, lose, or establish a point. + +3. If a point is established, you get to roll until you win outright or beat +the point, or lose, or draw. + +That's it! Go play! + +Press Enter to continue. + + diff --git a/player.fnl b/player.fnl new file mode 100644 index 0000000..2c28567 --- /dev/null +++ b/player.fnl @@ -0,0 +1,6 @@ +{ + :cash 100 + :point 6 + :bet 20 + :turn true + }