%Follow 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]).

%directions
facing(south).
facing(north).
facing(east).
facing(west).

badSpot([X,Y]) :- wall([X,Y]).
badSpot([X,Y]) :- X < 1; Y < 1.
badSpot([X,Y]) :- mazeSize([W, H]), (X > W; Y > H).

%south
possibleForward([X, Y, south]) :- NextX = X, NextY is Y - 1, \+badSpot([NextX, NextY]).
possibleBack([X, Y, south]) :- Next X = X, Next Y is Y + 1, \+badSpot([NextX, NextY]).
possibleLeft([X, Y, south]) :- Next X is X + 1, NextY = Y, \+badSpot([NextX, NextY]).
possibleRight([X, Y, south]) :- Next X is X - 1, NextY = Y, \+badSpot([NextX, NextY]).

%north
possibleForward([X, Y, north]) :- NextX = X, NextY is Y + 1, \+badSpot([NextX, NextY]).
possibleBack([X, Y, north]) :- Next X = X, Next Y is Y - 1, \+badSpot([NextX, NextY]).
possibleLeft([X, Y, north]) :- Next X is X - 1, NextY = Y, \+badSpot([NextX, NextY]).
possibleRight([X, Y, north]) :- Next X is X + 1, NextY = Y, \+badSpot([NextX, NextY]).

%west
possibleForward([X, Y, west]) :- NextX is X - 1 , NextY = Y, \+badSpot([NextX, NextY]).
possibleBack([X, Y, west]) :- Next X is X + 1 , Next Y = Y, \+badSpot([NextX, NextY]).
possibleLeft([X, Y, west]) :- Next X = X, NextY is Y - 1, \+badSpot([NextX, NextY]).
possibleRight([X, Y, west]) :- Next X = X, NextY is Y + 1, \+badSpot([NextX, NextY]).

%east
possibleForward([X, Y, east]) :- NextX is X + 1 , NextY = Y, \+badSpot([NextX, NextY]).
possibleBack([X, Y, east]) :- Next X is X - 1 , Next Y = Y, \+badSpot([NextX, NextY]).
possibleLeft([X, Y, east]) :- Next X = X, NextY is Y + 1, \+badSpot([NextX, NextY]).
possibleRight([X, Y, east]) :- Next X = X, NextY is Y - 1, \+badSpot([NextX, NextY]).

%prefer to go left

%up
move([CurrX, CurrY], [CurrX, NextY]) :- NextY is CurrY - 1.
%down
move([CurrX, CurrY], [NextX, NextY]) :- NextY is CurrY + 1, NextX = CurrX.
%left
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX - 1.
%right
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX + 1.


%possible direction to move left
possibleLeft([CurrX,CurrY]) :- NextX is CurrX - 1, NextY = CurrY, \+badSpot([NextX,NextY]).

possibleRight([CurrX, CurrY]) :- NextX is CurrX + 1, NextY = CurrY, \+badSpot([NextX, NextY]).

possibleUp([CurrX, CurrY]) :- NextX = CurrX, NextY is CurrY + 1, \+badSpot([NextX, NextY]).

possibleDown([CurrX, CurrY]) :- NextX = CurrX, NextY is CurrY - 1, \+badSpot([NextX, NextY]).


%moving in that direction
moveLeft([X,Y], [X1,Y1]) :- possibleLeft([X1, Y1]) -> X1 is X+1, Y1 = Y;
		 	   possibleDown([X1, Y1]) -> X1 = X, Y1 is Y - 1;
			   possibleUp([X1, Y1]) -> X1 = X, Y1 is Y + 1;
			   possibleRight([X1, Y1]) -> X1 is X - 1, Y1 = Y.

moveRight([X,Y], [X1, Y1]) :- possibleRight([X1, Y1] -> X1 is X - 1, Y1 = Y;
			    possibleDown([X1, Y1]) -> X1 = X, Y1 is Y - 1;
			   possibleUp([X1, Y1]) -> X1 = X, Y1 is Y + 1;
			possibleLeft([X1, Y1]) -> X1 is X+1, Y1 = Y.
				
moveUp([X,Y], [X1, Y1]) :- possibleUp(X1, Y1]) -> X1 = X, Y1 is Y + 1;
			possibleLeft([X1, Y1]) -> X1 is X+1, Y1 = Y;
			possibleRight([X1, Y1] -> X1 is X - 1, Y1 = Y.
			possibleDown([X1, Y1]) -> X1 = X, Y1 is Y - 1.

moveDown([X, Y], [X1, Y1]) :- possibleDown([X1, Y1]) -> X1 = X, Y1 is Y - 1;
			possibleLeft([X1, Y1]) -> X1 is X+1, Y1 = Y;
			possibleRight([X1, Y1] -> X1 is X - 1, Y1 = Y
			possibleUp(X1, Y1]) -> X1 = X, Y1 is Y + 1.

%direction
%[X,Y, Direction] north; x - 1, y ; east; x , y - 1; west x, y + 1; south; x + 1, y;

%back
move([CurrX, CurrY], [CurrX, NextY]) :- NextY is CurrY - 1.
%forward
move([CurrX, CurrY], [NextX, NextY]) :- NextY is CurrY + 1, NextX = CurrX.
%right
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX - 1.
%left
move([CurrX, CurrY], [NextX, NextY]) :- NextY = CurrY, NextX is CurrX + 1.



% A solution of the maze from our current location is [] if our current location is the end.
solve(CurrentLocation, _, Path) :- end(CurrentLocation), Path = [CurrentLocation].


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





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).