go:- 
	s(state(bank(3,3,1), bank(0,0,0)), []).

goal(state(bank(0,0,0), bank(3,3,1))).

%goal(state(bank(1, 3, 0), bank(2, 0, 1))).

boat(2,0).
boat(1,0).
boat(1,1).
boat(0,1).
boat(0,2).

s(state(bank(ML, CL, BL), bank(MR, CR, BR)), ListOfStates):-
	goal(state(bank(ML, CL, BL), bank(MR, CR, BR))),
	addMember((ML,CL,BL ':' MR,CR,BR), ListOfStates, NewList),
	printIt(NewList).

s(state(bank(ML, CL, BL), bank(MR, CR, BR)), ListOfStates):-
	ML >= 0, ML =< 3, CL >= 0, CL =< 3,
	MR >= 0, MR =< 3, CR >= 0, CR =< 3,
	BL >= 0, BL =< 1, BR >= 0, BR =< 1,
	ML + MR =:= 3, CL + CR =:= 3, BL + BR =:= 1,

%Are they eaten yet?
	((ML >= CL); (ML =:= 0)),
	((MR >= CR); (MR =:= 0)),

%Deja vu anyone?
	not(redCheck((ML,CL,BL ':' MR,CR,BR), ListOfStates)),

%Let's put the new state in the list of states
	addMember((ML,CL,BL ':' MR,CR,BR), ListOfStates, NewList),

%Let's make a move
	((BL =:= 1, boat(M,C), rowToRight(M, C, ML, CL, NewList));
	(BR =:= 1, boat(M,C), rowToLeft(M, C, MR, CR, NewList))).

%Implement the move
rowToRight(M, C, ML, CL, ListOfStates):-
	ML1 is ML - M,
	CL1 is CL - C,
	BL1 is 0,

	MR1 is (3 - ML) + M,
	CR1 is (3 - CL) + C,
	BR1 is 1,
	s(state(bank(ML1, CL1, BL1), bank(MR1, CR1, BR1)), ListOfStates).

rowToLeft(M, C, MR, CR, ListOfStates):-
	MR1 is MR - M,
	CR1 is CR - C,
	BR1 is 0,

	ML1 is (3 - MR) + M,
	CL1 is (3 - CR) + C,
	BL1 is 1,
	s(state(bank(ML1, CL1, BL1), bank(MR1, CR1, BR1)), ListOfStates).

%Print all the states in order
printIt([]).

printIt([Head | Tail]):-
	printIt(Tail),
	write(Head), nl.

addMember(NewMember, OldList, [NewMember|OldList]).

redCheck(State, [State|_]).

redCheck(State, [_|Tail]):-
	redCheck(State, Tail).
