go例子(二) 使用go語言實現數獨遊戲
阿新 • • 發佈:2018-12-21
例子託管於github
example.go
package mainimport ( "./sudoku" )
func main() { //var smap sudoku.Sudomap //smap = make([]byte,9) //for i:= 0; i<len(smap);i++{
sudoku/sudoku.go
package sudokuimport ( "fmt" )
type Sudomap [][]byte
var CanChoose []map[byte]byte // 0-8 行 9-17 列 18-26 塊 可填值的map var count = 0
func (smap *Sudomap) Print() { for _, line := range *smap { for _, v := range line { fmt.Printf("%d ", v) } fmt.Println() } } func PrintChoose() { i := 0 for _, v := range CanChoose { fmt.Println(i, v) i++ } }
/* 統計空缺的個數 */ func (smap *Sudomap) countZero() { for _, line := range *smap { for _, v := range line { if v == 0 { // 值為0時表示可填 count++ } } } } func makemap() (m map[byte]byte) { var i byte m = make(map[byte]byte) for i = 1; i <= 9; i++ { m[i] = i } return }
// 初始化可以填的數的列表,為map[int]int的陣列 func (smap *Sudomap) initCanChoose() { // 陣列初始化時是27個map 每個map中的鍵值為1-9 for i := 0; i < 27; i++ { CanChoose = append(CanChoose, makemap()) } // 根據傳進來的數獨資料進行刪除可以填寫的map表 for i := 0; i < 9; i++ { for j := 0; j < 9; j++ { if c := (*smap)[i][j]; c != 0 { //fmt.Println(c,i,j) delete(CanChoose[i], c) // 第i行 delete(CanChoose[j+9], c) // 第j列 delete(CanChoose[j/3+i/3*3+18], c) // 第?塊 //PrintChoose() } } } }
/* 判斷是否可以填寫,根據行,列,塊map確定唯一可以填寫的值 */ func (smap *Sudomap) isCanChoose(i, j int) (byte, bool) { flag := 0 var p byte var ok bool for _, v := range CanChoose[i] { p, ok = CanChoose[j+9][v] if ok != true { continue } p, ok = CanChoose[j/3+i/3*3+18][v] if ok != true { continue } flag++ } if flag == 1 { //fmt.Println("isCanChoose ",p) return p, true } else { return p, false } }
/* 進行填值操作 */ func (smap *Sudomap) do() { for i := 0; i < 9; i++ { for j := 0; j < 9; j++ { if c := (*smap)[i][j]; c == 0 { v, ok := smap.isCanChoose(i, j) if ok != true || v == 0 { continue } count-- delete(CanChoose[i], v) // 第i行 delete(CanChoose[j+9], v) // 第j列 delete(CanChoose[j/3+i/3*3+18], v) // 第?塊 (*smap)[i][j] = v fmt.Println("我認為:(", i+1, "行", j+1, "列)為", v) } } } }
/* 主入口 */ func (smap *Sudomap) SolveSudoku() { smap.countZero() //fmt.Println(count) //smap.Print() smap.initCanChoose() //PrintChoose() for count > 0 { smap.do() } //smap.Print() }