iT邦幫忙

2025 iThome 鐵人賽

DAY 6
2

今日目標

昨天我們已經完成了 左滑的合併邏輯,今天要讓遊戲可以往 上、右、下 三個方向滑動。
我們不會為每個方向重寫一套邏輯,而是 透過陣列轉置(transpose)與反轉(reverse),把其他方向的滑動轉換成「左滑」,再呼叫同一個函式處理。

核心概念

  • 左滑 → 已經實作完成
  • 右滑 = 先反轉每一列 → 左滑 → 再反轉回來
  • 上滑 = 先轉置矩陣 → 左滑 → 再轉置回來
  • 下滑 = 先轉置矩陣 → 右滑 → 再轉置回來
    這樣一來,四個方向只需要維護一套合併邏輯。

程式結構

// transpose - 把整個  board 作轉置
func (g *Game) transpose() [][]int {
	// board[r][c] = board[c][r]
	transposedBoard := make([][]int, sideSize)
	for r := range sideSize {
		transposedBoard[r] = make([]int, sideSize)
		for c := range sideSize {
			transposedBoard[r][c] = g.board[c][r]
		}
	}
	return transposedBoard
}

// reverseRow - 把整個 Row 反過來
func (g *Game) reverseRow(row []int) []int {
	reversedRow := make([]int, len(row))
	for idx := range len(row) {
		reversedRow[idx] = row[len(row)-idx-1]
	}
	return reversedRow
}

// moveRight - 整個 board 同時往右
func (g *Game) moveRight() {
	// 先把整個  board 作 reverse
	for i := range g.board {
		g.board[i] = g.reverseRow(g.board[i])
	}
	// 把整個 board 往左移動
	g.moveLeft()
	// 再整個  board 作 reverse 回來
	for i := range g.board {
		g.board[i] = g.reverseRow(g.board[i])
	}
}

// moveUp - 整個 board 同時往上
func (g *Game) moveUp() {
	// 先把 board 作轉置
	g.board = g.transpose()
	// 再把 board 同時往左
	g.moveLeft()
	// 再把 board 作轉置
	g.board = g.transpose()
}

// moveDown - 把整個 board 往下移動
func (g *Game) moveDown() {
	// 先把整個 board 轉置
	g.board = g.transpose()
	// 再把整個 board 往右滑
	g.moveRight()
	// 再把整個 board 轉置
	g.board = g.transpose()
}

gemini 產生測試案例的 prompt

gemini -p "你是一位 Golang 2048 遊戲邏輯的專業測試案例設計師。

任務:
請生成至少 3 組 4x4 棋盤的測試案例,
並提供每組棋盤在『向左、向右、向上、向下』四個方向滑動後的正確結果,
用來測試我的程式是否正確實作了四個方向的滑動邏輯。

規則提醒:
1. 每次滑動會將所有數字朝滑動方向推進。
2. 兩個相鄰且數值相同的格子會合併成該數值的兩倍。
3. 每個格子在一次滑動中最多只能合併一次。
4. 合併後的格子會緊貼滑動方向,其餘位置補 0。
5. 上下滑動等同於轉置矩陣後套用左右滑動規則。

輸出格式:
[
  {
    'original': [
      [x, x, x, x],
      [x, x, x, x],
      [x, x, x, x],
      [x, x, x, x]
    ],
    'left': [
      [...]
    ],
    'right': [
      [...]
    ],
    'up': [
      [...]
    ],
    'down': [
      [...]
    ]
  },
  ...
]

要求:
- 數字僅使用 0、2、4、8、16。
- 至少要有空格 (0) 與可合併的數字混合。
- 每組案例的原始棋盤要盡量不同,避免單一模式。
- 請直接輸出 JSON 格式結果,不要有多餘解釋。
"

gemini 產生的測試案例

[
  {
    "original": [
      [2, 2, 0, 4],
      [0, 4, 4, 8],
      [2, 0, 2, 0],
      [8, 8, 8, 8]
    ],
    "left": [
      [4, 4, 0, 0],
      [8, 8, 0, 0],
      [4, 0, 0, 0],
      [16, 16, 0, 0]
    ],
    "right": [
      [0, 0, 4, 4],
      [0, 0, 8, 8],
      [0, 0, 0, 4],
      [0, 0, 16, 16]
    ],
    "up": [
      [4, 2, 4, 4],
      [8, 4, 2, 16],
      [0, 8, 8, 16],
      [0, 0, 0, 0]
    ],
    "down": [
      [0, 0, 0, 0],
      [0, 2, 4, 0],
      [4, 4, 2, 4],
      [8, 8, 8, 16]
    ]
  },
  {
    "original": [
      [4, 4, 8, 16],
      [4, 0, 4, 0],
      [2, 2, 2, 2],
      [0, 0, 0, 0]
    ],
    "left": [
      [8, 8, 16, 0],
      [8, 0, 0, 0],
      [4, 4, 0, 0],
      [0, 0, 0, 0]
    ],
    "right": [
      [0, 8, 8, 16],
      [0, 0, 0, 8],
      [0, 0, 4, 4],
      [0, 0, 0, 0]
    ],
    "up": [
      [8, 4, 8, 16],
      [2, 2, 4, 2],
      [0, 0, 2, 0],
      [0, 0, 0, 0]
    ],
    "down": [
      [0, 0, 0, 0],
      [0, 0, 8, 0],
      [8, 4, 4, 16],
      [2, 2, 2, 2]
    ]
  },
  {
    "original": [
      [2, 4, 8, 16],
      [4, 8, 16, 2],
      [8, 16, 2, 4],
      [16, 2, 4, 8]
    ],
    "left": [
      [2, 4, 8, 16],
      [4, 8, 16, 2],
      [8, 16, 2, 4],
      [16, 2, 4, 8]
    ],
    "right": [
      [2, 4, 8, 16],
      [4, 8, 16, 2],
      [8, 16, 2, 4],
      [16, 2, 4, 8]
    ],
    "up": [
      [2, 4, 8, 16],
      [4, 8, 16, 2],
      [8, 16, 2, 4],
      [16, 2, 4, 8]
    ],
    "down": [
      [2, 4, 8, 16],
      [4, 8, 16, 2],
      [8, 16, 2, 4],
      [16, 2, 4, 8]
    ]
  }
]

測試結果

https://github.com/leetcode-golang-classroom/2048-game/actions/runs/17076939330

今日收穫

  • 學會用 轉置 + 反轉 來重用邏輯,避免為每個方向重寫程式。
  • 完成四方向滑動功能,遊戲邏輯已經接近完整。

明日預告(Day 7)

我們將進入 Ebiten 畫面初始渲染,把棋盤從 CLI 變成真正的遊戲畫面,看到 4x4 的格子與背景


上一篇
2048遊戲: 基本滑動邏輯(以左滑為例)
下一篇
2048遊戲: Ebiten 畫面初始渲染
系列文
在 ai 時代 gopher 遊戲開發者的 30 天自我養成23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言