% explications nécessaires solve(_SokobanPos, BoxsPos, Plan, Len) :- end(BoxsPos), !, Plan = [], Len = 0. solve(SokobanPos, BoxsPos, [push(BoxPos, Dir, Destination) | Plan], Len) :- select(BoxPos, BoxsPos, NewBoxsPos), next_location(PrevNextLoc, BoxPos, Dir), \+ member(PrevNextLoc, NewBoxsPos), next_location(BoxPos, NextNextLoc, Dir), possible_dest(NextNextLoc, BoxPos1), reachable(SokobanPos, PrevNextLoc, BoxsPos), next_dest(BoxPos, NextNextLoc, Dir, Destination, NewSokobanPos, BoxPos1), insert_list(Destination, NewBoxsPos, NexBoxsPos), solve(NewSokobanPos, NexBoxsPos, Plan, Len1), Len is Len1 + 1. % explication nécessaires reachable(Pos, Pos, BoxsPos). reachable(X, Y, BoxsPos) :- next_location(X, Z, _), \+ member(Z, BoxsPos), reachable(Z, Y, BoxsPos). % good_dest(Loc,BoxLocs):- % \+ member(Loc,BoxLocs), % (corner(Loc)->storage(Loc);true), % foreach(BoxLoc in BoxLocs, \+ stuck(BoxLoc,Loc)). possible_dest(Pos, []). possible_dest(Pos, [BoxPos|BoxPosSuite]) :- \+ Pos = BoxPos, (corner(Pos)->storage(Pos);true), \+ stuck(BoxPos, Pos), possible_dest(Pos, BoxPosSuite). next_dest(Pos, NextPos, _Dir, Destination, NewSokobanPos, _BoxsPos) :- Destination = NextPos, NewSokobanPos = BoxPos. next_dest(Pos, NextPos, Dir, Destination, NewSokobanPos, BoxsPos) :- next_location(NextPos, NextNextPos, Dir), possible_dest(NextNextPos, BoxsPos), next_dest(NextPos, NextNextPos, Dir, Destination, NewSokobanPos, BoxsPos).