/* Race to 21 game in Picat. From "Thinking as Computation", page 211ff. """ There are 21 chips on a table. Players take turns removing either one or two chips. The player removing the last chip wins. """ This program uses the module gameplayer_v3. This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import gameplayer_v3. main => go. /* The first player is max and the initial state is 21 Player max chooses move 1 and the new state is 20 Player min chooses move 2 and the new state is 18 Player max chooses move 1 and the new state is 17 Player min chooses move 2 and the new state is 15 Player max chooses move 1 and the new state is 14 Player min chooses move 2 and the new state is 12 Player max chooses move 1 and the new state is 11 Player min chooses move 2 and the new state is 9 Player max chooses move 1 and the new state is 8 Player min chooses move 2 and the new state is 6 Player max chooses move 1 and the new state is 5 Player min chooses move 2 and the new state is 3 Player max chooses move 1 and the new state is 2 Player min chooses move 2 and the new state is 0 -------- The winner is min */ go ?=> play_user(nobody), % automatic play nl, % fail, nl. go => true. /* Winning moves for each value of N=1..21 [n = 21,no_winning_move] [n = 20,p = max,m = 2] [n = 19,p = max,m = 1] [n = 18,no_winning_move] [n = 17,p = max,m = 2] [n = 16,p = max,m = 1] [n = 15,no_winning_move] [n = 14,p = max,m = 2] [n = 13,p = max,m = 1] [n = 12,no_winning_move] [n = 11,p = max,m = 2] [n = 10,p = max,m = 1] [n = 9,no_winning_move] [n = 8,p = max,m = 2] [n = 7,p = max,m = 1] [n = 6,no_winning_move] [n = 5,p = max,m = 2] [n = 4,p = max,m = 1] [n = 3,no_winning_move] [n = 2,p = max,m = 2] [n = 1,p = max,m = 1] Note: player max has no chance against against the algorithmic min player: min always draw so max have to get the 'no_winning_move' positions. */ go2 ?=> member(N,21..-1..1), if win_move(N,P,M) then println([n=N,p=P,m=M]) else println([n=N,no_winning_move]) end, fail, nl. go2 => true. /* Play as max against the computer. */ go3 ?=> play_user(max), nl. go3 => true. % % This is the Prolog definition of the game Race to 21. % player(max). player(min). % The two players. % Player Max goes first. initial_state(21,max). game_over(0,max,min). % If it is Max's turn to play, game_over(0,min,max). % then Min wins, and vice versa. legal_move(OldState,_,Move,NewState) :- small_number(Move), % A move is a small number. OldState >= Move, NewState is OldState - Move. small_number(1). % A small number is either small_number(2). % the number 1 or 2. % small_number(3). % TEST write_state(S) => nl, print(" "), print(S), nl.