I'm trying to write a program to calculate the solution in the board game Clue. I'm very new to core.logic
, so I'm starting off with a really simple version: given all the cards in my hand and in my opponents' hands, what are the three remaining cards? I've written the code below, but (do-query)
just makes the CPU max out and never returns. How should I write this? Should I take a different approach?
(def players [:green :scarlet :peacock :mustard :white :plum])
(def rooms [:study :hall :lounge :dining-room :kitchen :ballroom
:conservatory :billiard-room :library])
(def weapons [:candlestick :lead-pipe :revolver :wrench :rope :knife])
(def all-cards (concat players rooms weapons))
(defn do-query []
(let [cards (repeatedly 21 logic/lvar)
[solution remaining] (split-at 3 cards)
[my-cards remaining] (split-at 6 remaining)
[green-cards scarlet-cards] (split-at 6 remaining)]
(logic/run 1 [p r w]
(logic/== solution [p r w])
(logic/permuteo all-cards cards)
(logic/== my-cards [:rope :study :scarlet
:conservatory :mustard :wrench])
(logic/== green-cards [:green :lead-pipe :knife :dining-room
:billiard-room :library])
(logic/== scarlet-cards [:revolver :plum :hall
:lounge :kitchen :white])
(logic/membero p players)
(logic/membero r rooms)
(logic/membero w weapons))))
the permuteo is what does it
it results in a search tree with a lot of branches
come to think of it, I don't think I've ever played clue
I think I would start from a map of card names to lvars, where each lvar will have a value like :mine, :opponent, or :deck (if deck is valid in clue)
thanks, I'll try going down that route
if I have a core.logic goal that looks like this
(fresh [?1 ?2 ?3 ?4]
(membero ?1 vars)
(membero ?2 vars)
(membero ?3 vars)
(membero ?4 vars)
...)
will that expand into vars × vars × vars × vars
in memory, even if I have other goals that constrain the answer set to something much smaller?it depends what you mean by expands in memory
you will end up with a search tree that has at least that many branches, but the search tree typically is walked in a lazy fashion so the whole thing isn't realized at once