1. package main
    2. import (
    3. "fmt"
    4. "os"
    5. )
    6. func readMaze(fileName string) [][]int {
    7. file, err := os.Open(fileName)
    8. if err != nil {
    9. panic(err)
    10. }
    11. var row, col int
    12. fmt.Fscanf(file, "%d %d", &row, &col)
    13. maze := make([][]int, row)
    14. for i := range maze {
    15. maze[i] = make([]int, col)
    16. for j := range maze[i] {
    17. fmt.Fscanf(file, "%d", &maze[i][j])
    18. }
    19. }
    20. return maze
    21. }
    22. type point struct {
    23. i, j int
    24. }
    25. var dirs = [4]point{
    26. {-1, 0},
    27. {0, -1},
    28. {1, 0},
    29. {0, 1},
    30. }
    31. func (p point) add(r point) point {
    32. return point{p.i + r.i, p.j + r.j}
    33. }
    34. func (p point) at(grid [][]int) (int, bool) {
    35. if p.i < 0 || p.i >= len(grid) {
    36. return 0, false
    37. }
    38. if p.j < 0 || p.j >= len(grid[0]) {
    39. return 0, false
    40. }
    41. return grid[p.i][p.j], true
    42. }
    43. func walk(maze [][]int, start, end point) [][]int {
    44. steps := make([][]int, len(maze))
    45. for i := range steps {
    46. steps[i] = make([]int, len(maze[i]))
    47. }
    48. Q := []point{start}
    49. for len(Q) > 0 {
    50. cur := Q[0]
    51. Q = Q[1:]
    52. if cur == end {
    53. break
    54. }
    55. for _, dir := range dirs {
    56. next := cur.add(dir)
    57. // 下个节点是空白的才能继续
    58. val, ok := next.at(maze)
    59. if !ok || val == 1 {
    60. continue
    61. }
    62. val, ok = next.at(steps)
    63. if !ok || val != 0 {
    64. continue
    65. }
    66. if next == start {
    67. continue
    68. }
    69. curSteps, _ := cur.at(steps)
    70. steps[next.i][next.j] = curSteps + 1
    71. Q = append(Q, next)
    72. }
    73. }
    74. return steps
    75. }
    76. func main() {
    77. maze := readMaze("maze/maze.in")
    78. steps := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
    79. for _, row := range steps {
    80. for _, val := range row {
    81. fmt.Printf("%3d ", val)
    82. }
    83. fmt.Println()
    84. }
    85. }