Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref: move the score calculation logic out of merge-left function #16

Merged
merged 2 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Test

on: [push]

jobs:
lint:
runs-on: ubuntu-latest

name: Test

steps:
- name: Checkout
uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22

- run: npm ci

- run: npm test
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)))
Loading