Skip to content

Commit

Permalink
ref: move the score calculation logic out of merge-left function
Browse files Browse the repository at this point in the history
we can calculate score by summing the merged tiles which are marked as :merged
  • Loading branch information
WarFox committed Jan 1, 2025
1 parent b37ea92 commit ef3a522
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 80 deletions.
11 changes: 3 additions & 8 deletions src/cljs_2048/board.cljs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
(ns cljs-2048.board
(:require
[cljs-2048.game-events :as game-events]
[re-frame.core :as re-frame]))
(ns cljs-2048.board)

(def rows-count 4)
(def columns-count 4)
Expand Down Expand Up @@ -86,13 +83,12 @@
(nil? prev)
[acc current]

;; If equal, merge and add to accumulator, set nil as previous
;; If equal, merge and append to accumulator, set nil as previous
(= prev current)
(let [sum (+ prev current)]
(re-frame/dispatch [::game-events/add-score sum])
[(conj acc [sum :merged]) nil])

;; If not equal, add previous to accumulator and current element as previous
;; If not equal, append previous to accumulator and current element as previous
:else
[(conj acc [prev]) current]))

Expand All @@ -118,4 +114,3 @@
(every? true? (map =
(remove keyword? (flatten board1))
(remove keyword? (flatten board2)))))

49 changes: 47 additions & 2 deletions src/cljs_2048/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
[cljs-2048.board :as b]
[cljs-2048.db :as db]
[cljs-2048.game :as g]
[cljs-2048.game-events :as game-events]
[cljs-2048.local-storage :as ls]
[day8.re-frame.tracing :refer-macros [fn-traced]]
[re-frame.core :as re-frame]))

;; DB events

(re-frame/reg-event-db
::initialize-db
(fn-traced
Expand All @@ -22,11 +24,54 @@

(re-frame/reg-event-db ::start-game start-game)

(defn clear-tile-moves
[db [_ _]]
(assoc db
:tile-moves {}))

(re-frame/reg-event-db ::clear-tile-moves clear-tile-moves)

(defn gameover
[db [_]]
(assoc db :gameover true))

(re-frame/reg-event-db ::gameover gameover)

(defn clear-score-changes
[db _]
(assoc db
:score-changed false
:high-score-changed false))

(re-frame/reg-event-db ::clear-score-changes clear-score-changes)

;; FX events

(defn add-score
[{:keys [db]} [_ new-score]]
(let [score (+ new-score (:score db))
high-score (max score (:high-score db))]
(ls/set-high-score! high-score) ;; set high-score in local-storage
{:db (assoc db
:score score
:high-score high-score
:score-changed true
:high-score-changed (> high-score (:high-score db)))
:fx [[:dispatch-later {:ms 300 :dispatch [::clear-score-changes]}]]}))

(re-frame/reg-event-fx ::add-score add-score)

(defn move
[{:keys [db]} [_ direction]]
(let [new-board (g/move (:board db) direction)]
{:db (assoc db
:board new-board)
:fx [(when (g/gameover? new-board) [:dispatch [::game-events/gameover]])]}))
:fx (if (g/gameover? new-board)
[[:dispatch [::gameover]]]

[[:dispatch-later {:ms 300 :dispatch [::clear-tile-moves]}]
(let [score (g/move-score new-board)]
(when (pos? score)
[:dispatch [::add-score score]]))])}))

(re-frame/reg-event-fx ::move move)
12 changes: 11 additions & 1 deletion src/cljs_2048/game.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,20 @@
::up move-up
::down move-down})

(defn move-score
"Returns score after moving. Score is sum of :merged tiles"
[board]
(->> board
(mapcat (fn [row]
(filter (fn [tile]
(= :merged (second tile))) row)))
(map first)
(reduce + 0)))

(defn move
"Returns new board after moving in the direction. Adds random tile if board has changed"
[board direction]
(let [new-board ((direction movements) board)]
(let [new-board ((get movements direction) board)]
(if (b/equal? new-board board)
new-board
(b/random-tile new-board))))
37 changes: 0 additions & 37 deletions src/cljs_2048/game_events.cljs

This file was deleted.

2 changes: 1 addition & 1 deletion src/cljs_2048/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
[:div {:class (str "transition-transform duration-300 ease-in-out tile-position-" row-index "-" col-index) ;; TODO apply tile-position based on new position
:role "gridcell"
:aria-label (str "Tile " value)
:tabindex "0"}
:tabIndex "0"}
[:div {:class (str "text-5xl font-bold size-32 flex justify-center items-center rounded-md tile-" value
(cond
(= state :merged)
Expand Down
62 changes: 31 additions & 31 deletions test/cljs_2048/board_test.cljs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
(ns cljs-2048.board-test
(:require
[cljs-2048.board :as sut]
[cljs-2048.board :as board]
[cljs.test :refer-macros [deftest testing is]]))

(deftest initial-board-test
(testing "Inital board must be a 4x4 matrix filled with zeroes"
(is (= sut/initial-board
(is (= board/initial-board
[[[0] [0] [0] [0]]
[[0] [0] [0] [0]]
[[0] [0] [0] [0]]
[[0] [0] [0] [0]]]))))

(deftest set-tile
(let [board sut/initial-board]
(let [board board/initial-board]
(testing "Set value at given x and y"
(is (= (sut/set-tile board 1 2 4 :state)
(is (= (board/set-tile board 1 2 4 :state)
[[[0] [0] [0] [0]]
[[0] [0] [4 :state] [0]]
[[0] [0] [0] [0]]
[[0] [0] [0] [0]]])))))

(deftest get-tile
(let [board (sut/set-tile sut/initial-board 1 3 8 :state)]
(let [board (board/set-tile board/initial-board 1 3 8 :state)]
(testing "Get tile value of given x and y"
(is (= (sut/get-tile board 1 3) [8 :state])))))
(is (= (board/get-tile board 1 3) [8 :state])))))

(deftest empty-tiles
(is (empty? (sut/empty-tiles [[[1] [2] [3] [4]]
(is (empty? (board/empty-tiles [[[1] [2] [3] [4]]
[[5] [6] [7] [6]]
[[9] [7] [11] [12]]
[[13] [8] [15] [16]]])))

(is (= (sut/empty-tiles [[[1] [2] [3] [0]]
(is (= (board/empty-tiles [[[1] [2] [3] [0]]
[[0] [6] [7] [0]]
[[9] [0] [11] [12]]
[[13] [0] [15] [16]]])
Expand All @@ -43,7 +43,7 @@
[[5] [6] [7] [8]]
[[5] [6] [7] [8]]
[[5] [6] [7] [8]]]]
(is (= (sut/random-tile board)
(is (= (board/random-tile board)
board)))))

;; Transpose Test
Expand All @@ -55,21 +55,21 @@

(deftest transpose-test
(testing "flips the matrix diagonally so as row and column indices are switched"
(is (= (sut/transpose test-board)
(is (= (board/transpose test-board)
[[1 5 9 13]
[2 6 10 14]
[3 7 11 15]
[4 8 12 16]]))))

(deftest rotate-left-test
(is (= (sut/rotate-left test-board)
(is (= (board/rotate-left test-board)
[[4 8 12 16]
[3 7 11 15]
[2 6 10 14]
[1 5 9 13]])))

(deftest rotate-right-test
(is (= (sut/rotate-right test-board)
(is (= (board/rotate-right test-board)
[[13 9 5 1]
[14 10 6 2]
[15 11 7 3]
Expand All @@ -79,55 +79,55 @@

(deftest fill-zeroes-test
(testing "fills empty vector with n zeroes"
(is (= (sut/fill-zeroes [] 10)
(is (= (board/fill-zeroes [] 10)
[[0] [0] [0] [0] [0] [0] [0] [0] [0] [0]])))

(testing "fills non-empty vector with no zeroes"
(is (= (sut/fill-zeroes [[2] [4]] 7)
(is (= (board/fill-zeroes [[2] [4]] 7)
[[2] [4] [0] [0] [0] [0] [0]])))

(testing "if vector size is = n, return the vector"
(is (= (sut/fill-zeroes [[2] [4]] 2)
(is (= (board/fill-zeroes [[2] [4]] 2)
[[2] [4]])))

(testing "if vector size is > n, return the vector"
(is (= (sut/fill-zeroes [1 2 3 4] 2)
(is (= (board/fill-zeroes [1 2 3 4] 2)
[1 2 3 4]))))

(deftest merge-left-test
(is (= (sut/merge-left [[2] [2] [0] [0]])
(is (= (board/merge-left [[2] [2] [0] [0]])
[[4 :merged] [0] [0] [0]]))

(is (= (sut/merge-left [[4] [4] [2] [2]])
(is (= (board/merge-left [[4] [4] [2] [2]])
[[8 :merged] [4 :merged] [0] [0]]))

(is (= (sut/merge-left [[1] [2] [3] [4]])
(is (= (board/merge-left [[1] [2] [3] [4]])
[[1] [2] [3] [4]]))

(is (= (sut/merge-left [[4] [4] [4] [4]])
(is (= (board/merge-left [[4] [4] [4] [4]])
[[8 :merged] [8 :merged] [0] [0]]))

(is (= (sut/merge-left [[2] [0] [4] [4]])
(is (= (board/merge-left [[2] [0] [4] [4]])
[[2] [8 :merged] [0] [0]]))

(is (= (sut/merge-left [[0] [0] [4] [4]])
(is (= (board/merge-left [[0] [0] [4] [4]])
[[8 :merged] [0] [0] [0]]))

(is (= (sut/merge-left [[4] [4] [0] [4]])
(is (= (board/merge-left [[4] [4] [0] [4]])
[[8 :merged] [4] [0] [0]]))

(is (= (sut/merge-left [[4] [4] [8] [4]])
(is (= (board/merge-left [[4] [4] [8] [4]])
[[8 :merged] [8] [4] [0]]))

(is (= (sut/merge-left [[4] [2] [2] [0]])
(is (= (board/merge-left [[4] [2] [2] [0]])
[[4] [4 :merged] [0] [0]]))

(testing "with random and merged"
(is (= (sut/merge-left [[4] [2 :random] [2 :merged] [0]])
(is (= (board/merge-left [[4] [2 :random] [2 :merged] [0]])
[[4] [4 :merged] [0] [0]])))

(testing "map merge-left for a matrix"
(is (= (map sut/merge-left
(is (= (map board/merge-left
[[[4] [4] [2] [2]]
[[6] [4] [2] [2]]
[[8] [8] [2] [0]]
Expand All @@ -138,14 +138,14 @@
[[6] [8] [4 :merged] [0]]]))))

(deftest reverse-test
(is (= (sut/reverse-board test-board)
(is (= (board/reverse-board test-board)
[[4 3 2 1]
[8 7 6 5]
[12 11 10 9]
[16 15 14 13]])))

(deftest equal?-test
(is (true? (sut/equal?
(is (true? (board/equal?
[[[0] [0] [0] [0]]
[[0] [0] [0] [0]]
[[0] [0] [2 :random] [0]]
Expand All @@ -156,7 +156,7 @@
[[0] [0] [2] [0]]
[[4] [0] [4] [0]]])))

(is (true? (sut/equal?
(is (true? (board/equal?
[[[0] [0] [0] [0]]
[[0] [0] [0] [0]]
[[0] [0] [2 :random] [0]]
Expand All @@ -167,7 +167,7 @@
[[0] [0] [2] [0]]
[[4] [0] [4] [0]]])))

(is (false? (sut/equal?
(is (false? (board/equal?
[[[0] [0] [0] [0]]
[[0] [0] [0] [0]]
[[0] [0] [2 :random] [0]]
Expand Down
12 changes: 12 additions & 0 deletions test/cljs_2048/game_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,15 @@
(testing "random tile is added"
(is (= (sut/move board ::sut/up)
::random-tile-added)))))))

(deftest move-score-test
(is (= (sut/move-score [[[16 :merged] [0] [0] [0]]
[[2] [0] [0] [0]]
[[4 :merged] [0] [0] [0]]
[[4 :merged] [0] [0] [0]]]) 24))
(is (= (sut/move-score test-board-2) 0))

(is (= (sut/move-score [[[2] [4] [2] [2]]
[[4] [32] [8] [4]]
[[4] [4] [2] [8]]
[[4] [4] [16] [2]]]) 0)))

0 comments on commit ef3a522

Please sign in to comment.