(defn make-board-panel
[board turn-piece output-fn]
(proxy [JPanel MouseListener] []
;; ...
(mouseClicked [e]
(when (and (abs-coord-in-cell? (.getX e))
(abs-coord-in-cell? (.getY e)))
(let [cell-x (abs-coord-to-rel (.getX e))
cell-y (abs-coord-to-rel (.getY e))]
;; Here I compute the new board value
(output-fn new-board-value))))
;; ...
))
Trying to build a tic tac toe without any state (in pure fp style)
-
26-06-2022 - |
Question
I am learning Clojure and trying to implement a simple tic-tac-toe (or morpion). But i am working hard in order to avoid any ref/atom/agent ...
I know I could do it easily in a console application, as it would not be event-driven, so that I would exactly know when to pass in a new board value. I mean
- my board would be a vector of vectors ([[:circle 0 :cross][:any :circle :empty][:cross :none :none]] where only :circle and :cross values matter)
- I would have a simple text-based method which takes a board and return a string
But, whenever I want to implement a graphical Panel, I wonder how can I do the same thing. For example :
I am creating an instance of javax.swing.JPanel (please don't care about the other methods that are used here) :
(defn make-board-panel "Builds the board JPanel, whose state is given by board argument, and turn-piece argument (must be either :circle or :cross, I mean the next value to set in the board)." [board turn-piece] {:pre ['morpion.core/is-board? board, 'morpion.core/is-a-player-piece? turn-piece]} (proxy [JPanel MouseListener] [] (paintComponent [g] (proxy-super paintComponent g) (paint-board-lines g) (paint-board board g) ) (mouseClicked [e] (if (and (abs-coord-in-cell? (.getX e)) (abs-coord-in-cell? (.getY e))) (let [cell-x (abs-coord-to-rel (.getX e)) cell-y (abs-coord-to-rel (.getY e))] ;; Here I compute the new board value ) nil ;; Here I wish I could return the new board value to the caller of make-board-panel, but this seems impossible ! ) ) (mouseEntered [e]) (mouseExited [e]) (mousePressed [e]) (mouseReleased [e]) ) )
- But it seems that there are no way for me to fetch the new value of the board, from the mouseClicked event of the Panel : unless I introduce a state variable.
So is there a workaround :
Sources for my complete project :
(I've tried to improve thanks to Igrapenthin comment, but I am still failing.)
Solution
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow