Searching Game Trees
The top-level statement play(Game) :- initialize(Game,Position,Player), display_game(Position,Player), play(Position,Player,Result). initialize(Game,Position,Player) καθορίζει την αρχική θέση Position του παιχνιδιού Game, και Player ο παίχτης που θα αρχίσει. Ένα παιχνίδι είναι μια σειρά εναλλαγών, όπου κάθε εναλλαγή είναι μια επιλογή κίνησης από τον παίχτη, η κίνηση που εκτελείται και ο καθορισμός του επόμενου παίχτη.
Framework for playing games play(Game) :- Play game with name Game play(Game) :- initialize(Game,Position,Player), display_game(Position,Player), play(Position,Player,Result). play(Position,Player,Result) :- game_over(Position,Player,Result), !, announce(Result). play(Position,Player,Result) :- choose_move(Position,Player,Move), move(Move,Position,Position1), display_game(Position1,Player), next_player(Player,Player1), !, play(Position1,Player1,Result).
Choosing the best move Απλός αλγόριθμος που βρίσκει την καλύτερη κίνηση Βρες όλες τις πιθανές καταστάσεις παιχνιδιού (game states) με μια κίνηση. Υπολόγισε τις τιμές των καταστάσεων χρησιμοποιώντας την value(Position,Value) (computes the Value of Position). Επέλεξε την κίνηση που οδηγεί στη θέση με το μεγαλύτερο score. Αυτός ο αλγόριθμος υλοποιείται στο παρακάτω πρόγραμμα evaluate_and_choose(Moves,Position,Record,BestMove) :- Επιλέγει την καλύτερη κίνηση BestMove από ένα σύνολο κινήσεων Moves με βάση την τρέχουσα θέση Position. Record κρατάει την τρέχουσα καλύτερη κίνηση.
Choosing the best move (συνέχεια) evaluate_and_choose([Move|Moves],Position,Record,BestMove) :- move(Move,Position,Position1), % applies a Move to the current % Postion to reach Position1 value(Position1,Value), update(Move,Value,Record,Record1), evaluate_and_choose(Moves,Position,Record1,BestMove). evaluate_and_choose([ ],Position,(Move,Value),Move). update(Move,Value,(Move1,Value1),(Move1,Value1)) :- Value <= Value1. update(Move,Value,(Move1,Value1),(Move,Value)) :- Value > Value1.
Choosing the best move (συνέχεια) Ο παρακάτω κανόνας ενσωματώνει το τελευταίο πρόγραμμα στο γενικό Framework παιχνιδιών: choose_move(Position,computer,Move) :- findall(M,move(Position,M),Moves), evaluate_and_choose(Moves,Position),(nil,-1000),Move). Ο κανόνας move(Position,Move) ισχύει αν η Move είναι μια πιθανή κίνηση από την τρέχουσα θέση.
Choosing the best move with the Minimax Algorithm evaluate_and_choose(Moves,Position,Depth,Flag,Record,BestMove) :- Chooses the BestMove from the set of Moves from the current Position using the minimax algorithm searching Depth ply αhead. Flag indicates if we are currently minimizing or maximizing. Record records the current best move. evaluate_and_choose([Move|Moves],Position,D,MaxMin,Record,Best) :- move(Move,Position,Position1), minimax(D,Position1,MaxMin,MoveX,Value), update(Move,Value,Record,Record1), evaluate_and_choose(Moves,Position,D,MaxMin,Record1,Best). evaluate_and_choose([ ],Position,D,MaxMin,Record,Record).
Choosing the best move with the Minimax Algorithm (συνέχεια) minimax(0,Position,MaxMin,Move,Value) :- value(Position,V), Value is V * MaxMin. minimax(D,Position,MaxMin,Move,Value) :- D > 0, findall(M,move(Position,M),Moves), D1 is D – 1, MinMax is –MaxMin, evaluate_and_choose(Moves,Position,D1,MinMax,(nil,-1000),(Move,Value)). update(Move,Value,(Move1,Value1),(Move1,Value1)) :- Value <= Value1. update(Move,Value,(Move1,Value1),(Move,Value)) :- Value > Value1.
Choosing a move using minimax with alpha-beta pruning evaluate_and_choose(Moves,Position,Depth,Alpha,Beta,Record,BestMove) :- Chooses the BestMove from the set of Moves from the current Position using the minimax algorithm with alpha-beta cutoff searching Depth ply ahead. Alpha and Beta are the parameters of the algorithm. Record records the current best move. evaluate_and_choose([Move|Moves],Position,D,Alpha,Beta,Move1,BestMove):- move(Move,Position,Position1), alpha_beta(D,Position1,Alpha,Beta,MoveX,Value), Value1 is -Value, cutoff(Move,Value1,D,Alpha,Beta,Moves,Position,Move1,BestMove). evaluate_and_choose([ ],Position,D,Alpha,Beta,Move,(Move,Alpha)).
Choosing a move using minimax with alpha-beta pruning (συνέχεια) alpha_beta(0,Position,Alpha,Beta,Move,Value) :- value(Position,Value). alpha_beta(D,Position,Alpha,Beta,Move,Value) :- findall(M,move(Position,M),Moves), Alpha1 is –Beta, Beta1 is –Alpha, D1 is D-1, evaluate_and_choose(Moves,Position,D1,Alpha1,Beta1,nil,i(Move,Value)).
Choosing a move using minimax with alpha-beta pruning (συνέχεια) cutoff(Move,Value,D,Alpha,Beta,Moves,Position,Move1,(Move,Value)) :- Value >= Beta. cutoff(Move,Value,D,Alpha,Beta,Moves,Position,Move1,BestMove) :- Alpha < Value, Value < Beta, evaluate_and_choose(Moves,Position,D,Value,Beta,Move1,BestMove). cutoff(Move,Value,D,Alpha,Beta,Moves,Position,Move1,BestMove) :- Value <= Alpha, evaluate_and_choose(Moves,Position,D,Alpha,Beta,Move1,BestMove).