Commit ba343175 authored by Marius Frinken's avatar 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)).
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment