%%%%%%% Maze: Follow the left wall %%%%%%%%
% 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]).

% Spaces outside the bounds of the maze
badSpot([X,Y]) :- wall([X,Y]).
badSpot([X,Y]) :- X < 1; Y < 1.
badSpot([X,Y]) :- mazeSize([W, H]), (X > W; Y > H).

% move from current position to new position and change direction from where
% you're facing to where you consider turning

% North
move([CurrX,CurrY], [NewX, CurrY], north, west) :- NewX is CurrX-1.
move([CurrX,CurrY], [CurrX, NewY], north, north) :- NewY is CurrY-1.
move([CurrX,CurrY], [NewX, CurrY], north, east) :- NewX is CurrX+1.
move([CurrX,CurrY], [CurrX, NewY], north, south) :- NewY is CurrY+1.

% South
move([CurrX,CurrY], [NewX, CurrY], south, east) :- NewX is CurrX+1.
move([CurrX,CurrY], [CurrX, NewY], south, south) :- NewY is CurrY+1.
move([CurrX,CurrY], [NewX, CurrY], south, west) :- NewX is CurrX-1.
move([CurrX,CurrY], [CurrX, NewY], south, north) :- NewY is CurrY-1.

% East
move([CurrX,CurrY], [CurrX, NewY], east, north) :- NewY is CurrY-1.
move([CurrX,CurrY], [NewX, CurrY], east, east) :- NewX is CurrX+1.
move([CurrX,CurrY], [CurrX, NewY], east, south) :- NewY is CurrY+1.
move([CurrX,CurrY], [NewX, CurrY], east, west) :- NewX is CurrX-1.

% West 
move([CurrX,CurrY], [CurrX, NewY], west, south) :- NewY is CurrY+1.
move([CurrX,CurrY], [NewX, CurrY], west, west) :- NewX is CurrX-1.
move([CurrX,CurrY], [CurrX, NewY], west, north) :- NewY is CurrY-1.
move([CurrX,CurrY], [NewX, CurrY], west, east) :- NewX is CurrX+1.


% A solution for if space is the exit is empty
solve(CurrentLocation, Path, _) :- end(CurrentLocation), Path = [CurrentLocation].

solve(CurrentLocation, Path, CurrentDirection) :- 
    	move(CurrentLocation, NewLocation, CurrentDirection, NewDirection), 
        \+badSpot(NewLocation),
        solve(NewLocation, RestOfPath, NewDirection), 
        Path = [CurrentLocation | RestOfPath].
		
% Convenience rule
solve(Path, SDir) :- start(Start), solve(Start, Path, SDir).


drawCell(Column, Row, _) :- wall([Column, Row]), write("X"), !.
drawCell(Column, Row, _) :- start([Column, Row]), write("S"), !.
drawCell(Column, Row, _) :- end([Column, Row]), write("E"), !.
drawCell(Column, Row, Path) :- member([Column, Row], Path), write("P"), !.
drawCell(_, _, _) :- write("O").

drawRow(Row, Path) :- drawCell(1, Row, Path), tab(1), drawCell(2, Row, Path), tab(1), 
        drawCell(3, Row, Path), tab(1), drawCell(4, Row, Path), tab(1), 
        drawCell(5, Row, Path), tab(1), drawCell(6, Row, Path), nl.
                
draw :- drawRow(1, []), drawRow(2, []), drawRow(3, []), drawRow(4, []), drawRow(5, []), 
        drawRow(6, []).
draw(Path) :- drawRow(1, Path), drawRow(2, Path), drawRow(3, Path), drawRow(4, Path),
        drawRow(5, Path), drawRow(6, Path).