% 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]).
badSpot([X,Y]) :- wall([X,Y]).
badSpot([X,Y]) :- X < 1; Y < 1.
badSpot([X,Y]) :- mazeSize([W, H]), (X > W; Y > H).


%up
moveUp([CurrX, CurrY]) :- NextY is CurrY - 1, NextX = CurrX, \+badSpot([NextX, NextY]).
%down
moveDown([CurrX, CurrY]) :- NextY is CurrY + 1, NextX = CurrX, \+badSpot([NextX, NextY]).
%left
moveLeft([CurrX, CurrY]) :- NextY = CurrY, NextX is CurrX - 1, \+badSpot([NextX, NextY]).
%right
moveRight([CurrX, CurrY]) :- NextY = CurrY, NextX is CurrX + 1, \+badSpot([NextX, NextY]).


checkDown([X ,Y],[X1, Y1]):-
        moveRight([X, Y]) ->  X1 is X +1, Y1 = Y;
        moveDown([X, Y]) -> Y1 is Y +1, X1 = X;
        moveLeft([X, Y]) -> X1 is X -1, Y1 = Y;
        Y1 is Y -1, X1 = X.

checkRight([X, Y],[X1, Y1]):-
        moveUp([X,Y]) -> Y1 is Y -1, X1 = X;
        moveRight([X,Y]) -> X1 is X +1, Y1 = Y;
        moveDown([X,Y]) -> Y1 is Y +1, X1 = X;
        X1 is X +1, Y1 = Y.

checkLeft([X, Y],[X1, Y1]):-
        moveDown([X, Y]) -> Y1 is Y +1, X1 = X;
        moveLeft([X, Y]) -> X1 is X -1, Y1 = Y;
        moveUp([X, Y]) -> Y1 is Y -1, X1 = X;
        X1 is X -1, Y1 = Y.

checkUp([X,Y],[X1, Y1]):-
        moveLeft([X, Y]) -> X1 is X -1, Y1 = Y;
        moveUp([X, Y]) -> Y1 is Y -1, X1 = X ;
        moveRight([X,Y]) -> X1 is X +1, Y1 = Y;
        Y1 is Y +1, X1 = X.

%use current position to check for left wall 
current([PreX, PreY],[CurrX, CurrY],[NextX,NextY]):-
        CurrY is PreY +1, CurrX = PreX -> checkDown([CurrX, CurrY],[NextX, NextY]);
        CurrX is PreX +1, CurrY = PreY -> checkRight([CurrX, CurrY], [NextX, NextY]);
        CurrX is PreX -1, CurrY = PreY -> checkLeft([CurrX, CurrY], [NextX, NextY]);
        CurrY is PreY -1, CurrX = PreX -> checkUp([CurrX, CurrY], [NextX, NextY]). 		

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


% 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(OldLocation, NewLocation, BeenThere, Path):-
        current(OldLocation, NewLocation, NextLocation),
        \+badSpot(OldLocation),
        \+member(NewLocation, BeenThere),
        \+member(NextLocation, BeenThere),
        solve(NewLocation, NextLocation ,[[NewLocation| NextLocation] | BeenThere], RestPath),
        Path = [OldLocation | RestPath].

solve(Path) :- start(Start), move(Start,Next), solve(Start, Next ,[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).