iT邦幫忙

2025 iThome 鐵人賽

DAY 26
2

主題

在前一天,我們已經完成了 Sudoku 基本盤面繪製,能在畫面上顯示 9x9 的格子結構。
今天的目標是讓玩家能夠「操作遊戲」,具體來說:

  • 用鍵盤方向鍵移動游標,選擇不同的格子。
  • 按下數字鍵 (1–9) 來輸入數字到選定格子。
  • 避免覆蓋題目格子,僅能輸入在玩家可編輯的格子。

功能需求

游標控制

  • 使用方向鍵 ↑ ↓ ← → 移動。
  • 游標只能在盤面內 (0 ≤ row, col < 9)。

數字輸入

  • 玩家選中格子後,按下 1–9 對應輸入數字。
  • 0 或 Delete 代表清空輸入。
  • 僅允許修改「玩家輸入格子」,不可更動題目預設格子。

驗收條件

  • 游標能正確移動並顯示在選中格子上。
  • 數字輸入能更新盤面,並顯示在格子中。

程式設計

游標移動

// DetectCursor - 游標移動
func (gameLayout *GameLayout) DetectCursor() {
	// 游標移動偵測
	if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) {
		gameLayout.gameInstance.Board.DecreaseCursorRow()
		return
	}
	if inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) {
		gameLayout.gameInstance.Board.IncreaseCursorRow()
		return
	}
	if inpututil.IsKeyJustPressed(ebiten.KeyArrowLeft) {
		gameLayout.gameInstance.Board.DecreaseCursorCol()
		return
	}
	if inpututil.IsKeyJustPressed(ebiten.KeyArrowRight) {
		gameLayout.gameInstance.Board.IncreaseCursorCol()
		return
	}
}

鍵盤輸入

// DetectInput - 處理鍵盤輸入
func (gameLayout *GameLayout) DetectInput() {
	board := gameLayout.gameInstance.Board
	targetRow := board.CursorRow
	targetCol := board.CursorCol
	targetCell := board.Cells[targetRow][targetCol]
	// 偵測合法數字輸入
	// 數字輸入
	for key := ebiten.KeyDigit1; key <= ebiten.KeyDigit9; key++ {
		if inpututil.IsKeyJustPressed(key) {
			if targetCell.Type != game.Preset {
				value := int(key - ebiten.KeyDigit0)
				// 檢查輸入的值是否為放入是否能會造成 Conflict
				if !board.IsSafe(targetRow, targetCol, value) {
					// 標示為 Conflict Input
					board.Cells[targetRow][targetCol].Type = game.InputConflict
				} else {
					board.Cells[targetRow][targetCol].Type = game.Input
				}
				// 更新輸入
				board.Cells[targetRow][targetCol].Value = value
			}
			return
		}
	}

	// 清除輸入
	if inpututil.IsKeyJustPressed(ebiten.Key0) || inpututil.IsKeyJustPressed(ebiten.KeyDelete) {
		if targetCell.Type != game.Preset {
			// 清空目前 Cell 的值
			board.Cells[targetRow][targetCol].Value = 0
			board.Cells[targetRow][targetCol].Type = game.Empty
		}
		return
	}
}

程式重點解說

游標控制

  • 方向鍵控制 CursorRow 與 CursorCol。
  • 保證游標不會超出盤面。

數字輸入

  • 按下 1–9 會輸入數字到目前游標所在格。
  • 0 或 Delete 會清除數字。
  • 題目格子 (CellType == Preset) 無法被修改。

游標顯示

  • 使用半透明紅色矩形顯示當前選中格子。

執行結果

游標顯示

https://ithelp.ithome.com.tw/upload/images/20250907/20111580wCtAENhxOt.png

輸入數值

https://ithelp.ithome.com.tw/upload/images/20250907/20111580BowSC6k66r.png
https://ithelp.ithome.com.tw/upload/images/20250907/201115802bd7ovc6Wk.png

清除數值

https://ithelp.ithome.com.tw/upload/images/20250907/20111580P0PB3xJrJO.png

github action 測試結果

https://github.com/leetcode-golang-classroom/sudoku-game/actions/runs/17530043633

今日收穫

  • 學會在 Ebiten 中透過鍵盤控制游標移動。
  • 能正確在盤面上輸入數字,並區分 題目格子 與 玩家輸入格子。
  • 完成了數獨遊戲的核心互動功能之一:輸入解答。

明日預期

明天我們將實作 即時規則檢查:

  • 判斷玩家輸入的數字是否與數獨規則衝突(同列、同行、同宮不能重複)。
  • 在 UI 上提示錯誤,例如用紅字或警告框顯示。
  • 勝利判斷

上一篇
Sudoku 遊戲: Ebiten 基本盤面繪製
下一篇
Sudoku遊戲:輸入違規時給予錯誤提示或標記
系列文
在 ai 時代 gopher 遊戲開發者的 30 天自我養成30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言