File tree Expand file tree Collapse file tree 7 files changed +271
-0
lines changed Expand file tree Collapse file tree 7 files changed +271
-0
lines changed Original file line number Diff line number Diff line change 1+ name : Go
2+
3+ on :
4+ push :
5+ branches :
6+ - master
7+ pull_request :
8+ branches :
9+ - master
10+ jobs :
11+ build_and_test :
12+ runs-on : ubuntu-latest
13+ steps :
14+ - name : Checkout
15+ uses : actions/checkout@v4
16+ - name : Setup Go
17+ uses : actions/setup-go@v5
18+ with :
19+ go-version : ' stable'
20+ check-latest : true
21+ - name : Setup dependency
22+ run : go mod tidy
23+ - name : Test
24+ run : go test -v ./...
Original file line number Diff line number Diff line change 1+ # If you prefer the allow list template instead of the deny list, see community template:
2+ # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3+ #
4+ # Binaries for programs and plugins
5+ * .exe
6+ * .exe~
7+ * .dll
8+ * .so
9+ * .dylib
10+
11+ # Test binary, built with `go test -c`
12+ * .test
13+
14+ # Code coverage profiles and other test artifacts
15+ * .out
16+ coverage. *
17+ * .coverprofile
18+ profile.cov
19+
20+ # Dependency directories (remove the comment below to include it)
21+ # vendor/
22+
23+ # Go workspace file
24+ go.work
25+ go.work.sum
26+
27+ # env file
28+ .env
29+
30+ # Editor/IDE
31+ # .idea/
32+ # .vscode/
Original file line number Diff line number Diff line change 1+ # 2048-game
2+
3+ 這個 repository 主要用來 demo 使用 golang 來實做 2048 遊戲的功能
4+
5+ 目標會採用 ebiten 來作畫面展現的遊戲引擎
6+
7+ 預期會先從核心功能開始寫,最後再加上 ebiten 來作畫面渲染
8+
9+ ## 2048 遊戲介紹
10+
11+ 2048 是一款單人益智遊戲,玩家透過滑動方格中的數字進行合併,
12+ 最終目標是在盤面上生成一個 數字 2048 的方塊。
13+ 遊戲盤面為 4x4,每格可以放置一個數字(通常是 2 的冪次)。
14+
15+ ## 遊戲規則說明
16+
17+ 遊戲基本迴圈如下:
18+
19+ 1 . 初始化:隨機在兩個位置生成 2 或 4。
20+ 2 . 玩家滑動(上下左右四個方向)。
21+ 3 . 壓縮數字:將所有數字往滑動方向靠攏。
22+ 4 . 合併數字:相鄰且數值相同的數字會合併,數值加倍。
23+ 5 . 再壓縮:合併後的空格再次填補。
24+ 6 . 新增數字:在隨機空格生成 2 或 4。
25+ 7 . 檢查終止條件(勝利 / 失敗)。
26+ 8 . 重複步驟 2~ 7。
27+
28+ ## 滑動與合併規則
29+
30+ 這是 2048 最重要的邏輯,先用向左滑為例:
31+
32+
33+ | 操作前| 壓縮非零數字| 合併相同數字| 再壓縮|
34+ | :-:| :-:| :-:| :-:|
35+ | 2 0 2 4| 2 2 4 0| 4 0 4 0| 4 4 0 0|
36+ | 4 4 4 4| 4 4 4 4| 8 0 8 0| 8 8 0 0|
37+
38+ * 壓縮(Compress):將所有非零數字往滑動方向移動。
39+ * 合併(Merge):相鄰且相同的數字合併成一個,數值翻倍。
40+ * 再次壓縮:把合併後出現的空格補齊。
41+
42+ ## 終止條件
43+
44+ 遊戲會在以下情況結束:
45+
46+ * 勝利條件
47+
48+ 盤面上出現數字 2048(或玩家自訂目標,例如 4096)。
49+
50+ * 失敗條件
51+
52+ 盤面已無空格,且 四個方向都無法再合併。
Original file line number Diff line number Diff line change 1+ module github.com/leetcode-golang-classroom/2048-game
2+
3+ go 1.24.0
4+
5+ require github.com/stretchr/testify v1.10.0
6+
7+ require (
8+ github.com/davecgh/go-spew v1.1.1 // indirect
9+ github.com/pmezard/go-difflib v1.0.0 // indirect
10+ gopkg.in/yaml.v3 v3.0.1 // indirect
11+ )
Original file line number Diff line number Diff line change 1+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c =
2+ github.com/davecgh/go-spew v1.1.1 /go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38 =
3+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM =
4+ github.com/pmezard/go-difflib v1.0.0 /go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4 =
5+ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA =
6+ github.com/stretchr/testify v1.10.0 /go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY =
7+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM =
8+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 /go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0 =
9+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA =
10+ gopkg.in/yaml.v3 v3.0.1 /go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM =
Original file line number Diff line number Diff line change 1+ package internal
2+
3+ // sideSize - 預設 sideSize
4+ const sideSize = 4
5+
6+ // Game - 紀錄當下遊戲處理狀態
7+ //
8+ // board [][]int - 紀錄盤面狀態
9+ type Game struct {
10+ board [][]int
11+ }
12+
13+ // Init - 初始化
14+ func (g * Game ) Init (data [][]int ) {
15+ // 建立棋盤
16+ g .board = make ([][]int , sideSize )
17+ for index := range g .board {
18+ g .board [index ] = make ([]int , sideSize )
19+ }
20+ // checkout input value
21+ if len (data ) != sideSize || len (data [0 ]) != sideSize {
22+ return
23+ }
24+ // setup data
25+ for r := range sideSize {
26+ for c := range sideSize {
27+ if data [r ][c ] != 0 {
28+ g.board [r ][c ] = data [r ][c ]
29+ }
30+ }
31+ }
32+ }
33+
34+ func NewGame () * Game {
35+ return & Game {}
36+ }
Original file line number Diff line number Diff line change 1+ package internal
2+
3+ import (
4+ "testing"
5+
6+ "github.com/stretchr/testify/assert"
7+ )
8+
9+ func TestGameInit (t * testing.T ) {
10+ type field struct {
11+ board [][]int
12+ }
13+ tests := []struct {
14+ name string
15+ input field
16+ want [][]int
17+ }{
18+ {
19+ name : "Empty Input" ,
20+ input : field {
21+ board : nil ,
22+ },
23+ want : [][]int {
24+ {0 , 0 , 0 , 0 },
25+ {0 , 0 , 0 , 0 },
26+ {0 , 0 , 0 , 0 },
27+ {0 , 0 , 0 , 0 },
28+ },
29+ },
30+ {
31+ name : "Case1" ,
32+ input : field {
33+ board : [][]int {
34+ {2 , 4 , 0 , 0 },
35+ {8 , 0 , 0 , 0 },
36+ {16 , 0 , 4 , 0 },
37+ {0 , 0 , 0 , 0 },
38+ },
39+ },
40+ want : [][]int {
41+ {2 , 4 , 0 , 0 },
42+ {8 , 0 , 0 , 0 },
43+ {16 , 0 , 4 , 0 },
44+ {0 , 0 , 0 , 0 },
45+ },
46+ },
47+ {
48+ name : "Case2" ,
49+ input : field {
50+ board : [][]int {
51+ {128 , 64 , 32 , 16 },
52+ {8 , 0 , 0 , 2 },
53+ {4 , 0 , 0 , 4 },
54+ {2 , 4 , 8 , 16 },
55+ },
56+ },
57+ want : [][]int {
58+ {128 , 64 , 32 , 16 },
59+ {8 , 0 , 0 , 2 },
60+ {4 , 0 , 0 , 4 },
61+ {2 , 4 , 8 , 16 },
62+ },
63+ },
64+ {
65+ name : "Case3" ,
66+ input : field {
67+ board : [][]int {
68+ {0 , 0 , 0 , 0 },
69+ {0 , 2048 , 0 , 0 },
70+ {0 , 0 , 0 , 0 },
71+ {0 , 0 , 0 , 0 },
72+ },
73+ },
74+ want : [][]int {
75+ {0 , 0 , 0 , 0 },
76+ {0 , 2048 , 0 , 0 },
77+ {0 , 0 , 0 , 0 },
78+ {0 , 0 , 0 , 0 },
79+ },
80+ },
81+ {
82+ name : "Case4" ,
83+ input : field {
84+ board : [][]int {
85+ {16 , 8 , 4 , 2 },
86+ {32 , 16 , 8 , 4 },
87+ {64 , 32 , 16 , 8 },
88+ {128 , 64 , 32 , 16 },
89+ },
90+ },
91+ want : [][]int {
92+ {16 , 8 , 4 , 2 },
93+ {32 , 16 , 8 , 4 },
94+ {64 , 32 , 16 , 8 },
95+ {128 , 64 , 32 , 16 },
96+ },
97+ },
98+ }
99+ for _ , tt := range tests {
100+ t .Run (tt .name , func (t * testing.T ) {
101+ game := NewGame ()
102+ game .Init (tt .input .board )
103+ assert .Equal (t , tt .want , game .board )
104+ })
105+ }
106+ }
You can’t perform that action at this time.
0 commit comments