昨天我們完成了遊戲的基本介紹與專案規劃,今天要正式進入 Sudoku 的資料結構設計。
一個數獨遊戲的核心就是 9x9 的盤面,如何設計盤面、如何表示格子的狀態,將會影響到後續的遊戲邏輯。
我們使用 enum 來定義三種狀態,讓程式能清楚分辨格子屬性。
// CellType 代表數獨格子的狀態
type CellType int
const (
Empty CellType = iota // 空格
Preset // 題目預設的數字
Input // 玩家輸入的數字
)
一個格子需要存放 數字 與 狀態
// Cell 代表數獨的一個格子
type Cell struct {
Value int // 數字,0 表示空格
Type CellType // 狀態:Empty、Preset、Input
}
數獨盤面是 9x9 的二維陣列,用 Board 結構來封裝。
// Board 代表數獨盤面
type Board struct {
Cells [9][9]Cell
}
我們需要一個函式來產生空盤,所有格子都初始化為 Empty。
// Board - 盤面
type Board struct {
Cells [9][9]Cell
}
// NewBoard 建立一個空的數獨盤面
func NewBoard() *Board {
board := &Board{}
for row := 0; row < 9; row++ {
for col := 0; col < 9; col++ {
board.Cells[row][col] = Cell{Value: 0, Type: Empty}
}
}
return board
}
type Game struct {
board *Board
}
func NewGame() *Game {
return &Game{
board: NewBoard(),
}
}
func TestNewGame(t *testing.T) {
tests := []struct {
name string
wantBoard *Board
}{
{
name: "Empty Board",
wantBoard: &Board{
Cells: [9][9]Cell{
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
{
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
{0, Empty}, {0, Empty}, {0, Empty},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
game := NewGame()
assert.Equal(t, tt.wantBoard.Cells, game.board.Cells)
})
}
}
https://github.com/leetcode-golang-classroom/sudoku-game/actions/runs/17499941923