summaryrefslogtreecommitdiff
path: root/main.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'main.fnl')
-rw-r--r--main.fnl114
1 files changed, 75 insertions, 39 deletions
diff --git a/main.fnl b/main.fnl
index bf6933e..fae5445 100644
--- a/main.fnl
+++ b/main.fnl
@@ -5,6 +5,7 @@
: kvflip
: pprint
: slice
+ : all-mills?
:mill-at? mill-at-maker
:space-is-neighbor? space-is-neighbor-maker
} (require :lib.index))
@@ -28,21 +29,29 @@
})
+;; story mode:
;; there are two players
-;; their names are LUIGI and MARIO
+;; their names are WIGI and MALO
(local player {
- :one 1 ;; luigi has light cows
- :two 2 ;; mario has DARK cows >:)
+ :one 1 ;; wigi has light cows
+ :two 2 ;; malo has DARK cows >:)
})
; return the numerical index (1-24) of a [A-Za-z0-9] formatted move
(fn index-of-move [m]
- (let [upper (string.upper m)
- rev (string.reverse upper)
- idx (head (icollect [i v (ipairs const.spaces)]
- (if (or (= v upper) (= v rev)) i)))]
- idx))
+ (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)]
+ (if (or (= v upper) (= v rev)) i)))]
+ idx))
+
+
+(fn player-count [moves player]
+ (accumulate [count 0
+ _ x (ipairs moves)]
+ (if (= x player) (+ count 1) count)))
;; game state object
@@ -51,34 +60,57 @@
:stage stages.placing
:update (fn [self move]
(case self.stage
- 4 ;; capture
+ 4 ;; CAPTURE
(do
- ;; TODO: capturing during moving is not working?
(tset self.moves (index-of-move move) 0)
(tset self :player (self:next-player))
- (tset self :stage (if (> self.pieces-placed 17) stages.moving stages.placing))
- (tset self.moves (index-of-move move) self.player)
- )
- 1 ;; placing
+ (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
+ movetime stages.moving
+ stages.placing))))
+ 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.moves (index-of-move move) self.player)
- (if (mill-at? self.moves (index-of-move move))
- (tset self :stage stages.capture)
- (tset self :player (self:next-player))
- )
- )
- 2 ;; moving
+ (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))
+ capturetime (mill-at? self.moves (index-of-move move))]
+ (tset self :stage (if
+ capturetime stages.capture
+ flytime stages.flying
+ movetime stages.moving
+ stages.placing))
+ (if (not capturetime) (tset self :player (self:next-player)))))
+ 2 ;; MOVING
(let [from (index-of-move (string.sub move 1 2))
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)))]
+ (tset self :stage (if
+ capturetime stages.capture
+ flytime stages.flying
+ movetime stages.moving
+ stages.placing))
+ (if (not capturetime) (tset self :player (self:next-player)))))
+ 3 ;; FLYING
+ (let [from (index-of-move (string.sub move 1 2))
+ to (index-of-move (string.sub move -2 -1))]
(tset self.moves from 0)
(tset self.moves to self.player)
- (if (mill-at? self.moves to)
- (tset self :stage stages.capture)
- (tset self :player (self:next-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)))]
+ (tset self :stage (if
+ capturetime stages.capture
+ flytime stages.flying
+ movetime stages.moving
+ stages.placing))
+ (if (not capturetime) (tset self :player (self:next-player)))))
)
)
:next-player (fn [self] (if (= player.one self.player) player.two player.one))
@@ -98,6 +130,7 @@
(game:init)
+; TODO: move to lib utility
(fn string-upper [s]
(.. (string.upper (string.sub s 1 1)) (string.sub s 2)))
@@ -136,27 +169,23 @@
(let [unoccupied? 0] ; i.e. is move equal to 0
(= unoccupied? (. game.moves (index-of-move m)))))
-
+; is the space m occupied by the player's opponent?
(fn space-is-occupied-by-opponent? [m]
+ "is the space m occupied by the player's opponent?"
(let [opponent (if (= game.player 1) 2 1)
result (= opponent (. game.moves (index-of-move m))) ]
result))
-
+; checks that the first 2 charcters and the last 2 characters
+; of a string are legal spaces
+; moving-format is the same as flying-format
(fn moving-format? [m]
(let [from (string.sub m 1 2)
to (string.sub m -2 -1)]
- (and (space-exists? from) (space-exists? to))))
+ (and (>= (length m) 4) (space-exists? from) (space-exists? to))))
+
; is this a legal move?
-; maybe some functional error handling here?
-; https://mostly-adequate.gitbook.io/mostly-adequate-guide/ch08#pure-error-handling
-; https://mostly-adequate.gitbook.io/mostly-adequate-guide/appendix_b#either
-; or maybe all i need is a case-try statement..
-; https://fennel-lang.org/reference#case-try-for-matching-multiple-steps
-; update: i didn't really like that
-; i think maybe i do want the monad after all..
-; i'll come back to it later
(fn valid-move? [move]
(or
(and
@@ -169,8 +198,10 @@
(= stages.capture game.stage)
(or (space-is-occupied-by-opponent? move)
(print "Choose an opponent's piece to remove."))
- (or (not (mill-at? game.moves (index-of-move move)))
- (print "Ma'am, it is ILLEGAL to break up a mill."))
+ (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)
@@ -184,8 +215,13 @@
(print "That ain't your neighbor, Johnny"))
)
(and
- ;; TODO: add flying phase
(= stages.flying game.stage)
+ (or (moving-format? move)
+ (print "Try a move like A1A2 or A7 D7"))
+ (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!"))
)
)
)