~subsetpark/whist

b4197421dcbc4b6877e7b574a1fc6ee2802d1171 — Zach Smith 11 months ago b677ce2
Replace add_score with info boxes
5 files changed, 52 insertions(+), 38 deletions(-)

M game/beginplay.janet
M game/play.janet
M init.janet
M test/last-card.janet
M test/whist.janet
M game/beginplay.janet => game/beginplay.janet +7 -5
@@ 15,10 15,12 @@
  - `suit`: The led suit of the current trick.
  ```
  [{:meta meta} players {:player bidder :value to-discard}]
  # It's the first trick; bidder gets one trick for the discard.
    (let [bidder-record (find |(= ($0 :id) bidder) players)
	    current-hand (in bidder-record :hand)]
	  current-hand (in bidder-record :hand)
	  other-players (filter |(not= ($0 :id) bidder) players)]
      [{:phase "play" :meta (merge meta {:suit :null})}
       [{:event "add_score" :player bidder :value 1}
	{:event "discard" :player bidder :value to-discard}
	{:event "prompt_play" :player bidder :to "trick" :count 1}]]))
       (array/concat (map |{:event "add_info" :name (keyword ($0 :id) "_tricks") :value 0} other-players)
		     # It's the first trick; bidder gets one trick for the discard.
		     {:event "add_info" :name (keyword bidder "_tricks") :value 1}
		     {:event "discard" :player bidder :value to-discard}
		     {:event "prompt_play" :player bidder :to "trick" :count 1})]))

M game/play.janet => game/play.janet +2 -2
@@ 46,7 46,7 @@
  # allows us to check for the edge case where the suit has
  # not been set, even after a card (or two) has been played
  # - if the first card is a Joker, and it's no trumps.
  (var new-state @{:meta @{} :stacks @{}})
  (var new-state @{:info (old-state :info) :meta @{} :stacks @{}})
  (var events @[(events/add-decoration player "play_action" (string "played " (cards/to-text card)))])
  (let [current-trick (get-in old-state [:stacks :trick])
	current-bid (get-in old-state [:meta :bid])


@@ 58,7 58,7 @@
	      current-suit (get-in old-state [:meta :suit])
	      highest (cards/high-card current-suit (current-bid :suit) ;with-compare)
	      highest-player (highest :player)]
	  (array/push events {:event "add_score" :player highest-player :value 1})
	  (update-in new-state [:info (keyword highest-player "_tricks") :value] inc)
	  (case (length ((players 0) :hand)) 
	    # It's the last trick of the hand.
	    # TODO: reckon scores and reset

M init.janet => init.janet +15 -8
@@ 2,20 2,27 @@
  config
  []
  {:deck "52JJ"
   :stacks {"trick" {:orientation :up
		     :max-size 4
		     :alignment :stagger}}})
   :stacks [{:name "trick"
	     :orientation :up
	     :max-size 4
	     :alignment :stagger}]
   :info [{:name "north_south" :label "North/South" :value 0}
	  {:name "east_west" :label "East/West" :value 0}
	  {:name "tricks_north" :value 0}
	  {:name "tricks_east" :value 0}
	  {:name "tricks_south" :value 0}
	  {:name "tricks_west" :value 0}]})

(defn-
  make-player
  [id team]
  {:id id :team team :score 0})
  {:id id :team team})

(defn init
  "Create an initial game state."
  [fst snd thd fth]
  {:players [(make-player fst 1)
	     (make-player snd 2)
	     (make-player thd 1)
	     (make-player fth 2)]
  {:players [(make-player fst "north_south")
	     (make-player snd "east_west")
	     (make-player thd "north_south")
	     (make-player fth "east_west")]
   :state {:phase "deal"}})

M test/last-card.janet => test/last-card.janet +19 -17
@@ 14,21 14,22 @@
   {:hand [S2 SA] :score 0 :team 2 :id "West"}])

(deftest north-takes-the-trick
  (def player-lead {:players two-cards-left
		    :state {:phase "play" :meta {:suit "clubs"
						 :bid {:count 3 :suit "notrumps" :direction "up"}}
			    :stacks {:trick [(merge-into @{:player "East"} CK)
					     (merge-into @{:player "South"} D2)
					     (merge-into @{:player "West"} S3)]}}
		    :action {:player "North" :name "play" :value CA}})
  (def player-lead @{:players two-cards-left
		     :state @{:phase "play" :meta @{:suit "clubs"
						    :bid @{:count 3 :suit "notrumps" :direction "up"}}
			      :info @{:North_tricks @{:value 0}}
			      :stacks @{:trick [(merge-into @{:player "East"} CK)
						(merge-into @{:player "South"} D2)
						(merge-into @{:player "West"} S3)]}}
		     :action @{:player "North" :name "play" :value CA}})
  (def [state events] (whist/next player-lead))
  (def [north-decoration north-add-score north-prompt] events)
  (def [north-decoration  north-prompt] events)
  (let [played-card (merge-into @{:player "North"} CA)]
    (is (deep= @{} (state :meta)))
    (is (deep= @{:trick []} (state :stacks))))
    (is (deep= @{:trick []} (state :stacks)))
    (is (deep= @{:North_tricks @{:value 1}} (state :info))))
  (is (= {:value "played \xE2\x99\xA3Ace" :event "add_decoration" :player "North" :name "play_action"}
	 north-decoration))
  (is (= {:event "add_score" :value 1 :player "North"} north-add-score))
  (is (deep= {:player "North" :event "prompt_play" :count 1 :to "trick" :from [C2 CA]}
	     north-prompt)))



@@ 39,13 40,14 @@
   {:hand [SA] :score 0 :team 2 :id "West"}])

(deftest north-takes-the-last-trick
  (def player-lead {:players last-cards
		    :state {:phase "play" :meta {:suit "clubs"
						 :bid {:count 3 :suit "notrumps" :direction "up"}}
			    :stacks {:trick [(merge-into @{:player "East"} CK)
					     (merge-into @{:player "South"} D2)
					     (merge-into @{:player "West"} S3)]}}
		    :action {:player "North" :name "play" :value CA}})
  (def player-lead @{:players last-cards
		     :state @{:phase "play" :meta @{:suit "clubs"
						    :bid @{:count 3 :suit "notrumps" :direction "up"}}
			      :info @{:North_tricks @{:value 0}}
			      :stacks @{:trick [(merge-into @{:player "East"} CK)
						(merge-into @{:player "South"} D2)
						(merge-into @{:player "West"} S3)]}}
		     :action @{:player "North" :name "play" :value CA}})
  (def [state events] (whist/next player-lead))
  # TODO: Test end of hand.
  (def [] events))

M test/whist.janet => test/whist.janet +9 -6
@@ 9,10 9,10 @@

(def- players ["North" "East" "South" "West"])

(def- player-state [{:score 0 :team 1 :id "North"}
		    {:score 0 :team 2 :id "East"}
		    {:score 0 :team 1 :id "South"}
		    {:score 0 :team 2 :id "West"}])
(def- player-state [{:team "north_south" :id "North"}
		    {:team "east_west" :id "East"}
		    {:team "north_south" :id "South"}
		    {:team "east_west" :id "West"}])

(defn all-not-passed [] @{:North true :East true :South true :West true}) 



@@ 114,8 114,11 @@
				  :meta {:suit :null}}
			  :action {:player "North" :name "discard" :value [C2]}}]
    (def [state events] (whist/next player-discarded))
    (def [north-score north-discard north-prompt] events)
    (is (= {:event "add_score" :value 1 :player "North"} north-score))
    (def [east-info south-info west-info north-info north-discard north-prompt] events)
    (is (= {:value 1 :name :North_tricks :event "add_info"} north-info))
    (is (= {:value 0 :name :East_tricks :event "add_info"} east-info))
    (is (= {:value 0 :name :South_tricks :event "add_info"} south-info))
    (is (= {:value 0 :name :West_tricks :event "add_info"} west-info))
    (is (deep= {:event "discard" :value [@{:rank 2 :suit "clubs"}] :player "North"} north-discard))
    (is (= {:count 1 :to "trick" :event "prompt_play" :player "North"} north-prompt))
    (is (deep= {:phase "play" :meta @{:suit :null}} state))))