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

%Specific moves
moveup([CurrX,CurrY],[CurrX,NextY]):- NextY is CurrY -1.
movedown([CurrX,CurrY],[CurrX,NextY]):- NextY is CurrY +1.
moveleft([CurrX,CurrY],[NextX,CurrY]):- NextX is CurrX -1.
moveright([CurrX,CurrY],[NextX,CurrY]):- NextX is CurrX +1.



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

%base case
solve(CurrentLocation,_,Path):- end(CurrentLocation),Path = [CurrentLocation].
%Attempt to move in the direction of the exit if the move is safe and has not been visited before
% exit is above current position
solve(CurrentLocation,BeenThere,Path):- end(End),End = [_,EndY|_],
    CurrentLocation = [_,CurrY|_],EndY<CurrY,moveup(CurrentLocation,NextLocation),
    \+badSpot(NextLocation),\+member(NextLocation,BeenThere),
    solve(NextLocation,[NextLocation,BeenThere],RestOfPath),
    Path = [CurrentLocation|RestOfPath].
% exit is below current position
solve(CurrentLocation,BeenThere,Path):- end(End),End = [_,EndY|_],
    CurrentLocation = [_,CurrY|_],EndY>CurrY,movedown(CurrentLocation,NextLocation),
    \+badSpot(NextLocation),\+member(NextLocation,BeenThere),
    solve(NextLocation,[NextLocation,BeenThere],RestOfPath),
    Path = [CurrentLocation|RestOfPath].
%exit is to the left
solve(CurrentLocation,BeenThere,Path):- end(End),End = [EndX|_],
    CurrentLocation = [CurrX|_],EndX<CurrX,moveleft(CurrentLocation,NextLocation),
    \+badSpot(NextLocation),\+member(NextLocation,BeenThere),
    solve(NextLocation,[NextLocation,BeenThere],RestOfPath),
    Path = [CurrentLocation|RestOfPath].
%exit is to the right
solve(CurrentLocation,BeenThere,Path):- end(End),End = [EndX|_],
    CurrentLocation = [CurrX|_],EndX>CurrX,moveright(CurrentLocation,NextLocation),
    \+badSpot(NextLocation),\+member(NextLocation,BeenThere),
    solve(NextLocation,[NextLocation,BeenThere],RestOfPath),
    Path = [CurrentLocation|RestOfPath].

%If no prefered move can be made then follow the next available move
%no prefered movements are valid move to the next available space
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).



