clara

http://www.clara-rules.org/
oskarkv 2020-05-02T22:11:37.053500Z

I'm new to Clara Rules. I have been trying to write a rule for a board game, but I haven't been able to do it. The rule in English is: During a player's turn, at the stage of the turn called :into-city, the player will move into the city if either there are no other players in the city, or if there is just one player in the city and the total number of players is more than four. I have these fact types:

(defrecord Player [id name health score energy])
(defrecord Turn [id stage])
(defrecord InCity [id])
InCity just means that a player is in the city. Turn keeps track of whose turn it is and at what stage the player is in his turn. Player just represents a player. I tried this:
(cr/defrule into-city
  [?turn <- Turn (= ?id id) (= :into-city stage)]
  [?players <- (acc/count) :from [Player]]
  [?in-city <- (acc/count) :from [InCity]]
  ;; (or (zero? ?in-city
  ;;            (and (= 1 ?in-city)
  ;;                 (> ?players 4))))
  =>
  (cr/retract! ?turn)
  (cr/insert! (->Turn ?id (next-stage :into-city)))
  (cr/insert! (->InCity ?id)))
But of course that part of the condition with "if either there are no other players in the city, or if there is just one player in the city and the total number of players is more than 4" is missing. I have commented out an expression that I tried to put in there somehow. But I'm not sure where to put that. As far as I have seen, conditions apply to individual facts, and I'm not sure if I can put in another condition line with just boolean logic. Can I? Also, since, as you can see, I'm retracting the Turn fact that led to the new facts being inserted, because now the stage of the turn is the next stage, and so the inserted facts will be instantly retracted, right? So how should I think about it? I'm finding it harder than I anticipated to write a program with rules.