He escrito un programa de pelotas de rebote multiproceso en clojure. Después de iniciar el hilo de la animación, hago-programa de bolas de rebote multiproceso usando agentes en Clojure
(send-balls)
para comenzar los hilos de las pelotas de rebote. Las bolas no se mueven y esto se muestra en la consola:
(#<[email protected] FAILED: #<[email protected]: {:x 759, :y 629, :x-speed 3, :y-speed 1}>> #<[email protected] FAILED: #<[email protected]: {:x 794, :y 258, :x-speed 2, :y-speed 3}>> #<[email protected] FAILED: #<[email protected]: {:x 831, :y 251, :x-speed 4, :y-speed 2}>>)
¿Alguien puede indicar qué está pasando aquí?
(import
'(java.awt Color Graphics Dimension)
'(java.awt.image BufferedImage)
'(javax.swing JPanel JFrame))
(def width 1000)
(def height 1000)
(def number-of-balls 3)
(def rad 20)
(def origin-x 100)
(def origin-y 100)
(def box-height 500)
(def box-width 700)
(def max-x (+ origin-x box-width (* 4 rad)))
(def max-y (+ origin-y box-height (* 4 rad)))
(def min-x origin-x)
(def min-y origin-y)
(defn init-x
[]
(+ (rand-int (- max-x min-x)) min-x))
(defn init-y
[]
(+ (rand-int (- max-y min-y)) min-y))
(defstruct ball :x :y :x-speed :y-speed)
(def balls
(apply vector (map (fn [_] (ref (struct ball (init-x) (init-y)
(rand-int 10) (rand-int 10))))
(range number-of-balls))))
(def ball-agents (apply vector (map agent balls)))
(defn get-ball
[n]
(balls n))
(defn set-new-x
[ball]
(let [x (@ball :x)
x-speed (@ball :x-speed)
new-x (+ x x-speed)]
(dosync
(if (and (>= new-x min-x) (<= new-x max-x))
(ref-set ball (assoc @ball :x new-x))
(ref-set ball (assoc @ball :x-speed (* -1 x-speed)))))
(println "the new x is " @(ball :x)))
@ball)
(defn set-new-y
[ball]
(let [y (@ball :y)
y-speed (@ball :y-speed)
new-y (+ y y-speed)]
(dosync
(if (and (>= new-y min-y) (<= new-y max-y))
(ref-set ball (assoc @ball :y new-y))
(ref-set ball (assoc @ball :y-speed (* -1 y-speed))))))
@ball)
(defn paint-balls
[bg x y]
(doto bg
(.setColor (. Color red))
(.fillOval x y rad rad)))
(defn render
[g]
(let [img (new BufferedImage width height
(. BufferedImage TYPE_INT_ARGB))
bg (. img (getGraphics))]
(doto bg
(.setColor (. Color white))
(.fillRect 0 0 (. img (getWidth)) (. img (getHeight)))
(.setColor (. Color red))
(.drawRect origin-x origin-y (+ origin-x box-width) (+ origin-y box-height)))
(dorun
(for [i (range number-of-balls)]
(do
(paint-balls bg (@(get-ball i) :x) (@(get-ball i) :y)))))
(. g (drawImage img 0 0 nil))
(. bg (dispose))))
(def panel (doto (proxy [JPanel] []
(paint [g] (render g)))
(.setPreferredSize (new Dimension
width
height))))
(def frame (doto (new JFrame) (.add panel) .pack .show))
(def animator (agent nil))
(defn bounce
[x]
(while true
(set-new-x @*agent*)
(set-new-y @*agent*)
(. Thread (sleep 100))
(println "here in bounce " *agent*)))
(defn animation
[x]
(send-off *agent* animation)
(. panel (repaint))
(. Thread (sleep 100)))
(defn send-balls
[]
(doall
(for [i (range number-of-balls)]
(do
(send-off (ball-agents i) bounce)))))
(send-off animator animation)
Parece que su actualización de agente está fallando, probablemente debido a una excepción dentro de la función de rebote. Sospecho que un problema es que está haciendo demasiadas dereferencias, es decir, "@ * agente *" debería ser realmente "\ * agente \ *". – mikera
@mikera - Lo intenté, pero eso no es ... – Pranav