much more clearer A* implementation