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

%Checks location of walls, maze bounds, makes sure we cant move there
badSpot([X,Y]) :- wall([X,Y]).
badSpot([X,Y]) :- X < 1; Y < 1.
badSpot([X,Y]) :- mazeSize([W, H]), (X > W; Y > H).

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

moveLeft(Forward, Left) :- Left is mod(Forward + 3, 4).
moveRight(Forward, Right) :- Right is mod(Forward + 1, 4).

% 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, Direction) :- 
        moveLeft(Direction, LeftDir),
        moveRight(Direction, RightDir),
        move(CurrentLocation, NewLocation, LeftDir),
        (badSpot(NewLocation) -> 
                (solve(CurrentLocation, BeenThere, Path, RightDir)) ; 
                (solve(NewLocation, [NewLocation | BeenThere], RestOfPath, LeftDir))),
        Path = [CurrentLocation | RestOfPath].
		
% Convenience rule
solve(Path) :- start(Start), solve(Start, [Start], Path, StartDir).
