• Nie Znaleziono Wyników

Przedstawimy teraz ten algorytm w bardziej for- malnej postaci. Korzystać będziemy w tym opisie z następujacych funkcji i stałych

N/A
N/A
Protected

Academic year: 2021

Share "Przedstawimy teraz ten algorytm w bardziej for- malnej postaci. Korzystać będziemy w tym opisie z następujacych funkcji i stałych"

Copied!
8
0
0

Pełen tekst

(1)

3. MINIMAX.

Bardzo wygodną strukturą danych pozwalającą reprezentować stan i przebieg gry (szczególnie gier dwuosobowych) jest drzewo. Węzły drzewa reprezentują stan gry po wykonaniu ruchu przez jednego z graczy. Gałąź przechodząca od węzła x do węzła y oznacza, że przyjmując za stan bieżący stan x jeden z graczy może wybrać taki ruch, który spowoduje, że stan gry (czyli na przykład sytuacja na planszy) będzie równy y.

Poziomy drzewa reprezentują wszystke ruchy, jakie może wykonać jeden z graczy w danej turze. Każdy węzeł ma przypisaną liczbę wyrażającą wartość reprezentowanej pozycji z punktu widzenia gracza, dla którego zaczęliśmy konstruować drzewo; w poniższym przykładowym drzewie graczem tym jest A.

Rysunek 1: Drzewo obrazujące przebieg gry.

Naszym zadaniem jest teraz wyznaczenie ścieżki prowadzącej od stanu począt- kowego do tego ze stanów końcowych, który daje nam pewność, że nie zdobędziemy mniej jak x punktów, przy czym x jest największą z najmniejszych wartości jakie możemy zdobyć. Już wyjaśniam o co chodzi...

Rozważmy następujace drzewo gry (każdy stan oceniany jest od -10 - przegrana gracza A do +10 - wygrana gracza A)

(2)

Rysunek 2: Drzewo gry - ruchy gracza A.

Będąc w stanie 1 i mając wykonać ruch gracz A z pewnością wybierze przj- ście (czyli wykona ruch powodujący zmianę na planszy) do stanu 2, gdyż stan ten zapewnia mu największą ilość punktów. Rozwińmy jednak to drzewo o jeden dodat- kowy poziom, który powstanie po wykonaniu ruchu przez gracza B (wszystkie stany oceniane są z punktu widzenia gracza A).

Rysunek 3: Drzewo gry. Pierwszy poziom ruchy gracza A; drugi - ruchy gracza B.

Otórz w odpowiedzi na nasz ruch r2 gracz B może odpowiedzieć ruchami r5, r6 i r7. Zakładając, że gracz B stosuje kryterium zdrowego rozsądku, to znaczy wybiera najkorzystniejszy dla siebie ruch, wykona on ruch r6 a to oznacza dla gracza A zdecydowane pogorszenie poprzedniej świetnej sytuacji. Zdecydowanie lepiej dla A wykonać taki ruch, który zagwarantuje nam, że po odpowiedzi gracza B stracimy jak najmniej. Ruchem tym jest r3. W najgorszym razie znajdziemy się bowiem w sytuacji ocenianej na -2. Owszem, wybierając r2 moglibyśmy znaleźć się w stanie ocenianym na 9, ale pamiętajmy, że B nie gra przeciw sobie więc raczej ruchu r5 nie wykona.

Przykład ten pokazuje jeszcze jedną rzecz. Bardzo istotna jest głębokość analizy, czyli wysokość drzewa. Najlepiej, jeśli możnaby wygenerować całe drzewo, co dla większości gier jest... niemożliwe. Problem stanowi tutaj czas potrzebny na realizację takiego zadania (tj. generowania i przeszukiwania drzewa). Dla prostych gier, jak ta z zadania, wystarczają 2-3 poziomy.

Przyjmijmy więc, że nasze drzewo ma kilka poziomów odpowiadających kilku tu- rom w pewnej grze. Jak zatem wybrać odpowiednią ścieżkę. Analizę drzewa rozpocz-

(3)

niemy od jego liści i posuwać będziemy się w kierunku korzenia. Liściom przypisjemy wartości gry odpowiadajęce reprezentowanym przez nie stanom. Dla pozostałych wę- złów powstałych w wyniku ruchu gracza B będzie to max z wartości oceny dzieci, natomiast dla węzłów odpowiadających ruchowi gracza A min z wartości oceny dzie- ci (max i min liczone jest osobno dla każdego węzła).

Rozważmy poniższe drzewo gry.

Rysunek 4: Drzewo gry.

Postępując zgodnie z powyższym opisem rozpoczynamy jego analizę od liści (wę- złów o numerach 11-18). Każdemu z nich przypiszemy wartość reprezentowanego przez niego stanu gry. Stąd nasze drzewo przyjmie postać: Wartości dla węzłów z tury II odpowiadających ruchowi gracza A będą minimami z wartości przechowy- wanych przez dzieci. Stąd drzewo przyjmie postać:

Wartości dla węzłów z tury II odpowiadających ruchowi gracza A będą minimami z wartości przechowywanych przez dzieci. Stąd drzewo przyjmie postać:

(4)

Wartości dla węzłów odpowiadających ruchowi gracza B w turze I to maksima z wartości ich dzieci, czyli

Wartości dla węzłów odpowiadających ruchowi gracza A w turze I to ponownie minima z wartości ich dzieci, czyli

(5)

Ostatecznie, do korzenia zwracamy maxymalną wartości jego dzieci, czyli -2:

Jeśli więc wykonamy ruch, który spowoduje, że znajdziemy się w stanie 2 to w najgorszym przypadku znajdziemy się w stanie ocenianym na -2 (przy założeniu, że nie gramy przeciw sobie.

Przedstawimy teraz ten algorytm w bardziej for- malnej postaci. Korzystać będziemy w tym opisie z następujacych funkcji i stałych

• MOVEGEN(Position, Player) - funkcja ta generuje wszystkie ruchy jakie mo- że wykonać gracz Player traktując stan Position jako stan początkowy. Zwra- ca ona listę, w której każda pozycja zawiera nowy stan wraz z opisem ru- chu, który do niego doprowadził. Na przykład MOVEGEN(1,B) daje listę {{3, r3}, {4, r4}}.

• ASSESS(Position,Player) - funkcja, która ocenia stan Position według kryte- riów gracza Palyer, na przykład ASSESS(3,B)=-2.

(6)

• Ponieważ jest to algorytm rekursywny zatem istotne jest przerwanie w pewnym momencie ciągu „samowywołań”. Uczynimy tak, gdy funkcja zwróci wartości TRUE.

• Stałe oznaczają największą i najmniejszą wartość jaką może zwócić funkcja ASSESS.

Algorytm Minimax

MINIMAX (Position, Depth, Player)

1. Jeśli DEEP_ENOUGH(Position,Depth)=TRUE to zwróć strukturę VALUE:=ASSESS(Position,PLAYER_A)

PATH:=NULL

2. W przeciwnym razie wygeneruj kolejny poziom drzewa wywołując funkcję MOVGEN(Position, PLAYER_B) jeśli Player=PLAYER_A

MOVGEN(Position, PLAYER_A) jeśli Player=PLAYER_B a zwrócone przez nią wartości zapisz w SUCCESSORS.

3. Jeśli SUCCESSORS=NULL, oznacz to, że nie ma już więcej możliwych do wykonania ruchów. Zwracamy zatem strukturę

VALUE:=ASSESS(Position,PLAYER_A) PATH:=NULL

4. W przeciwnym razie jeśli

a) Player=PLAYER_A to wykonaj:

PATH:=NULL

VALUE:=THE_BEST;

Dla każdego stanu S z SUCCESSORS będącego wynikiem ruchu R wykonaj:

(T_VALUE,T_PATH):=MINIMAX(S,Depth+1,PLAYER_B) Jeśli VALUE > T_VALUE to

VALUE:=T_VALUE PATH:=R+T_PATH

b) Player=PLAYER_B to wykonaj:

PATH:=NULL

VALUE:=THE_WORSE;

Dla każdego stanu S z SUCCESSORS będącego wynikiem ruchu R wykonaj:

(T_VALUE,T_PATH):=MINIMAX(S,Depth+1,PLAYER_A) Jeśli VALUE < T_VALUE to

VALUE:=T_VALUE PATH:=R+T_PATH 5. Zwróć strukturę

VALUE PATH

(7)

Algorytm został przedstawiony wyjątkowo nie w postaci ogólnej aby można było zauważyć momenty wybierania wartości minimalnej lub maksymalne. Dodatkowo jest to postać odpowiednia dla gracza A.

Chcąc użyć go dla gracza B należy zamienić wystąpienia PLAYER_A i PLAYER_B na PLAYER_B i PLAYER_A.

Pozostał jeszcze technicznych "drobiazg": jak TO wywolac?

Popronuje tak:

1. Generujemy wszystkie możliwe ruchy dla PLAYER_A jakie może wykonać dla bieżącego układu planszy.

2. Dla każdego ruchu wygenerowanego w poprzednik kroku wywołujemy MINIMAX(kolejny_wygenerowany_ruch,1,PLAYER_A).

3. Z wartości zwróconych przez wszystkie wywolanie minimax-u wybieramy największą.

Zadanie.

Zadanie tym razem polega na napisaniu gry, w której poczynaniami jednego z graczy steruje komputer. Kolejny ruch do wykonania przez komputer znajdowany ma być oczywiście w oparciu o przedstawiony algorytm. Zasady gry są następujace

1. Gramy na planszy podobnej do planszy szachowej. Rozmiar dowolny, ale nie mniejszy niż 8x8 (nie musi to być kwadrat).

2. Wszystkie pola mają jednakowy kolor.

3. Dwóch graczy posługuje się pionkami dwóch różnych kolorów.

4. Na każdym polu może stać tylko jeden pionek.

5. Początkowo na planszy każdy z graczy ma po jednym pionku; ustawione one są w przeciwległych rogach planszy.

6. Sąsiedztwem pionka nazywamy wszystkie 8 pól, które bezpośrednio do niego przylegają (krzyżyki na rysunku).

7. Możliwe są dwa rodzaje ruchów:

(8)

• Rozmnożenie: przejście z pola bieżącego na sąsiednie polegające na po- stawieniu na sąsiednim polu pionka.

• Przeskok: przejście z pola bieżącego na pole oddalone o 1 pole.

8. Ruch możliwy jest w pionie i poziomie (jak ktoś chce może także dodać skosy).

9. Podczas fazy ruchu jednego z graczy wszystkie pionki przeciwnika, które znaj- dą się w otoczeniu przemieszczonego pionka zmieniają kolor na kolor wykonu- jącego ruch.

10. Celem gry jest zdobycie przewagi w postaci większej liczby pionków na plan- szy. Gra toczy się do momentu zapełnienia wszystkich pól na planszy lub niemożności wykonania posuniecia przez jednego z graczy.

Cytaty

Powiązane dokumenty

W tafli jeziora odbija się przelatujący ptak, widać także leżący na dnie kamień. Pozorna głębokość, na jakiej widać 1) odbicie ptaka, 2) kamień, jest w stosunku do

Równoważność jest prawdziwa wyłącznie wtedy, gdy oba jej człony. mają tę

- potrafię scharakteryzować kolejne etapy podboju Europy przez Adolfa Hitlera do sierpnia 1939 r. Obejrzyjcie film

Tematy z tego działu to Odrodzenie Rzeczypospolitej, Walka o granicę wschodnią, Kształtowanie się granicy zachodniej i południowej..

- potrafię wymienić przyczyny przejęcia władzy przez Adolfa Hitlera Temat i cel lekcji zapiszcie w zeszycie do historii.. Obejrzyjcie film

Rzeczpospolita na arenie międzynarodowej, Polska w przededniu II wojny światowej..

- potrafię ocenić skutki polityki gospodarczej ZSRS Temat i cel lekcji zapiszcie w zeszycie do historii.. Obejrzyjcie film

Wykorzystując funkcje z grupy BD.______ oblicz ile jest kobiet, ilu mężczyzn, jaką średnią minimalną i maksymalną liczbę punktów w sumie uzyskali mężczyźni a jaką