I'm writing a console blackjack game.
To hold all the possible moves a player can make, I have a map that maps a keyboard key to a move keyword:
(def move-map {\s :stand
\h :hit
\p :split
\d :double})
Splitting and doubling are only available options during the first move though, so I'd like to filter them out of the available moves before verifying the user's input if they aren't legal moves.
My current method is to indicate which are legal using a flag for doubling and one for splitting, then filtering the map if a flag isn't set:
(defn- filter-moves [moves can-split? can-double?]
(let [r-split (if can-split? moves (filter #(not= :split (second %)) moves))
r-doub (if can-double? r-split (filter #(not= :double (second %)) r-split))]
(into {} r-doub)))
The problem is, this contains a fair amount of redundancy. It should only iterate the map once because filter
is lazy, but I'm still not happy with this solution.
Usage:
(filter-moves move-map true false)
=> {"s" :stand, "h" :hit, "p" :split}
Any improvement suggestions would be appreciated. I'm not against redesigning the function if it helps readability and maintainability.