74 lines
2.1 KiB
Plaintext
74 lines
2.1 KiB
Plaintext
v@dir(u, dir) {
|
|
v.dir := dir
|
|
tmp := 32
|
|
bt dir, 4
|
|
if CF
|
|
tmp := LINE_LEN*32
|
|
bt dir, 3
|
|
if CF
|
|
tmp := -tmp
|
|
|
|
if dir & 0b0_111 = 0
|
|
v := u + tmp
|
|
CheckBounds(v)
|
|
Graph.Edges(u, v) := cost(v)
|
|
v := v + tmp
|
|
CheckBounds(v)
|
|
Graph.Edges(u, v) += cost(v)
|
|
v := v + tmp
|
|
CheckBounds(v)
|
|
Graph.Edges(u, v) += cost(v)
|
|
v := v + tmp
|
|
CheckBounds(v)
|
|
Graph.Edges(u, v) += cost(v)
|
|
else
|
|
v := u + tmp
|
|
CheckBounds(v)
|
|
Graph.Edges(u, v) := cost(v)
|
|
}
|
|
|
|
neighbors(u@dir) {
|
|
; can always turn
|
|
neighbors += v@dir(u, ~u.dir & 0b10_000)
|
|
neighbors += v@dir(u, (~u.dir & 0b10_000) | 0b01_000)
|
|
; can go forward if consec < 6
|
|
if u.dir & 0b00_111 < 6
|
|
neighbors += v@dir(u, u.dir + 1)
|
|
}
|
|
|
|
; 28 possibilities, use 32 so we can do bit hacks
|
|
; 00000 00001 00010 00011 00100 00101 00110 00111
|
|
; 0 1 2 3 4 5 6 7
|
|
dir = { R4, R5, R6, R7, R8, R9, RA, XX,
|
|
; 01000 01001 01010 01011 01100 01101 01110 01111
|
|
; 8 9 10 11 12 13 14 15
|
|
L4, L5, L6, L7, L8, L9, LA, XX,
|
|
; 10000 10001 10010 10011 10100 10101 10110 10111
|
|
; 16 17 18 19 20 21 22 23
|
|
D4, D5, D6, D7, D8, D9, DA, XX,
|
|
; 11000 11001 11010 11011 11100 11101 11110 11111
|
|
; 24 25 26 27 28 29 30 31
|
|
U4, U5, U6, U7, U8, U9, UA, XX}
|
|
|
|
dist[(x,y),dir]
|
|
prev[(x,y),dir]
|
|
q[(x,y),dir]
|
|
|
|
for each vertex v in Graph.Vertices:
|
|
dist[v] ← INFINITY
|
|
prev[v] ← UNDEFINED
|
|
add v to Q
|
|
|
|
for all real dir:
|
|
dist[source@dir] ← 0
|
|
|
|
while Q is not empty and any dist[u] in Q < inf:
|
|
u ← vertex in Q with min dist[u]
|
|
remove u from Q
|
|
for each neighbor v of u still in Q:
|
|
alt ← dist[u] + Graph.Edges(u, v)
|
|
if alt < dist[v]:
|
|
dist[v] ← alt
|
|
prev[v] ← u
|
|
done
|