Commit ba343175 by Marius Frinken

### minimax solution and uebung06 presentation

parent 71415b29
 % A Tic-Tac-Toe program in Prolog. S. Tanimoto, May 11, 2003. % To play a game with the computer, type % playo. % To watch the computer play a game with itself, type % selfgame. % % original at https://courses.cs.washington.edu/courses/cse341/03sp/slides/PrologEx/tictactoe.pl.txt % Predicates that define the winning conditions: win(Board, Player) :- rowwin(Board, Player). win(Board, Player) :- colwin(Board, Player). win(Board, Player) :- diagwin(Board, Player). rowwin(Board, Player) :- Board = [Player,Player,Player,_,_,_,_,_,_]. rowwin(Board, Player) :- Board = [_,_,_,Player,Player,Player,_,_,_]. rowwin(Board, Player) :- Board = [_,_,_,_,_,_,Player,Player,Player]. colwin(Board, Player) :- Board = [Player,_,_,Player,_,_,Player,_,_]. colwin(Board, Player) :- Board = [_,Player,_,_,Player,_,_,Player,_]. colwin(Board, Player) :- Board = [_,_,Player,_,_,Player,_,_,Player]. diagwin(Board, Player) :- Board = [Player,_,_,_,Player,_,_,_,Player]. diagwin(Board, Player) :- Board = [_,_,Player,_,Player,_,Player,_,_]. % Helping predicate for alternating play in a "self" game: other(x,o). other(o,x). game(Board, Player) :- win(Board, Player), !, write([player, Player, wins]). game(Board, Player) :- other(Player,Otherplayer), move(Board,Player,Newboard), !, display(Newboard), game(Newboard,Otherplayer). move([b,B,C,D,E,F,G,H,I], Player, [Player,B,C,D,E,F,G,H,I]). move([A,b,C,D,E,F,G,H,I], Player, [A,Player,C,D,E,F,G,H,I]). move([A,B,b,D,E,F,G,H,I], Player, [A,B,Player,D,E,F,G,H,I]). move([A,B,C,b,E,F,G,H,I], Player, [A,B,C,Player,E,F,G,H,I]). move([A,B,C,D,b,F,G,H,I], Player, [A,B,C,D,Player,F,G,H,I]). move([A,B,C,D,E,b,G,H,I], Player, [A,B,C,D,E,Player,G,H,I]). move([A,B,C,D,E,F,b,H,I], Player, [A,B,C,D,E,F,Player,H,I]). move([A,B,C,D,E,F,G,b,I], Player, [A,B,C,D,E,F,G,Player,I]). move([A,B,C,D,E,F,G,H,b], Player, [A,B,C,D,E,F,G,H,Player]). display([A,B,C,D,E,F,G,H,I]) :- write([A,B,C]),nl,write([D,E,F]),nl, write([G,H,I]),nl,nl. selfgame :- game([b,b,b,b,b,b,b,b,b],x). % Predicates to support playing a game with the user: x_can_win_in_one(Board) :- move(Board, x, Newboard), win(Newboard, x). % The predicate orespond generates the computer's (playing o) reponse % from the current Board. % move and win orespond(Board,Newboard) :- move(Board, o, Newboard), win(Newboard, o), !. % a draw occurs orespond(Board,Newboard) :- not(member(b,Board)), !, write('Cats game!'), nl, Newboard = Board. % minimax has to be calculated % this function computes the list of possible moves, % calculates the Utility value for each element in this list via minimap % and returns the board with the largest one (by sorting a List of Tuples (Utility,Board)) orespond(Board,Newboard) :- show_possiblemoves(Board,o,L), maplist(minimaxwrap, L, ListofTuples), predsort(sort_boards,ListofTuples,[(_,Newboard)|_]). % the wrapper for minimax, used to bind a board to an utilty value minimaxwrap(Board,(Utility, Board)):- minimax(x,Board,Utility). % minimax(Player,Board,Utility value) % case: draw minimax(_,Board,0):- not(win(Board,o)), not(win(Board,x)), not(member(b,Board)). % case: o wins minimax(_,Board,100):- win(Board,o). % case: x wins minimax(_,Board,-100):- win(Board,x). % case: o's turn minimax(o,Board,Utility):- show_possiblemoves(Board,o,L), maplist(minimax(x),L,Utilities), max_list(Utilities,Utility). % case: x's turn minimax(x, Board,Utility):- show_possiblemoves(Board,x,L), maplist(minimax(o),L,Utilities), min_list(Utilities,Utility). %% HELPER FUNCTIONS % compare function for a tuple (Utilty,Board) sort_boards(Delta, (C1,_),(C2,_)):- C1==C2; compare(Delta,C2,C1). %finds all possible moves for Player from Board and stores it into a ListOfBoards show_possiblemoves(Board, Player, ListOfBoards):- findall(Newboard, move(Board,Player,Newboard),ListOfBoards). %% END HELPER FUNCTIONS % The following translates from an integer description % of x's move to a board transformation. xmove([b,B,C,D,E,F,G,H,I], 1, [x,B,C,D,E,F,G,H,I]). xmove([A,b,C,D,E,F,G,H,I], 2, [A,x,C,D,E,F,G,H,I]). xmove([A,B,b,D,E,F,G,H,I], 3, [A,B,x,D,E,F,G,H,I]). xmove([A,B,C,b,E,F,G,H,I], 4, [A,B,C,x,E,F,G,H,I]). xmove([A,B,C,D,b,F,G,H,I], 5, [A,B,C,D,x,F,G,H,I]). xmove([A,B,C,D,E,b,G,H,I], 6, [A,B,C,D,E,x,G,H,I]). xmove([A,B,C,D,E,F,b,H,I], 7, [A,B,C,D,E,F,x,H,I]). xmove([A,B,C,D,E,F,G,b,I], 8, [A,B,C,D,E,F,G,x,I]). xmove([A,B,C,D,E,F,G,H,b], 9, [A,B,C,D,E,F,G,H,x]). xmove(Board, _, Board) :- write('Illegal move.'), nl. % The 0-place predicate playo starts a game with the user. playo :- explain, playfrom([b,b,b,b,b,b,b,b,b]). explain :- write('You play X by entering integer positions followed by a period.'), nl, display([1,2,3,4,5,6,7,8,9]). playfrom(Board) :- win(Board, x), write('You win!'). playfrom(Board) :- win(Board, o), write('I win!'). playfrom(Board) :- read(N), xmove(Board, N, Newboard), display(Newboard), orespond(Newboard, Newnewboard), display(Newnewboard), playfrom(Newnewboard). % The 0-place predicate playo2 starts a game with the AI. playo2 :- explain, playfrom2([b,b,b,b,b,b,b,b,b]). playfrom2(Board) :- win(Board, x), write('You win!'). playfrom2(Board) :- win(Board, o), write('I win!'). playfrom2(Board) :- orespond(Board, Newboard), display(Newboard), (not(member(b,Newboard)), write('Cats game!'); win(Newboard, x), write('You win!'); win(Newboard, o), write('I win!'); read(N), xmove(Newboard, N, Newnewboard), display(Newnewboard), playfrom2(Newnewboard)).