(defglobal ?*start-position* = (create$ 5 2))
(defglobal ?*winning-distance* = 13)
(deftemplate node
(slot position)
(slot g)
(slot h)
(slot f))
(deffunction distance (?x ?y)
(return (sqrt (+ (* ?x ?x) (* ?y ?y)))))
(deffunction heuristic (?x ?y)
(return (- ?*winning-distance* (distance ?x ?y))))
(deffunction generate-children (?node)
(bind ?pos (fact-slot-value ?node position))
(bind ?x (nth 1 ?pos))
(bind ?y (nth 2 ?pos))
(return (create$ (create$ (+ ?x 3) ?y)
(create$ ?x (+ ?y 3))
(create$ ?x (+ ?y 4)))))
(defrule init
(initial-fact)
=>
(assert (node (position ?*start-position*)
(g 0)
(h (heuristic (nth 1 ?*start-position*) (nth 2 ?*start-position*)))
(f (heuristic (nth 1 ?*start-position*) (nth 2 ?*start-position*))))))
(defrule expand-node
?node <- (node (position ?pos)
(g ?g)
(h ?h)
(f ?f))
=>
(bind ?children (generate-children ?node))
(foreach ?child ?children
(bind ?x (nth 1 ?child))
(bind ?y (nth 2 ?child))
(bind ?dist (distance ?x ?y))
(if (>= ?dist ?*winning-distance*)
then
(printout t "Winning position: " ?child crlf)
(halt))
(assert (node (position ?child)
(g (+ ?g 1))
(h (heuristic ?x ?y))
(f (+ (+ ?g 1) (heuristic ?x ?y))))))))
(defrule display-tree
?node <- (node (position ?pos) (g ?g) (h ?h) (f ?f))
=>
(printout t "Node: " ?pos ", g: " ?g ", h: " ?h ", f: " ?f crlf))
(reset)
(run)
; your code goes here
(exit)
; empty line at the end