Go 迷宮演算法

來源:互聯網
上載者:User

標籤:ret   混淆   bubuko   檔案的   str   col   fun   dir   walk   

首先讀取一個迷宮檔案maze.in (第一行是檔案的行列  下面是檔案內容:1表示牆 0表示此路可走)

如何讀取?

//讀取一個二維數組 func readMaze(filename string) [][]int {    // 先開啟檔案 預設是已經存在這個檔案 故沒有做其他出錯處理    file, err := os.Open(filename)      if err != nil {        panic(err)    }    //需要先將行、列讀出來 利用Fscanf讀取    var row, col int    fmt.Fscanf(file, "%d %d", &row, &col)    //建立二維slice 注意:這裡是傳入參數行row 因為二維數組其實就是:有row這麼多一維數組構成 這裡是使用切片    maze := make([][]int, row)    for i := range maze {        maze[i] = make([]int, col)  //利用make建立        for j := range maze[i] {            fmt.Fscanf(file, "%d", &maze[i][j])        }    }    return maze}func main() {    maze := readMaze("mazepractice/maze.in")    for _,row := range maze {        for _,val := range row {            fmt.Printf("%3d",val)        }        fmt.Println()    }}

 迷宮演算法解讀

package mainimport (    "fmt"    "os")func readMaze(filename string) [][]int {    file, err := os.Open(filename)    if err != nil {        panic(err)    }    var row, col int    fmt.Fscanf(file, "%d %d", &row, &col)    maze := make([][]int, row)    for i := range maze {        maze[i] = make([]int, col)        for j := range maze[i] {            fmt.Fscanf(file, "%d", &maze[i][j])        }    }    return maze}// 定義點的結構體 因為這裡是數組 最好不要用x,y定義(以免自己與座標混淆)type point struct {    i, j int}// 定義4個方向分別是:上 左 下 右 方向var dirs = [4]point{    {-1, 0}, {0, -1}, {1, 0}, {0, 1}}// 走迷宮需要從上左下右方向去走,因此座標會相應的變化  註:這裡是利用返回一個新的point 而不是利用指標(當然,指標也可以)func (p point) add(r point) point {    return point{p.i + r.i, p.j + r.j}}//判斷走的點是不是合理的 有沒越界  傳回值是點和一個狀態值func (p point) at(grid [][]int) (int, bool) {    if p.i < 0 || p.i >= len(grid) {        return 0, false    }    if p.j < 0 || p.j >= len(grid[p.i]) {        return 0, false    }    return grid[p.i][p.j], true}// 走迷宮的關鍵演算法 通過傳入3個參數:二維切片,開始點,結束點  返回的是:一個二維切片func walk(maze [][]int, start, end point) [][]int {    // 這裡其實是建立一個走過路線的steps 根據我們讀取的檔案maze.in規格大小來建立    steps := make([][]int, len(maze))    for i := range steps {        steps[i] = make([]int, len(maze[i]))    }    // 建立一個隊列 開始點是(0,0)    Q := []point{start}    // 隊列不空    for len(Q) > 0 {        cur := Q[0]  //cur代表隊列開始點(0,0)        Q = Q[1:]    //去掉隊列第一個點        // 發現終點 退出        if cur == end {            break        }       // 沒有走到的請看        for _, dir := range dirs {            // 通過上 左 下 右 走這些路            next := cur.add(dir)            // 判斷走的路線是不是可以走:0 可以走  1 不可以走  當然越界也是不行的            val, ok := next.at(maze)            if !ok || val == 1 {                continue            }            // 判斷這些點有沒有走過:就是不要走回頭路            val, ok = next.at(steps)            if !ok || val != 0 {                continue            }            // 不是0 可能回到起點 不行的            if next == start {                continue            }            // 當前的步驟數            curSteps, _ := cur.at(steps)            steps[next.i][next.j] = curSteps + 1            // 把這個放在隊列的後面            Q = append(Q, next)        }    }    return steps}func main() {    maze := readMaze("mazepractice/maze.in")    steps := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})    // 列印實際走的這個數組    for _, row := range steps {        for _, val := range row {            fmt.Printf("%3d", val)        }        fmt.Println()    }    lessStep := steps[len(maze)-1][len(maze[0])-1]    fmt.Printf("這個迷宮最少需要%d步走完",lessStep)    // TODO: construct path from steps}

 左邊是讀取的檔案,右邊是輸出結果:

 

 左邊是讀取的檔案,右邊是輸出結果:

 

Go 迷宮演算法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.