-
Notifications
You must be signed in to change notification settings - Fork 0
/
pathfinder.go
114 lines (94 loc) · 2.07 KB
/
pathfinder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package recursion
import "fmt"
// Path finder recursion
/*
Base cases:
- At the end
- Hit the wall
- Already visited
- Out of the map
Recursive cases:
- Goes all four directions
*/
type Path struct {
points []Point
}
func (path *Path) Pop() (v Point) {
pathLength := len(path.points)
if len(path.points) == 0 {
return
}
newPoints, lastItem := path.points[:pathLength-2], path.points[pathLength-1]
path.points = newPoints
return lastItem
}
func (path *Path) Push(point Point) {
path.points = append(path.points, point)
}
type Point struct {
x int
y int
}
var dir [4][2]int = [4][2]int{
{0, 1}, {0, -1}, {1, 0}, {-1, 0},
}
func walk(maze [][]string, wall string, currentPoint Point, end Point, seen [][]bool, path *Path) bool {
// Base case: off the map
if currentPoint.x >= len(maze[0]) || currentPoint.x < 0 || currentPoint.y < 0 || currentPoint.y >= len(maze) {
return false
}
// Base case: hit the wall
if maze[currentPoint.y][currentPoint.x] == wall {
return false
}
// Arrive at end
if currentPoint.x == end.x && currentPoint.y == end.y {
path.Push(currentPoint)
return true
}
// Base case: already visited
if seen[currentPoint.y][currentPoint.x] {
return false
}
seen[currentPoint.y][currentPoint.x] = true
path.Push(currentPoint)
for i := 0; i < len(dir); i++ {
if walk(maze, wall, Point{
x: currentPoint.x + dir[i][1],
y: currentPoint.y + dir[i][0],
}, end, seen, path) {
return true
}
}
path.Pop()
return false
}
func PathFinder(maze [][]string, wall string, start Point, end Point) Path {
path := Path{points: []Point{}}
seen := make([][]bool, 0)
for i := 0; i < len(maze[0]); i++ {
innerSeen := make([]bool, len(maze[0]))
seen = append(seen, innerSeen)
}
walk(maze, wall, start, end, seen, &path)
return path
}
func PathFinderExample() {
wall := "#"
maze := [][]string{
{"#", "#", "e", "#"},
{"#", "p", "p", "#"},
{"#", "p", "p", "#"},
{"#", "s", "#", "#"},
}
start := Point{
x: 1,
y: 3,
}
end := Point{
x: 2,
y: 0,
}
path := PathFinder(maze, wall, start, end)
fmt.Println("Found path:", path.points)
}