Hey i'm currently fiddling with Prolog to complete the tower of hanoi puzzle game. I've managed to be able to represent the search space like this:
hanoi_move predicate is the current state([][][]), then the goal state([][][]) then (X Y Z)
I have been able to solve this problem using rules and facts then a depth first search and a next_node function. as shown:
I was wondering what you think and if possible, a way to improve on this search using a heuristic? Something like a Drunk/Gambling search that can chose a random route but not loop on itself or an A* algorithm search, or other ideas.
Any help is much appreciated.
Any help and ideas are much appreciated.
Code:
% Initial State:
% -8 | |
% ---7 | |
% -----6 | |
% -------5 | |
% ---------4 | |
% -----------3 | |
% -------------2 | |
% ---------------1____________|__________________|__________
%
% (State = what pieces are upon what poles)
%
% use: hanoi_move([8,7,6,5,4,3,2,1],[],[],[],[],[8,7,6,5,4,3,2,1],X,Y,Z).
hanoi_move predicate is the current state([][][]), then the goal state([][][]) then (X Y Z)
I have been able to solve this problem using rules and facts then a depth first search and a next_node function. as shown:
Code:
hanoi_move([],[],[],A,B,C,_,_,_):- (write('Please Enter Some Discs ([3,2,1],[],[] etc.)')). %No Variables Entered into Lists
hanoi_move(A,B,C,A,B,C,_,_,_):- (write('DONE')). %If the Current state is the Goal state
hanoi_move([H1|T1],[],L3,Goal1,G2,G3,T1,[H1],L3). %Move from peg 1 - peg 2 when empty list
hanoi_move([H1|T1],[H2|T2],L3,Goal1,G2,G3,T1,[H1,H2|T2],L3):- %Move from peg 1 - peg 2
(H1 > H2). %Cannot put bigger discs upon smaller
%Cannot move from an empty peg
hanoi_move([H1|T1],L2,[],Goal1,G2,G3,T1,L2,[H1]). %Move from peg 1 - peg 3 when empty list
hanoi_move([H1|T1],L2,[H3|T3],Goal1,G2,G3,T1,L2,[H1,H3|T3]):- %Move from peg 1 - peg 3
(H1 > H3).
hanoi_move([],[H2|T2],L3,Goal1,G2,G3,[H2],T2,L3). %Move from peg 2 - peg 1 when empty list
hanoi_move([H1|T1],[H2|T2],L3,Goal1,G2,G3,[H2,H1|T1],T2,L3):- %Move from peg 2 - peg 1
(H2 > H1).
hanoi_move(L1,[H2|T2],[],Goal1,G2,G3,L1,T2,[H2]). %Move from peg 2 - peg 3 when empty list
hanoi_move(L1,[H2|T2],[H3|T3],Goal1,G2,G3,L1,T2,[H2,H3|T3]):- %Move from peg 2 - peg 3
(H2 > H3).
hanoi_move([],L2,[H3|T3],Goal1,G2,G3,[H3],L2,T3). %Move from peg 3 - peg 1 when empty list
hanoi_move([H1|T1],L2,[H3|T3],Goal1,G2,G3,[H3,H1|T1],L2,T3):- %Move from peg 3 - peg 1
(H3 > H1).
hanoi_move(L1,[],[H3|T3],Goal1,G2,G3,L1,[H3],T3). %Move from peg 3 - peg 2 when empty list
hanoi_move(L1,[H2|T2],[H3|T3],Goal1,G2,G3,L1,[H3,H2|T2],T3):- %Move from peg 3 - peg 2
(H3 > H2).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicate - next_node/9
% Arguments:
% Current1,C2,C3 - the current position of the pieces%
% Path1,P2,P3 - the list of already visited states
% Next1,N2,N3 - the Next state after current
%
% use: next_node([4,3,2,1],[],[],[],[],[4,3,2,1],[4,3,2,1],[],[],A,B,C).
next_node(Current1,C2,C3, Goal1,G2,G3, Path1,P2,P3, Next1,N2,N3):-
hanoi_move(Current1,C2,C3, Goal1,G2,G3, Next1,N2,N3), %Calls the facts to get the next nodes
not(member(Next1,N2,N3,Path1,P2,P3)). %Checks if the next nodes have already been visited
%%%%%%%%%%%%%%%%%%%%%%%%%%
% GENERAL ROUTINES
member(X,Y,Z,[X|_],[Y|_],[Z|_]). %is a member if it is the head
member(X,Y,Z,[_|T],[_|T2],[_|T3]) :- member(X,Y,Z,T,T2,T3). %is a member if it is in the tail
%%%%%%%%%%%%%%%%%%%%%%
% DEPTH-FIRST SEARCH
% Predicate - depth_first/9
%
% use - depth_first([4,3,2,1],[],[],[],[],[4,3,2,1],A,B,C).
depth_first(Start1,S2,S3, Goal1,G2,G3, Path1,P2,P3) :-
depth_first1(Start1,S2,S3, Goal1,G2,G3, [Start1],[S2],[S3], Path1,P2,P3).
depth_first1(Goal1,G2,G3, Goal1,G2,G3, _,_,_, [Goal1],[G2],[G3]). %Boundary Case
depth_first1(Start1,S2,S3, Goal1,G2,G3, Visited1,V2,V3, [Start1 | Path1], [S2 | P2], [S3 | P3]) :-
next_node(Start1,S2,S3, Goal1,G2,G3, Visited1,V2,V3, Next_node1,Next_node2,Next_node3),
/*write('Visited: '), write(Visited1),write(V2),write(V3), nl,*/
depth_first1(Next_node1,Next_node2,Next_node3, Goal1,G2,G3, [Next_node1 | Visited1],[Next_node2 | V2],[Next_node3 | V3], Path1,P2,P3).
I was wondering what you think and if possible, a way to improve on this search using a heuristic? Something like a Drunk/Gambling search that can chose a random route but not loop on itself or an A* algorithm search, or other ideas.
Any help is much appreciated.
Any help and ideas are much appreciated.