1 more bugfix in this commit: running a BFS over BFSs was not traversing the paths from shortest to longest, because it was implicitly counting the number of crate pushes and not including moves in between crate pushes. Now things seem a lot more natural.
YR62G4PUZEC2PMXMLTPUKFYTSQ3YTCAXXFGLZOIQTUOM2FABPNFQC
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x-1, y=c.y}, dir='left', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x-1, y=c.y}, dir='left', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x+1, y=c.y}, dir='right', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x+1, y=c.y}, dir='right', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y-1}, dir='up', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y-1}, dir='up', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y+1}, dir='down', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y+1}, dir='down', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {x=x-1, y=y, dir='left', prev=cand})
table.insert(cands, {x=x+1, y=y, dir='right', prev=cand})
table.insert(cands, {x=x, y=y-1, dir='up', prev=cand})
table.insert(cands, {x=x, y=y+1, dir='down', prev=cand})
table.insert(cands, {x=x-1, y=y, dir='left', prev=cand, path_length=p+1})
table.insert(cands, {x=x+1, y=y, dir='right', prev=cand, path_length=p+1})
table.insert(cands, {x=x, y=y-1, dir='up', prev=cand, path_length=p+1})
table.insert(cands, {x=x, y=y+1, dir='down', prev=cand, path_length=p+1})
function shortest_path(cands)
Real_print('', #cands)
local min, minscore = 1, cands[1].path_length
for i=2,#cands do
local iscore = cands[i].path_length
Real_print('', i, iscore, '<=>', min,minscore)
if iscore < minscore then
min, minscore = i, iscore
end
end
return min
end