% Create the maze
% Row 1
wall([X,1]) :- X =\= 2.
% Row 2
wall([X,2]) :- X = 1; X = 4; X = 6.
% Row 3
wall([X,3]) :- X = 1; X = 2; X = 6.
% Row 4
wall([X,4]) :- X =\= 3,X =\= 5.
% Row 5
wall([X,5]) :- X = 1; X = 4; X = 6.
% Row 6
wall([X,6]) :- X =\= 2.
% Start / end
start([2,1]).
end([2,6]).
% Maze Size
mazeSize([6,6]).

% Wall is bad, out of bounds is bad.
badSpot([X,Y]) :- wall([X,Y]).
badSpot([X,Y]) :- X < 1; Y < 1.
badSpot([X,Y]) :- mazeSize([W, H]), (X > W; Y > H).

% Movement options
move([CurrX, CurrY], [CurrX, NextY]) :- NextY is CurrY - 1.
move([CurrX, CurrY], [NextX, NextY]) :- NextY is CurrY + 1, NextX = CurrX.
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX - 1.
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX + 1.

movementOriented([W,X],[Y,Z]):- A is 2-W*2-W+6-X*6-X, B is 2-Y*2-Y+6-Z*6-Z, A < B.

% Base Case
solve(CurrentLocation, _, Path) :- end(CurrentLocation), Path = [CurrentLocation].

% Recursive Solve with Oriented Mover
solve(CurrentLocation, BeenThere, Path) :-
	move(CurrentLocation, NewLocation),
		\+movementOriented(CurrentLocation, NewLocation),
        		\+badSpot(NewLocation),
        			\+member(NewLocation, BeenThere),
       				solve(NewLocation, [NewLocation | BeenThere], RestOfPath),
        					Path = [CurrentLocation | RestOfPath].
		
% Backup Recursive Solve lacking Oriented Mover		
solve(CurrentLocation, BeenThere, Path) :-
	move(CurrentLocation, NewLocation),
        	\+badSpot(NewLocation),
			\+member(NewLocation, BeenThere),
				solve(NewLocation, [NewLocation | BeenThere], RestOfPath),
        				Path = [CurrentLocation | RestOfPath].
solve(Path) :- start(Start), solve(Start, [Start], Path).
