% Peg solitaire puzzle % Brute force, no tabling % Can make about 9 moves /* Board consists of list peg(X,Y) and hole(X,Y) enumerated in row-major order (2,0), (3,0), ..., (3,6), (4,6) with blocked spaces missing */ % test(N) -- print the number of possible N moves test(N) :- g_assign(count, 0), solve(N), g_inc(count), % not affected by backtracking fail. test(N) :- g_read(count, K), format("At ~p, ~p solutions\n", [N,K]). % solve(N) -- make N moves from initial state solve(N) :- init(State0), moves(N, State0). % moves(N, State) -- make N moves from State. moves(0, _). moves(N, State1) :- N > 0, move1(State1, State2), N1 is N-1, moves(N1, State2). % move1(State1, State2) -- make 1 move from State1 to reach State 2 move1([peg(X,Y),peg(X1,Y),hole(X2,Y)|State], [hole(X,Y),hole(X1,Y),peg(X2,Y)|State]). move1([peg(X,Y)|State], [hole(X,Y)|State2]) :- Y1 is Y+1, move_up2(X, Y1, State, State2). move1([hole(X,Y),peg(X1,Y),peg(X2,Y)|State], [peg(X,Y),hole(X1,Y),hole(X2,Y)|State]). move1([hole(X,Y)|State], [peg(X,Y)|State2]) :- Y1 is Y+1, move_down2(X, Y1, State, State2). move1([Place|State], [Place|State2]) :- move1(State, State2). % move_up2(X, Y+1, State1, State2) % move up from (X,Y) to (X,Y+2) in State1 to reach State2 % State1 is tail after (X,Y) move_up2(X, Y1, [peg(X,Y1)|State], [hole(X,Y1)|State2]) :- !, Y2 is Y1+1, move_up3(X, Y2, State, State2). move_up2(X, Y1, [hole(X,Y1)|_], _) :- !, fail. move_up2(X, Y1, [Place|State], [Place|State2]) :- move_up2(X, Y1, State, State2). % move_up3(X, Y+2, State1, State2) % move up from (X,Y) to (X,Y+2) in State1 to reach State2 % State1 is tail after (X,Y+1) move_up3(X, Y2, [hole(X,Y2)|State], [peg(X,Y2)|State]) :- !. move_up3(X, Y2, [peg(X,Y2)|_], _) :- !, fail. move_up3(X, Y2, [Place|State], [Place|State2]) :- move_up3(X, Y2, State, State2). % move_down2(X, Y+1, State1, State2) % move down from (X,Y+2) to (X,Y) in State1 to reach State2 % State1 is tail after (X,Y) move_down2(X, Y1, [peg(X,Y1)|State], [hole(X,Y1)|State2]) :- !, Y2 is Y1+1, move_down3(X, Y2, State, State2). move_down2(X, Y1, [hole(X,Y1)|_], _) :- !, fail. move_down2(X, Y1, [Place|State], [Place|State2]) :- move_down2(X, Y1, State, State2). % move_down3(X, Y+2, State1, State2) % move down from (X,Y+2) to (X,Y) in State1 to reach State2 % State1 is tail after (X,Y+1) move_down3(X, Y2, [peg(X,Y2)|State], [hole(X,Y2)|State]) :- !. move_down3(X, Y2, [hole(X,Y2)|_], _) :- !, fail. move_down3(X, Y2, [Place|State], [Place|State2]) :- move_down3(X, Y2, State, State2). % init(-State) -- return initial state of 33-hole solitaire % ordered in row-major order init([ peg(2,0),peg(3,0),peg(4,0), peg(2,1),peg(3,1),peg(4,1), peg(0,2),peg(1,2),peg(2,2),peg(3,2),peg(4,2),peg(5,2),peg(6,2), peg(0,3),peg(1,3),peg(2,3),hole(3,3),peg(4,3),peg(5,3),peg(6,3), peg(0,4),peg(1,4),peg(2,4),peg(3,4),peg(4,4),peg(5,4),peg(6,4), peg(2,5),peg(3,5),peg(4,5), peg(2,6),peg(3,6),peg(4,6)]).