Created
December 4, 2012 22:22
-
-
Save tgoossens/4209494 to your computer and use it in GitHub Desktop.
Board game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Idea | |
------ | |
I'm redesigning last years project in java (course: OOP) | |
Long story short: | |
I have a "board" ,"robot" "item", "wall" | |
a board contains pieces at certain positions | |
a robot must be able to pickup an item and use it/ drop it again | |
a robot can move forward and backward, | |
a robot can rotate clockwise or anticlockwise | |
For now | |
------ | |
I'm experimenting how far I can go in not using any refs, atoms (or identity in general). I have still no clear opinion (2 months of clojure programming) on whether this is a good thing or not. | |
But at the moment i'm having a hard time trying to think what must happen when a robot picks up an item, then the board needs to get updated (remove the robot "value" from the board and put it on again etc) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns roborally.piece) | |
;PIECES | |
;everything is an 'piece' | |
(derive ::robot ::piece) | |
(derive ::wall ::piece) | |
(derive ::item ::piece) | |
;items | |
(derive ::battery ::item) | |
(defn create-piece [] {:type ::piece)) | |
(defn create-wall [] | |
(merge | |
(create-piece) | |
{:type ::wall})) | |
(defn energy-carrier [energy maxenergy] | |
{:energy energy | |
:maxenergy maxenergy}) | |
(defn create-battery [energy maxenergy] | |
(merge | |
(energy-carrier energy maxenergy) | |
(create-piece) | |
{ :type ::battery})) | |
(defn create-robot [energy maxenergy] | |
(merge | |
(energy-carrier energy maxenergy) | |
(create-piece) | |
:type ::robot | |
:items []})) | |
(defn create-wall [energy] | |
(merge | |
(create-piece) | |
{:type ::wall})) | |
;ENERGY | |
(defn charge [{:keys [energy] :as container} charge-fn] | |
(assoc container :energy (charge-fn energy))) | |
(defn charge-exact [value] (fn [energy] value)) | |
(defn drain [amount] | |
(fn [energy] | |
(if (> amount energy) | |
0 | |
(- energy amount)))) | |
(defn recharge [amount] | |
(fn [energy] | |
(+ energy amount))) | |
(defn transfer-energy [{:keys [energy maxenergy] :as from} {:keys [energy maxenergy] :as to}] | |
(let [amount (min (:energy from) (- (:maxenergy to) (:energy to)))] | |
[(charge from (drain amount)) (charge to (recharge amount))])) | |
;ITEMS | |
(defn change-items [{:keys [items] :as carrier} item-fn] | |
(assoc carrier :items (item-fn items))) | |
;probably more useful to represent items in a map: piece -> | |
(defn drop-item [item] | |
(fn [items] (remove #(= item %) items))) | |
(defn add-item | |
([item] (fn [items] (conj items item)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns roborally.pieceboard) | |
(defn board [width height] | |
{:pieces {[0 0] '()} | |
:height height | |
:width width }) | |
(derive ::piece ::orientable) | |
(defn addpiece [pieces piece [x y] ] | |
(assoc pieces [x y] (conj pieces piece))) | |
(defn inrange? [board [x y]] | |
(let [height (:height board) | |
width (:width board)] | |
(and (>= x 0) (>= y 0) | |
(< y height) | |
(< x width)))) | |
(defn remove-first [pred coll] | |
(let [[a b] | |
(split-with #(not (pred %)) | |
coll)] (concat a (rest b)))) | |
(defn hasposition? [board position] | |
(contains? (:pieces board) position)) | |
(defmulti place-on-board (fn [board piece [x y]] (:type piece))) | |
;checking in range should happen on higher level | |
(defmethod place-on-board ::piece | |
[board piece position] | |
(assoc board :pieces | |
(assoc (:pieces board) position (conj | |
(if (hasposition? board position) | |
((:pieces board) position) | |
'()) | |
(place piece position))))) | |
(defn remove-piece [{:keys [position] :as piece}] | |
(fn [pieces] | |
(let [pieces-at-pos (pieces position)] | |
(assoc pieces position | |
(remove-first #(= piece %) pieces-at-pos))))) | |
(defn update-pieces [board update-fn] | |
(assoc board :pieces (update-fn (:pieces board)))) | |
(defn swap-piece [board piece newpiece] | |
"Swap new value of a piece which stays at the same place" | |
(place-on-board | |
(update-pieces (:pieces board) (remove-piece piece)) | |
newpiece | |
(:position piece))) | |
;problems here | |
(defn move-on-board [board {:keys [position orientation] :as piece} move-fn] | |
(place-on-board | |
(update-pieces board (remove-piece piece)) | |
piece | |
(move-fn position orientation))) | |
;ORIENTATION | |
(defn orientation-to-vector [orientation] | |
({:north [0 -1] | |
:east [1 0] | |
:south [0 1] | |
:west [-1 0]} orientation)) | |
(defn invert-orientation [orientation] | |
({:north :south | |
:east :west | |
:south :north | |
:west :east} orientation)) | |
(defn clockwise [orientation] | |
({:north :east | |
:east :south | |
:south :west | |
:west :north} orientation)) | |
(defn anticlockwise [orientation] | |
(invert-orientation (clockwise orientation))) | |
(defn turn [{:keys [orientation] :as piece} rotate-fn ] | |
(assoc piece :orientation (rotate-fn orientation))) | |
;POSITION | |
(defn place [{:keys [position] :as piece} position] | |
(assoc piece :position position)) | |
(defn forward [position orientation] | |
(vec (map + position (orientation-to-vector orientation)))) | |
(defn backward [position orientation] | |
(vec (map - position (orientation-to-vector orientation)))) | |
(defn move [{:keys [position orientation] :as piece} move-fn] | |
(assoc piece :position (move-fn position orientation))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment