Skip to content

Commit 20ec61f

Browse files
committed
✨ (sudoku-game): add cursor and input logic
1 parent 4d98862 commit 20ec61f

File tree

9 files changed

+142
-12
lines changed

9 files changed

+142
-12
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ This is a implementation sudoku game with golang
44

55
# 執行畫面
66

7-
![sudoku-game-play](sudoku-game-play.png)
7+
初始畫面
8+
![sudoku-game-play](sudoku-game-play.png)
9+
10+
游標輸入
11+
![sudoku-game-play-with-cursor](sudoku-game-play-with-cursor.png)

internal/game/board.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package game
33
import "fmt"
44

55
// 檢查 row, col 位置是否可以放置 num
6-
func (board *Board) isSafe(row, col, num int) bool {
6+
func (board *Board) IsSafe(row, col, num int) bool {
77
// 檢查行與列是否有放相同的值
88
for i := 0; i < BoardSize; i++ {
99
if board.Cells[row][i].Value == num ||
@@ -23,10 +23,6 @@ func (board *Board) isSafe(row, col, num int) bool {
2323
}
2424
}
2525

26-
// 檢查 num 值介於 1 到 9
27-
if num < 1 || num > 9 {
28-
return false
29-
}
3026
return true
3127
}
3228

internal/game/board_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestIsSafe(t *testing.T) {
5454
for _, tt := range tests {
5555
t.Run(tt.name, func(t *testing.T) {
5656
board := tt.setup()
57-
got := board.isSafe(tt.targetCoord.Row, tt.targetCoord.Col, tt.targetValue)
57+
got := board.IsSafe(tt.targetCoord.Row, tt.targetCoord.Col, tt.targetValue)
5858
assert.Equal(t, tt.want, got)
5959
})
6060
}

internal/game/puzzle.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func (board *Board) presetBoard() bool {
2020
// 隨機取值出來填寫
2121
for _, digit := range digitsShuffled() {
2222
// 確認 digit 是否可以填入 row, col
23-
if board.isSafe(row, col, digit) {
23+
if board.IsSafe(row, col, digit) {
2424
// 先填入 row, col 為 digit
2525
board.Cells[row][col].Type = Preset
2626
board.Cells[row][col].Value = digit
@@ -54,7 +54,7 @@ func solveCount(board *Board, limit int) int {
5454
// 開始試著填入值找到解答
5555
count := 0
5656
for _, digit := range digitsShuffled() {
57-
if board.isSafe(row, col, digit) {
57+
if board.IsSafe(row, col, digit) {
5858
// 先填入 row, col 為 digit
5959
board.Cells[row][col].Type = Preset
6060
board.Cells[row][col].Value = digit

internal/game/sudoku.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ const (
77

88
// Board - 盤面
99
type Board struct {
10-
Cells [BoardSize][BoardSize]*Cell
10+
Cells [BoardSize][BoardSize]*Cell
11+
CursorRow int
12+
CursorCol int
1113
}
1214

1315
// NewBoard 建立一個空的數獨盤面
@@ -32,3 +34,31 @@ func NewGame() *Game {
3234
Board: NewBoard(),
3335
}
3436
}
37+
38+
func (board *Board) IncreaseCursorRow() {
39+
if board.CursorRow < BoardSize-1 {
40+
board.CursorRow++
41+
return
42+
}
43+
}
44+
45+
func (board *Board) DecreaseCursorRow() {
46+
if board.CursorRow >= 1 {
47+
board.CursorRow--
48+
return
49+
}
50+
}
51+
52+
func (board *Board) IncreaseCursorCol() {
53+
if board.CursorCol < BoardSize-1 {
54+
board.CursorCol++
55+
return
56+
}
57+
}
58+
59+
func (board *Board) DecreaseCursorCol() {
60+
if board.CursorCol >= 1 {
61+
board.CursorCol--
62+
return
63+
}
64+
}

internal/layout/cursor-control.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package layout
2+
3+
import (
4+
"github.com/hajimehoshi/ebiten/v2"
5+
"github.com/hajimehoshi/ebiten/v2/inpututil"
6+
)
7+
8+
// DetectCursor - 游標移動
9+
func (gameLayout *GameLayout) DetectCursor() {
10+
// 游標移動偵測
11+
if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) {
12+
gameLayout.gameInstance.Board.DecreaseCursorRow()
13+
return
14+
}
15+
if inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) {
16+
gameLayout.gameInstance.Board.IncreaseCursorRow()
17+
return
18+
}
19+
if inpututil.IsKeyJustPressed(ebiten.KeyArrowLeft) {
20+
gameLayout.gameInstance.Board.DecreaseCursorCol()
21+
return
22+
}
23+
if inpututil.IsKeyJustPressed(ebiten.KeyArrowRight) {
24+
gameLayout.gameInstance.Board.IncreaseCursorCol()
25+
return
26+
}
27+
}

internal/layout/input-control.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package layout
2+
3+
import (
4+
"github.com/hajimehoshi/ebiten/v2"
5+
"github.com/hajimehoshi/ebiten/v2/inpututil"
6+
"github.com/leetcode-golang-classroom/sudoku-game/internal/game"
7+
)
8+
9+
// DetectInput - 處理鍵盤輸入
10+
func (gameLayout *GameLayout) DetectInput() {
11+
board := gameLayout.gameInstance.Board
12+
targetRow := board.CursorRow
13+
targetCol := board.CursorCol
14+
targetCell := board.Cells[targetRow][targetCol]
15+
// 偵測合法數字輸入
16+
// 數字輸入
17+
for key := ebiten.KeyDigit1; key <= ebiten.KeyDigit9; key++ {
18+
if inpututil.IsKeyJustPressed(key) {
19+
if targetCell.Type != game.Preset {
20+
value := int(key - ebiten.KeyDigit0)
21+
// 檢查輸入的值是否為放入是否能會造成 Conflict
22+
if !board.IsSafe(targetRow, targetCol, value) {
23+
// 標示為 Conflict Input
24+
board.Cells[targetRow][targetCol].Type = game.InputConflict
25+
} else {
26+
board.Cells[targetRow][targetCol].Type = game.Input
27+
}
28+
// 更新輸入
29+
board.Cells[targetRow][targetCol].Value = value
30+
}
31+
return
32+
}
33+
}
34+
35+
// 清除輸入
36+
if inpututil.IsKeyJustPressed(ebiten.Key0) || inpututil.IsKeyJustPressed(ebiten.KeyDelete) {
37+
if targetCell.Type != game.Preset {
38+
// 清空目前 Cell 的值
39+
board.Cells[targetRow][targetCol].Value = 0
40+
board.Cells[targetRow][targetCol].Type = game.Empty
41+
}
42+
return
43+
}
44+
}

internal/layout/layout.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,42 @@ type GameLayout struct {
2424
}
2525

2626
func (gameLayout *GameLayout) Update() error {
27+
gameLayout.DetectCursor()
28+
gameLayout.DetectInput()
2729
return nil
2830
}
2931

3032
func (gameLayout *GameLayout) Draw(screen *ebiten.Image) {
3133
// 畫出基本背景
3234
gameLayout.drawBoardBackground(screen)
35+
// // 畫出 cursor
36+
gameLayout.drawCursor(screen)
3337
// 根據遊戲狀態來畫出盤面
3438
gameLayout.drawCellValuesOnBoard(screen)
3539
// 畫出盤面格線
3640
gameLayout.drawLinesOnBoard(screen)
3741
}
3842

43+
func (gameLayout *GameLayout) drawCursor(screen *ebiten.Image) {
44+
cursorBgColor := color.RGBA{0xff, 0, 0, 128}
45+
targetRow := gameLayout.gameInstance.Board.CursorRow
46+
targetCol := gameLayout.gameInstance.Board.CursorCol
47+
if gameLayout.gameInstance.Board.Cells[targetRow][targetCol].Type == game.Preset {
48+
cursorBgColor = color.RGBA{0xff, 0xff, 0, 128}
49+
}
50+
if gameLayout.gameInstance.Board.Cells[targetRow][targetCol].Type == game.Input {
51+
cursorBgColor = color.RGBA{0x00, 0xff, 0x00, 128}
52+
}
53+
if gameLayout.gameInstance.Board.Cells[targetRow][targetCol].Type == game.InputConflict {
54+
cursorBgColor = color.RGBA{0x00, 0xff, 0xff, 128}
55+
}
56+
gameLayout.drawCellBackground(screen,
57+
gameLayout.gameInstance.Board.CursorRow,
58+
gameLayout.gameInstance.Board.CursorCol,
59+
cursorBgColor,
60+
)
61+
}
62+
3963
// drawBoardBackground - 畫出盤面背景顏色
4064
func (gameLayout *GameLayout) drawBoardBackground(screen *ebiten.Image) {
4165
boardBgColor := color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}
@@ -50,8 +74,13 @@ func (gameLayout *GameLayout) drawCellValuesOnBoard(screen *ebiten.Image) {
5074
for row := 0; row < game.BoardSize; row++ {
5175
for col := 0; col < game.BoardSize; col++ {
5276
// draw preset value
53-
if board.Cells[row][col].Type == game.Preset {
54-
gameLayout.drawCellBackground(screen, row, col, getTileBgColor(board.Cells[row][col].Type))
77+
if board.Cells[row][col].Type == game.Preset ||
78+
board.Cells[row][col].Type == game.Input ||
79+
board.Cells[row][col].Type == game.InputConflict {
80+
if row != gameLayout.gameInstance.Board.CursorRow ||
81+
col != gameLayout.gameInstance.Board.CursorCol {
82+
gameLayout.drawCellBackground(screen, row, col, getTileBgColor(board.Cells[row][col].Type))
83+
}
5584
gameLayout.drawCellValue(screen, row, col, board.Cells[row][col].Value,
5685
getTileColor(board.Cells[row][col].Type),
5786
)

sudoku-game-play-with-cursor.png

26.7 KB
Loading

0 commit comments

Comments
 (0)