Skip to content

Commit 8547afd

Browse files
committed
✨ (2048): add moveLeft function
1 parent 037782f commit 8547afd

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

internal/game.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,15 @@ func (g *Game) addRandomTile() {
5353
}
5454
}
5555
}
56+
5657
// 如果所有格子都滿了
5758
if len(emptyTiles) == 0 {
5859
return
5960
}
61+
6062
// 選出要填入的位置
6163
position := emptyTiles[g.randomPositonerFunc(len(emptyTiles))]
64+
6265
// 90% 機率是 2 , 10% 機率則為 4
6366
value := 2
6467
if g.randomFunc() < 0.1 {
@@ -67,6 +70,53 @@ func (g *Game) addRandomTile() {
6770
g.board[position[0]][position[1]] = value
6871
}
6972

73+
// slideAndMergeLeft - 向左滑動並且合併
74+
func (g *Game) slideAndMergeLeft(row []int) []int {
75+
// 1 去掉空格
76+
filtered := make([]int, 0, len(row))
77+
for _, v := range row {
78+
if v != 0 {
79+
filtered = append(filtered, v)
80+
}
81+
}
82+
83+
// 假設沒有空格
84+
if len(filtered) == 0 {
85+
return row
86+
}
87+
88+
// 2 合併相鄰相同數字
89+
for i := 0; i < len(filtered)-1; i++ {
90+
if filtered[i] == filtered[i+1] {
91+
filtered[i] *= 2
92+
filtered[i+1] = 0
93+
i++ // 跳過剛合併的數字
94+
}
95+
}
96+
97+
// 3 再次去掉空格
98+
result := make([]int, 0, len(row))
99+
for _, v := range filtered {
100+
if v != 0 {
101+
result = append(result, v)
102+
}
103+
}
104+
105+
// 4 補充剩下的空格為 0
106+
for len(result) < len(row) {
107+
result = append(result, 0)
108+
}
109+
110+
return result
111+
}
112+
113+
// moveLeft - 整個 board 同時左移
114+
func (g *Game) moveLeft() {
115+
for r := 0; r < sideSize; r++ {
116+
g.board[r] = g.slideAndMergeLeft(g.board[r][:])
117+
}
118+
}
119+
70120
func NewGame() *Game {
71121
return &Game{
72122
nil,

internal/game_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,75 @@ func TestGameRandTile(t *testing.T) {
243243
}
244244

245245
}
246+
247+
func TestGameMoveLeft(t *testing.T) {
248+
type field struct {
249+
board [][]int
250+
}
251+
tests := []struct {
252+
name string
253+
input field
254+
want [][]int
255+
}{
256+
{
257+
name: "case1: 單行多次合併",
258+
input: field{
259+
board: [][]int{
260+
{4, 4, 4, 4},
261+
{2, 2, 0, 0},
262+
{2, 0, 2, 0},
263+
{8, 0, 0, 8},
264+
},
265+
},
266+
want: [][]int{
267+
{8, 8, 0, 0},
268+
{4, 0, 0, 0},
269+
{4, 0, 0, 0},
270+
{16, 0, 0, 0},
271+
},
272+
},
273+
{
274+
name: "case2: 新生成的數字不參與當回合合併",
275+
input: field{
276+
board: [][]int{
277+
{2, 2, 4, 8},
278+
{0, 0, 0, 0},
279+
{4, 4, 8, 8},
280+
{2, 2, 2, 2},
281+
},
282+
},
283+
want: [][]int{
284+
{4, 4, 8, 0},
285+
{0, 0, 0, 0},
286+
{8, 16, 0, 0},
287+
{4, 4, 0, 0},
288+
},
289+
},
290+
{
291+
name: "case3: 無合併,只有移動",
292+
input: field{
293+
board: [][]int{
294+
{2, 4, 8, 16},
295+
{0, 2, 0, 4},
296+
{8, 0, 4, 0},
297+
{2, 4, 2, 4},
298+
},
299+
},
300+
want: [][]int{
301+
{2, 4, 8, 16},
302+
{2, 4, 0, 0},
303+
{8, 4, 0, 0},
304+
{2, 4, 2, 4},
305+
},
306+
},
307+
}
308+
for _, tt := range tests {
309+
t.Run(tt.name, func(t *testing.T) {
310+
game := NewGame()
311+
game.Init(tt.input.board, nil, nil)
312+
// 模擬左移
313+
game.moveLeft()
314+
assert.Equal(t, tt.want, game.board)
315+
})
316+
}
317+
}

0 commit comments

Comments
 (0)