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
