summaryrefslogtreecommitdiff
path: root/main.fnl
diff options
context:
space:
mode:
authordozens2024-06-15 21:15:59 -0600
committerdozens2024-06-18 19:43:51 -0600
commitce09973e7cacccdc779f91b8e6e48a520b9f9f4d (patch)
treedfa96b0558981278d95395be24668b15ac03732a /main.fnl
parent1250f9f057c2e21a0edab87f0a6003a25decd1b7 (diff)
feat: add end game
Diffstat (limited to 'main.fnl')
-rw-r--r--main.fnl86
1 files changed, 45 insertions, 41 deletions
diff --git a/main.fnl b/main.fnl
index fae5445..56c0536 100644
--- a/main.fnl
+++ b/main.fnl
@@ -1,19 +1,18 @@
;; helper and utility functions
(local {
- : contains
- : head
- : kvflip
- : pprint
- : slice
+ : str
+ : tbl
: all-mills?
:mill-at? mill-at-maker
:space-is-neighbor? space-is-neighbor-maker
+ :no-moves? no-moves-maker
} (require :lib.index))
;; constants...more like just strings
(local const (require :lib.constants))
;; front-loading with some partials
(local mill-at? (partial mill-at-maker const.mills))
(local space-is-neighbor? (partial space-is-neighbor-maker const.neighbors))
+(local no-moves? (partial no-moves-maker const.neighbors))
;; there are three phases of play:
@@ -43,7 +42,7 @@
(assert (= "string" (type m)) "index-of-move needs a string argument")
(let [upper (string.upper m)
rev (string.reverse upper)
- idx (head (icollect [i v (ipairs const.spaces)]
+ idx (tbl.head (icollect [i v (ipairs const.spaces)]
(if (or (= v upper) (= v rev)) i)))]
idx))
@@ -63,19 +62,24 @@
4 ;; CAPTURE
(do
(tset self.moves (index-of-move move) 0)
- (tset self :player (self:next-player))
- (let [flytime (and (> self.pieces-placed 17) (= 3 (player-count self.moves self.player)))
- movetime (and (> self.pieces-placed 17) (> (player-count self.moves self.player) 3))]
- (tset self :stage (if flytime stages.flying
+ (let [flytime (and (self:phase-two?) (= 3 (player-count self.moves (self:next-player))))
+ movetime (and (self:phase-two?) (> (player-count self.moves (self:next-player)) 3))
+ endtime (and (self:phase-two?)
+ (or (< (length (icollect [_ m (ipairs self.moves)] (if (= m 1) 1))) 3)
+ (< (length (icollect [_ m (ipairs self.moves)] (if (= m 2) 2))) 3)))]
+ (tset self :stage (if endtime stages.complete
+ flytime stages.flying
movetime stages.moving
- stages.placing))))
+ stages.placing))
+ (if (not endtime) (tset self :player (self:next-player)))
+ ))
1 ;; PLACING
(do
(set self.pieces-placed (+ 1 self.pieces-placed))
- (tset self :stage (if (> self.pieces-placed 17) stages.moving stages.placing))
+ (tset self :stage (if (self:phase-two?) stages.moving stages.placing))
(tset self.moves (index-of-move move) self.player)
- (let [flytime (and (> self.pieces-placed 17) (= 3 (player-count self.moves self.player)))
- movetime (and (> self.pieces-placed 17) (> (player-count self.moves self.player) 3))
+ (let [flytime (and (self:phase-two?) (= 3 (player-count self.moves self.player)))
+ movetime (and (self:phase-two?) (> (player-count self.moves self.player) 3))
capturetime (mill-at? self.moves (index-of-move move))]
(tset self :stage (if
capturetime stages.capture
@@ -88,13 +92,15 @@
to (index-of-move (string.sub move -2 -1))]
(tset self.moves from 0)
(tset self.moves to self.player)
- (let [flytime (and (> self.pieces-placed 17) (= 3 (player-count self.moves (self:next-player))))
- movetime (and (> self.pieces-placed 17) (> (player-count self.moves (self:next-player)) 3))
- capturetime (mill-at? self.moves (index-of-move (string.sub move -2 -1)))]
+ (let [flytime (and (self:phase-two?) (= 3 (player-count self.moves (self:next-player))))
+ movetime (and (self:phase-two?) (> (player-count self.moves (self:next-player)) 3))
+ capturetime (mill-at? self.moves (index-of-move (string.sub move -2 -1)))
+ endtime (no-moves? self.moves (self:next-player))]
(tset self :stage (if
capturetime stages.capture
flytime stages.flying
movetime stages.moving
+ endtime stages.complete
stages.placing))
(if (not capturetime) (tset self :player (self:next-player)))))
3 ;; FLYING
@@ -102,8 +108,8 @@
to (index-of-move (string.sub move -2 -1))]
(tset self.moves from 0)
(tset self.moves to self.player)
- (let [flytime (and (> self.pieces-placed 17) (= 3 (player-count self.moves (self:next-player))))
- movetime (and (> self.pieces-placed 17) (> (player-count self.moves (self:next-player)) 3))
+ (let [flytime (and (self:phase-two?) (= 3 (player-count self.moves (self:next-player))))
+ movetime (and (self:phase-two?) (> (player-count self.moves (self:next-player)) 3))
capturetime (mill-at? self.moves (index-of-move (string.sub move -2 -1)))]
(tset self :stage (if
capturetime stages.capture
@@ -111,10 +117,17 @@
movetime stages.moving
stages.placing))
(if (not capturetime) (tset self :player (self:next-player)))))
+ 5 ;; COMPLETE
+ (print "Unreachable!")
)
+ (tset self :turns (+ self.turns 1))
)
:next-player (fn [self] (if (= player.one self.player) player.two player.one))
:pieces-placed 0
+ :turns 0
+ ; so basically there's phase 1 where you place your checkers
+ ; and then phase 2 when you move and fly around trying to capture pieces
+ :phase-two? (fn [self] (> self.pieces-placed 17))
:init (fn [self]
; initialize moves[] to 0.
; this is the game state.
@@ -130,11 +143,6 @@
(game:init)
-; TODO: move to lib utility
-(fn string-upper [s]
- (.. (string.upper (string.sub s 1 1)) (string.sub s 2)))
-
-
; Print! That! Board!
(fn print-board [board moves]
(var index 1)
@@ -143,12 +151,13 @@
(if (> slots 0)
(do
(let [offset (+ index slots)
- myslice (slice moves index offset)]
+ myslice (tbl.slice moves index offset)]
(print (string.format row-template (table.unpack myslice)))
(set index offset)))
(print row))))
- (print (.. "Stage: " (string-upper (. (kvflip stages) game.stage))))
+ (print (.. "Stage: " (str.capitalize (. (tbl.invert stages) game.stage))))
(print (.. "Player " game.player "'s turn:")))
+(local with-board (partial print-board const.board))
; add the inverse of each valid move
@@ -161,7 +170,7 @@
; does the move exist within the domain of valid spaces
-(fn space-exists? [m] (contains const.spaces (string.upper m)))
+(fn space-exists? [m] (tbl.contains const.spaces (string.upper m)))
; is the space represented by a [A-Za-z0-9] move unoccupied?
@@ -201,8 +210,7 @@
(or (or (all-mills? game.moves game.player)
(not (mill-at? game.moves (index-of-move move))))
(print "Ma'am, it is ILLEGAL to break up a mill.")
- )
- )
+ ))
(and
(= stages.moving game.stage)
(or (moving-format? move)
@@ -212,8 +220,7 @@
(or (space-is-unoccupied? (string.sub move -2 -1))
(print "That space is occupied!"))
(or (space-is-neighbor? (index-of-move (string.sub move 1 2)) (index-of-move (string.sub move -2 -1)))
- (print "That ain't your neighbor, Johnny"))
- )
+ (print "That ain't your neighbor, Johnny")) )
(and
(= stages.flying game.stage)
(or (moving-format? move)
@@ -221,8 +228,7 @@
(or (not (space-is-occupied-by-opponent? (string.sub move 1 2)))
(print "That's not yours, don't touch it."))
(or (space-is-unoccupied? (string.sub move -2 -1))
- (print "That space is occupied!"))
- )
+ (print "That space is occupied!")))
)
)
@@ -235,8 +241,7 @@
(fn main []
;; game loop
(while (not (= game.stage stages.complete))
- (print-board const.board game.moves)
-
+ (with-board game.moves)
;; validation loop
(var is-valid false)
(var move "")
@@ -246,11 +251,10 @@
(if (not is-valid)
(print "Try again.")
(do
- (print (.. "You chose " move))
- (game:update move)
- )
- )
- )
- )
+ (print (string.format "Turn %d: You chose %s" game.turns move))
+ (game:update move)))))
+ ;; game is complete
+ (print "Congratulations!")
+ (print (string.format "Player %d is the winner!" game.player))
)
(main)