1. 程式人生 > >go例子(二) 使用go語言實現數獨遊戲

go例子(二) 使用go語言實現數獨遊戲

例子託管於github

example.go

package main
import (     "./sudoku" )
func main() {     //var smap sudoku.Sudomap     //smap = make([]byte,9)     //for i:= 0; i<len(smap);i++{
    //  smap[i] = make (byte,9)     //}     smap := sudoku.Sudomap{         {5, 3, 0, 0, 7, 0, 0, 0, 0},         {6, 0, 0, 1, 9, 5, 0, 0, 0},
        {0, 9, 8, 0, 0, 0, 0, 6, 0},         {8, 0, 0, 0, 6, 0, 0, 0, 3},         {4, 0, 0, 8, 0, 3, 0, 0, 1},         {7, 0, 0, 0, 2, 0, 0, 0, 6},
        {0, 6, 0, 0, 0, 0, 2, 8, 0},         {0, 0, 0, 4, 1, 9, 0, 0, 5},         {0, 0, 0, 0, 8, 0, 0, 7, 9},     }     smap.SolveSudoku() }

sudoku/sudoku.go

package sudoku
import (     "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() }