go 广度优先算法走迷宫

这个走迷宫算法的原理:就是利用队列先进后出,以起始点为出发,将这个点按照某个方向规则走,周围所有可以走的位置依次写入到队列,这个点走完之后,队首出队列,走这个点所有可以走的点,按照之前的规则,将走过点依次放入到队列中,重复之前过程,直到队列为空或者走到终点。在这个过程中在借助一个辅助矩阵,存放起点到位置的最短路径。


文件内容:

6 5
0 1 1 1 0
0 0 0 1 0
0 1 0 1 0
0 0 0 0 0
0 1 0 0 1
0 1 0 0 1

package main


import (
"fmt"
"os"
)

// 点结构
type point struct {
i, j int
}

func (p point) add(r point) point {
return point{p.i + r.i, p.j + r.j}
}

func (p point) at(grip [][]int) (int, bool) {
// 往上越界,往下越界
if p.i < 0 || p.i >= len(grip) {
return 0, false
}

// 往左,往右越界
if p.j < 0 || p.j >= len(grip[p.i]) {
return 0, false
}
return grip[p.i][p.j], true
}

// 走的方向
var dirs = [4]point{
{-1, 0}, /* 向上 */
{0, -1}, /* 向左 */
{1, 0},  /* 向下 */
{0, 1},  /* 向右 */
}

// 函数说明:读取文件内容
// 参数说明:
//      fileName: 文件名

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
}

// 方法:广度优先走迷宫
// 参数说明:
//    maze:  迷宫图
//    start: 开始坐标
//    end:   结束坐标

func walk(maze [][]int, start, end point) [][]int {
// steps用来存放广度优先走过的路径
steps := make([][]int, len(maze))
for i := range steps {
steps[i] = make([]int, len(maze[i]))
}
// 创建Q队列
Q := []point{start}
// 退出的结束条件是队列为空
for len(Q) > 0 {
cur := Q[0]
Q = Q[1:]

// 走到终点
if cur == end {
break
}

for _, dir := range dirs {
next := cur.add(dir)
// 如果没有走出迷宫和碰到墙
val, ok := next.at(maze)
if !ok || val == 1 {
continue
}
// 没有走出迷宫和走过
val, ok = next.at(steps)
if !ok || val != 0 {
continue
}
// 走到起始点
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("./maze.in")
// 打印迷宫
fmt.Println("迷宫图:")
for i := range maze {
for j := range maze[i] {
fmt.Printf("%2d ", maze[i][j])
}
fmt.Println()
}
fmt.Println()
//
steps := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
// 打印路径
fmt.Println("打印路径:")
for i := range steps {
for j := range steps[i] {
fmt.Printf("%2d ", steps[i][j])
}
fmt.Println()
}
min := 0
if steps[len(steps)-2][len(steps[0])-1] == 0 {
min = steps[len(steps)-1][len(steps[0])-2]
} else if steps[len(steps)-1][len(steps[0])-2] == 0 {
min = steps[len(steps)-2][len(steps[0])-1]
} else if steps[len(steps)-1][len(steps[0])-2] < steps[len(steps)-2][len(steps[0])-1] {
min = steps[len(steps)-1][len(steps[0])-2]
} else {
min = steps[len(steps)-2][len(steps[0])-1]
}
fmt.Printf("达到坐标:(%d,%d)的最小路径是:%d\n", len(steps), len(steps[0]), min)

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值