Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns morpion.graphic
- (:import (javax.swing JPanel JFrame JOptionPane)
- (java.awt.event MouseListener)
- (java.awt Color BasicStroke Dimension)
- )
- (:gen-class))
- (def squares-size 90)
- (def board-lines-size 10)
- (def cross-lines-width 7)
- (def circle-lines-width 5)
- (def circle-size 70)
- (def circle-color Color/RED)
- (def cross-color Color/BLUE)
- (def board-lines-color Color/GREEN)
- (def board-background-color Color/LIGHT_GRAY)
- (declare make-board-panel)
- (defn panel-callback
- "The callback function for the JPanel"
- [frame board was-cell-played?]
- (JOptionPane/showMessageDialog nil "Ok!")
- )
- (defn make-frame
- "Builds the application JFrame."
- []
- (let [frame (JFrame.)]
- (doto frame
- (.setTitle "Morpion game")
- (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
- (.add (make-board-panel ('morpion.core/new-board) :circle (partial panel-callback frame)) )
- (.pack)
- )
- frame
- )
- )
- (defn square-center
- "Gives the square center coordinate matching the given coord (can be either x
- or y integer value))."
- [coord-value]
- {:pre [(>= coord-value 0)]}
- (+
- (* coord-value (+ board-lines-size squares-size))
- (/ squares-size 2)
- )
- )
- (defn paint-elem
- "Paints the given element, at the given coords
- (an hashmap with :x and :y integer values
- and in the given java.awt.Graphics."
- [value coords g]
- {:pre ['morpion.core/valid-coords? coords]}
- (let [square-center-x (square-center (:x coords))
- square-center-y (square-center (:y coords))
- half-squares-size (/ squares-size 2)
- half-circle-size (/ circle-size 2)
- cross-lines-length (int (* (Math/sqrt 2) squares-size))
- old-stroke (.getStroke g)]
- (cond
- (= :cross value)
- (do
- (.setColor g cross-color)
- (.translate g square-center-x square-center-y)
- (.rotate g 0.79)
- (.setStroke g (BasicStroke. cross-lines-width BasicStroke/CAP_ROUND BasicStroke/JOIN_ROUND))
- (.drawLine g (* half-squares-size -1) 0 half-squares-size 0)
- (.drawLine g 0 (* half-squares-size -1) 0 half-squares-size )
- (.setStroke g old-stroke)
- (.rotate g -0.79)
- (.translate g 0 0)
- )
- (= :circle value)
- (do
- (.setColor g circle-color)
- (.setStroke g (BasicStroke. circle-lines-width BasicStroke/CAP_ROUND BasicStroke/JOIN_ROUND))
- (.drawOval g (- square-center-x half-circle-size) (- square-center-y half-circle-size) circle-size circle-size)
- (.setStroke g old-stroke)
- )
- )
- )
- )
- (defn paint-board-lines
- "Paints the board lines in the given java.awt.Graphics."
- [g]
- (do
- (.setColor g board-lines-color)
- (dotimes [i 2]
- (.fillRect (+ squares-size (* i (+ board-lines-size squares-size)))
- 0
- (+ squares-size (* i (+ board-lines-size squares-size)))
- (+ squares-size (* 3 (+ board-lines-size squares-size)))
- )
- (.fillRect 0
- (+ squares-size (* i (+ board-lines-size squares-size)))
- (+ squares-size (* 3 (+ board-lines-size squares-size)))
- (+ squares-size (* i (+ board-lines-size squares-size)))
- )
- )
- )
- )
- (defn paint-board-elements
- "Paints the given board elements in the given java.awt.Graphics."
- [board g]
- {:pre ('morpion.core/is-board? board)}
- (dotimes [line 3]
- (dotimes [col 3]
- (let [value ((board line) col)]
- (paint-elem value #{:x col :y line})
- )
- )
- )
- )
- (defn abs-coord-in-cell?
- "Says whether an absolute coordinate relative to the panel is
- in a cell."
- [coord]
- (< squares-size (rem coord (+ squares-size board-lines-size)))
- )
- (defn abs-coord-to-rel
- "Gets a cell coordinate from a panel coordinate :
- converts the x/y value of point in the panel to a value
- which can be 0,1,2 ."
- [coord] {:pre (abs-coord-in-cell? coord)}
- (int (/ coord (+ squares-size board-lines-size)))
- )
- (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).
- callback-fn should be a function that takes a board (vector of 3 vectors of 3 values) as
- first argument, and a was-cell-played? (as a boolean). Board will be the updated board
- and was-cell-played? says whether the cell had already a :cross or :circle."
- [board turn-piece callback-fn]
- {: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-elements 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))
- cell-to-play #{:x cell-x, :y cell-y}
- was-cell-played? ('morpion.core/cell-played? cell-to-play)]
- (callback-fn ('morpion.core/play-board board cell-to-play turn-piece) was-cell-played?)
- )
- )
- )
- (mouseEntered [e])
- (mouseExited [e])
- (mousePressed [e])
- (mouseReleased [e])
- (getPreferredSize []
- (let [panel-dim (+ (* squares-size 3) (* board-lines-size 2))]
- (Dimension. panel-dim panel-dim)
- )
- )
- )
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement