Commit 863a7bc3 authored by Davide Taviani's avatar Davide Taviani

complete rework of the modeling behind boards, now employing the idea of column-links and row-links

parent 53091f10
......@@ -7,7 +7,7 @@
margin-bottom: -7px;
.cell {
display: inline;
display: inline-block;
margin-right: -1px;
.create-board {
......@@ -50,9 +50,10 @@ align-items:center;
justify-content: center;
.fill-block {
.link-block {
display: inline-block;
width: 20px;
height: 20px;
background-color: black;
\ No newline at end of file
width: 50px;
height: 50px;
border: 1px solid #DDD;
.fill {background-color: black;}
\ No newline at end of file
row_links TEXT NOT NULL,
column_links TEXT NOT NULL
\ No newline at end of file
......@@ -6,27 +6,35 @@
(def db {:connection-uri (or (env :db-url) "jdbc:postgresql://localhost:5432/harmony")})
(defn level->record [{:keys [id size pattern] :as l}]
(defn level->record [{:keys [id size column-links row-links] :as l}]
{:id id
:size size
:pattern (prn-str pattern)})
:row_links (prn-str row-links)
:column_links (prn-str column-links)
(defn record->level [{:keys [id size pattern] :as r}]
(defn record->level [{:keys [id size row_links column_links] :as r}]
{:id id
:size size
:pattern (edn/read-string pattern)})
:row-links (edn/read-string row_links)
:column-links (edn/read-string column_links)})
(defn create! [level]
(let [record (level->record level)]
(prn [:r record])
(j/insert! db :levels record)))
(defn update! [level]
(let [record (level->record level)]
(j/update! db :levels record ["id = ?" (:id level)])))
(defn delete! [level]
(j/delete! db :levels ["id = ?" (:id level)]))
(defn query-level [id]
(when-let [record (first (j/query db ["SELECT * from levels where id = ?" id]))]
(record->level record)))
(defn list-levels []
(map record->level (j/query db "SELECT * from levels order by size;")))
\ No newline at end of file
(map record->level (j/query db "SELECT * from levels order by size;")))
......@@ -3,6 +3,7 @@
[compojure.route :as route]
[compojure.core :refer [defroutes GET PUT POST]]
[ :refer [html5 include-css include-js]]
[hiccup.form :as form]
[ring.middleware.transit :as transit]
[ring.adapter.jetty :as jetty]
[harmony.db :as db]
......@@ -23,29 +24,35 @@
[:th "Actions"]]]
(for [level levels]
[:td (str (:size level))]
[:td (str (:pattern level))]
[:td [:a {:class "button"
:href (str "/play/" (:id level))}
[:td (str (:size level))]
[:td (str (:pattern level))]
[:a {:class "button"
:href (str "/play/" (:id level))}
(form/form-to [:post (str "/delete/" (:id level))]
[:input {:class "button is-danger" :type :submit :value "Delete"}])]])]])))
(defroutes routes
(GET "/" req (list-page))
(GET "/play/:level-id" {{:keys [level-id]} :params}
(html-utils/spa-page (db/query-level (UUID/fromString level-id)) "harmony.core.render_play();"))
(GET "/new" [] (html-utils/spa-page {} "harmony.core.render_new();"))
#_(POST "/delete/:level-id" {{:keys [level-id]} :params}
(let [level (db/query-level (UUID/fromString level-id))]
(when level
(when (db/delete! level)
{:status 200
:body {:saved? true}})))
(POST "/delete/:level-id" {{:keys [level-id]} :params}
(if-let [level (db/query-level (UUID/fromString level-id))]
(let [result (db/delete! level)]
(response/redirect "/"))
(prn "No level: " level-id)))
(POST "/create-level" {:keys [body]}
(when (db/create! (assoc body :id (UUID/randomUUID)))
{:status 200
:body {:saved? true}}))
(GET "/load-stuff" [] {:status 200
:body {:something "here"}})
(route/resources "/")
(ns harmony.board)
(def board-pattern
{:size 1
:pattern [1]})
{:size 2
:pattern [1 1
0 1]})
(defn tile [n-set value]
......@@ -30,12 +31,11 @@
east? (and (= (quot index size)
(quot (+ index 1) size))
(= 1 (get pattern (+ index 1))))]
(->> [(when north? :N)
(when west? :W)
(when east? :E)
(when south? :S)]
(remove nil?)
(into #{}))))
(cond-> #{}
north? (conj :N)
west? (conj :W)
east? (conj :E)
south? (conj :S))))
(defn board->neighbor [b]
(map-indexed (fn [index p]
......@@ -44,12 +44,12 @@
(:pattern b)))
(defn create-board [{:keys [size] :as bp}]
(defn create-board [{:keys [size pattern] :as bp}]
(let [neighbors (board->neighbor bp)
tiles (map tile neighbors (:pattern bp))]
tiles (map tile neighbors pattern)]
{:size size
:cells (mapv create-cell
(:pattern bp)
......@@ -105,3 +105,41 @@
:row-links [1 0]
:column-links [0 1]})
(defn connected-neighbors [{:keys [size row-links column-links]} index]
(let [i (quot index size)
j (rem index size)
north? (and (not= i 0)
(= 1 (get column-links (+ j (* (dec i) size)))))
south? (and (not= i (dec size))
(= 1 (get column-links index)))
west? (and (not= j 0)
(= 1 (get row-links (+ (dec j) (* i (dec size))))))
east? (and (not= j (dec size))
(= 1 (get row-links (+ j (* i (dec size))))))]
(cond-> #{}
north? (conj :N)
south? (conj :S)
west? (conj :W)
east? (conj :E)
(defn create-board2 [bl]
{:size (:size bl)
:cells (->> (range (Math/pow (:size bl) 2))
(map (partial connected-neighbors bl))
(mapv (fn [n-set]
(let [value (if (empty? n-set) 0 1)
tile (tile n-set value)]
{:value value
:neighbors n-set
:tile tile
:status (rand-int 4)}))))}
(def end
{:size 2
:cells [{:value 1 :neighbors #{:E} :tile :1-tile :status 0}
{:value 1 :neighbors #{:W :S} :tile :2-tile-L :status 0}
{:value 0 :neighbors #{} :tile :0-tile :status 0}
{:value 1 :neighbors #{:N} :tile :1-tile :status 0}]})
\ No newline at end of file
......@@ -6,8 +6,11 @@
[ajax.core :as ajax]))
(defonce app-state (r/atom {:size 2
:column-links [0 1]
:row-links [0 0]
:pattern [1 1 1 1]}))
(defonce main-topic (f/topic (f/log)))
(defmulti handle-command
......@@ -41,12 +44,12 @@
(defmethod handle-command :change-size
[state [_cmd value]]
{:size value
:pattern (into [] (repeat (Math/pow value 2) 1))})
:column-links (into [] (repeat (* value (dec value)) 1))
:row-links (into [] (repeat (* value (dec value)) 1))})
(defn pattern-component []
(let [board (->> @app-state b/create-board b/solve)
(defn level-creator []
(let [board (->> @app-state b/create-board2 b/solve)
{:keys [size cells]} board]
[:div {:class "board create-board"}
......@@ -63,13 +66,55 @@
[:img {:key (str i j)
:class (str "cell rotate-" (get-in cells [index :status]))
:src (str "/tiles/" tile-name ".svg")
:width (str (Math/floor (/ 100 size)) "%")
:height (str (Math/floor (/ 100 size)) "%")
:width "100px;" #_(str (Math/floor (/ 100 size)) "%")
:height "100px;" #_(str (Math/floor (/ 100 size)) "%")
:on-click #(f/send! main-topic [:toggle-cell index])}]))
(partition size cells)))]])
(partition size cells)))]]))
(defn row-link-board []
(let [{:keys [size row-links]} @app-state]
[:div {:class "board create-board"}
(for [i (range size)]
[:div {:class "row"
:key i}
(for [j (range (dec size))]
(let [index (+ (* i (dec size)) j)]
[:div {:key (str "row-" i j)
:on-click #(f/send! main-topic [:toggle-row-link index])
:class (str "link-block"
(when (= 1 (get row-links index))
" fill"))}]))
(defn column-link-board []
(let [{:keys [size column-links]} @app-state]
[:div {:class "board create-board"}
(for [i (range (dec size))]
[:div {:key i
:class "row"}
(for [j (range size)]
(let [index (+ (* i size) j)]
[:div {:key (str "col-" i j)
:on-click #(f/send! main-topic [:toggle-column-link index])
:class (str "link-block"
(when (= 1 (get column-links index))
" fill"))}]))
(defmethod handle-command :toggle-column-link
[state [_cmd index]]
(update-in state [:column-links index] (comp #(mod % 2) inc)))
(defmethod handle-command :toggle-row-link
[state [_cmd index]]
(update-in state [:row-links index] (comp #(mod % 2) inc)))
(defmethod handle-command :toggle-cell
[state [_cmd index]]
(update-in state [:pattern index]
......@@ -77,11 +122,17 @@
(defmethod handle-command :clear-board
[state [_cmd]]
(update-in state [:pattern] (partial mapv (constantly 0))))
(-> state
(update-in [:row-links] (partial mapv (constantly 0)))
(update-in [:column-links] (partial mapv (constantly 0))))
(defmethod handle-command :fill-board
[state [_cmd]]
(update-in state [:pattern] (partial mapv (constantly 1))))
(-> state
(update-in [:row-links] (partial mapv (constantly 1)))
(update-in [:column-links] (partial mapv (constantly 1))))
(defn init-handler []
(f/subscribe! main-topic
......@@ -104,4 +155,10 @@
:on-click #(f/send! main-topic [:clear-board])} "Clear"]
[:button {:class "button btn-create is-info"
:on-click #(f/send! main-topic [:fill-board])} "Fill"]]]
[:div {:class "columns"}
[:div {:class "column is-one-quarter"}
[:div {:class "column is-one-quarter"}
......@@ -37,8 +37,7 @@
[:div {:class "column is-half is-offset-one-quarter"}
[:div {:class "board-controls"}
[:button {:class "button is-primary"
:on-click #(f/send! main-topic [:reset-game])} "Reset"]]]]])
:on-click #(f/send! main-topic [:reset-game])} "Reset"]]]]]))
(defmethod handle-command :rotate-tile
......@@ -66,7 +65,7 @@
(defmethod handle-command :init-game
[state [_cmd data]]
(->> data
(defn notification []
(if (and @game-state
......@@ -82,11 +81,9 @@
[:iframe {:width "300px"
:height "300px"
#_[:iframe {:width "1px"
:height "1px"
:scrolling "no"
:frameBorder "no"
:src "
:src ""}]]))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment