Skip to content

Commit c2d25e8

Browse files
committed
✨ (2048): add moveUp, moveLeft, moveRight
1 parent 8547afd commit c2d25e8

File tree

4 files changed

+441
-211
lines changed

4 files changed

+441
-211
lines changed

internal/game.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,62 @@ func (g *Game) moveLeft() {
117117
}
118118
}
119119

120+
// transpose - 把整個 board 作轉置
121+
func (g *Game) transpose() [][]int {
122+
// board[r][c] = board[c][r]
123+
transposedBoard := make([][]int, sideSize)
124+
for r := range sideSize {
125+
transposedBoard[r] = make([]int, sideSize)
126+
for c := range sideSize {
127+
transposedBoard[r][c] = g.board[c][r]
128+
}
129+
}
130+
return transposedBoard
131+
}
132+
133+
// reverseRow - 把整個 Row 反過來
134+
func (g *Game) reverseRow(row []int) []int {
135+
reversedRow := make([]int, len(row))
136+
for idx := range len(row) {
137+
reversedRow[idx] = row[len(row)-idx-1]
138+
}
139+
return reversedRow
140+
}
141+
142+
// moveRight - 整個 board 同時往右
143+
func (g *Game) moveRight() {
144+
// 先把整個 board 作 reverse
145+
for i := range g.board {
146+
g.board[i] = g.reverseRow(g.board[i])
147+
}
148+
// 把整個 board 往左移動
149+
g.moveLeft()
150+
// 再整個 board 作 reverse 回來
151+
for i := range g.board {
152+
g.board[i] = g.reverseRow(g.board[i])
153+
}
154+
}
155+
156+
// moveUp - 整個 board 同時往上
157+
func (g *Game) moveUp() {
158+
// 先把 board 作轉置
159+
g.board = g.transpose()
160+
// 再把 board 同時往左
161+
g.moveLeft()
162+
// 再把 board 作轉置
163+
g.board = g.transpose()
164+
}
165+
166+
// moveDown - 把整個 board 往下移動
167+
func (g *Game) moveDown() {
168+
// 先把整個 board 轉置
169+
g.board = g.transpose()
170+
// 再把整個 board 往右滑
171+
g.moveRight()
172+
// 再把整個 board 轉置
173+
g.board = g.transpose()
174+
}
175+
120176
func NewGame() *Game {
121177
return &Game{
122178
nil,

internal/game_move_test.go

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
package internal
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestGameMoveLeft(t *testing.T) {
11+
type field struct {
12+
board [][]int
13+
}
14+
tests := []struct {
15+
name string
16+
input field
17+
want [][]int
18+
}{
19+
{
20+
name: "case1: 單行多次合併",
21+
input: field{
22+
board: [][]int{
23+
{4, 4, 4, 4},
24+
{2, 2, 0, 0},
25+
{2, 0, 2, 0},
26+
{8, 0, 0, 8},
27+
},
28+
},
29+
want: [][]int{
30+
{8, 8, 0, 0},
31+
{4, 0, 0, 0},
32+
{4, 0, 0, 0},
33+
{16, 0, 0, 0},
34+
},
35+
},
36+
{
37+
name: "case2: 新生成的數字不參與當回合合併",
38+
input: field{
39+
board: [][]int{
40+
{2, 2, 4, 8},
41+
{0, 0, 0, 0},
42+
{4, 4, 8, 8},
43+
{2, 2, 2, 2},
44+
},
45+
},
46+
want: [][]int{
47+
{4, 4, 8, 0},
48+
{0, 0, 0, 0},
49+
{8, 16, 0, 0},
50+
{4, 4, 0, 0},
51+
},
52+
},
53+
{
54+
name: "case3: 無合併,只有移動",
55+
input: field{
56+
board: [][]int{
57+
{2, 4, 8, 16},
58+
{0, 2, 0, 4},
59+
{8, 0, 4, 0},
60+
{2, 4, 2, 4},
61+
},
62+
},
63+
want: [][]int{
64+
{2, 4, 8, 16},
65+
{2, 4, 0, 0},
66+
{8, 4, 0, 0},
67+
{2, 4, 2, 4},
68+
},
69+
},
70+
}
71+
for _, tt := range tests {
72+
t.Run(tt.name, func(t *testing.T) {
73+
game := NewGame()
74+
game.Init(tt.input.board, nil, nil)
75+
// 模擬左移
76+
game.moveLeft()
77+
assert.Equal(t, tt.want, game.board)
78+
})
79+
}
80+
}
81+
82+
func TestGameMove(t *testing.T) {
83+
84+
type field struct {
85+
board [][]int
86+
}
87+
type result struct {
88+
left [][]int
89+
right [][]int
90+
up [][]int
91+
down [][]int
92+
}
93+
tests := []struct {
94+
name string
95+
input field
96+
want result
97+
}{
98+
{
99+
name: "case1",
100+
input: field{
101+
board: [][]int{
102+
{2, 2, 0, 4},
103+
{0, 4, 4, 8},
104+
{2, 0, 2, 0},
105+
{8, 8, 8, 8},
106+
},
107+
},
108+
want: result{
109+
left: [][]int{
110+
{4, 4, 0, 0},
111+
{8, 8, 0, 0},
112+
{4, 0, 0, 0},
113+
{16, 16, 0, 0},
114+
},
115+
right: [][]int{
116+
{0, 0, 4, 4},
117+
{0, 0, 8, 8},
118+
{0, 0, 0, 4},
119+
{0, 0, 16, 16},
120+
},
121+
up: [][]int{
122+
{4, 2, 4, 4},
123+
{8, 4, 2, 16},
124+
{0, 8, 8, 0},
125+
{0, 0, 0, 0},
126+
},
127+
down: [][]int{
128+
{0, 0, 0, 0},
129+
{0, 2, 4, 0},
130+
{4, 4, 2, 4},
131+
{8, 8, 8, 16},
132+
},
133+
},
134+
},
135+
{
136+
name: "case2",
137+
input: field{
138+
board: [][]int{
139+
{4, 4, 8, 16},
140+
{4, 0, 4, 0},
141+
{2, 2, 2, 2},
142+
{0, 0, 0, 0},
143+
},
144+
},
145+
want: result{
146+
left: [][]int{
147+
{8, 8, 16, 0},
148+
{8, 0, 0, 0},
149+
{4, 4, 0, 0},
150+
{0, 0, 0, 0},
151+
},
152+
right: [][]int{
153+
{0, 8, 8, 16},
154+
{0, 0, 0, 8},
155+
{0, 0, 4, 4},
156+
{0, 0, 0, 0},
157+
},
158+
up: [][]int{
159+
{8, 4, 8, 16},
160+
{2, 2, 4, 2},
161+
{0, 0, 2, 0},
162+
{0, 0, 0, 0},
163+
},
164+
down: [][]int{
165+
{0, 0, 0, 0},
166+
{0, 0, 8, 0},
167+
{8, 4, 4, 16},
168+
{2, 2, 2, 2},
169+
},
170+
},
171+
},
172+
{
173+
name: "case3 - 無法移動",
174+
input: field{
175+
board: [][]int{
176+
{2, 4, 8, 16},
177+
{4, 8, 16, 2},
178+
{8, 16, 2, 4},
179+
{16, 2, 4, 8},
180+
},
181+
},
182+
want: result{
183+
left: [][]int{
184+
{2, 4, 8, 16},
185+
{4, 8, 16, 2},
186+
{8, 16, 2, 4},
187+
{16, 2, 4, 8},
188+
},
189+
right: [][]int{
190+
{2, 4, 8, 16},
191+
{4, 8, 16, 2},
192+
{8, 16, 2, 4},
193+
{16, 2, 4, 8},
194+
},
195+
up: [][]int{
196+
{2, 4, 8, 16},
197+
{4, 8, 16, 2},
198+
{8, 16, 2, 4},
199+
{16, 2, 4, 8},
200+
},
201+
down: [][]int{
202+
{2, 4, 8, 16},
203+
{4, 8, 16, 2},
204+
{8, 16, 2, 4},
205+
{16, 2, 4, 8},
206+
},
207+
},
208+
},
209+
}
210+
for _, tt := range tests {
211+
t.Run(fmt.Sprintf("%s left", tt.name), func(t *testing.T) {
212+
game := NewGame()
213+
game.Init(tt.input.board, nil, nil)
214+
// 模擬左移
215+
game.moveLeft()
216+
assert.Equal(t, tt.want.left, game.board)
217+
})
218+
t.Run(fmt.Sprintf("%s right", tt.name), func(t *testing.T) {
219+
game := NewGame()
220+
game.Init(tt.input.board, nil, nil)
221+
// 模擬右移
222+
game.moveRight()
223+
assert.Equal(t, tt.want.right, game.board)
224+
})
225+
t.Run(fmt.Sprintf("%s up", tt.name), func(t *testing.T) {
226+
game := NewGame()
227+
game.Init(tt.input.board, nil, nil)
228+
// 模擬上移
229+
game.moveUp()
230+
assert.Equal(t, tt.want.up, game.board)
231+
})
232+
t.Run(fmt.Sprintf("%s down", tt.name), func(t *testing.T) {
233+
game := NewGame()
234+
game.Init(tt.input.board, nil, nil)
235+
// 模擬下移
236+
game.moveDown()
237+
assert.Equal(t, tt.want.down, game.board)
238+
})
239+
}
240+
}

0 commit comments

Comments
 (0)