wtorek, 22 maja 2012

Szachy i komputery (6)


Jak działa silnik szachowy

Silniki szachowe są rozwijane od dziesiątków lat, ale dopiero od kilku ich siła gry pozwala im rywalizować z najlepszymi szachistami. Ma na to oczywiście wpływ wzrost wydajności sprzętu komputerowego i rosnąca efektywność kodu, ale przede wszystkim silniki mają coraz większą wiedzę, zwłaszcza o strategii, i coraz lepiej naśladują człowieka w ocenie pozycji i ruchów-kandydatów.
Gdy Deep Blue ponad dekadę temu pokonał Kasparowa, był zdolny przetworzyć około 200 milionów pozycji na sekundę, czyli kilkadziesiąt milionów razy więcej niż jego ludzki przeciwnik. W pierwszej partii przegrał, przegrałby też ze sto razy wolniejszym tandemem współczesnego programu i nowoczesnego peceta. Dlaczego?

Jak silnik widzi pozycję

Najczęściej stosowaną w silnikach szachowych metodą przedstawiania pozycji (nie mylić z kodem pozycji, FEN) są plansze bitowe (ang. bit board lub bitboard). Plansza bitowa to cyfrowy obraz wycinka pozycji, pozwalający silnikom (i procesorom) bardzo efektywnie przechowywać i przetwarzać pozycje przy użyciu prostych operacji logicznych. Zestaw takich dających się porównywać plansz tworzy kompletną pozycję. W szachach planszę bitową tworzy 64-bitowe słowo (szachownica ma 64 pola), w którym poszczególne znaki określają pola od A1 do H8. Plansza odnosi się do wybranego aspektu pozycji, na przykład pól dostępnych białemu hetmanowi, pól zajętych przez czarne piony lub kilku centralnych pól. (Każdy typ bierek, z rozróżnieniem kolorów, ma własną planszę). Z reguły planszom towarzyszy szereg zmiennych (na przykład określających prawo do roszady albo obecność przechodniego piona) i stałych (na przykład odpowiadających wybranej linii).
Stosuje się też „obracanie” plansz bitowych (o 45, 90 i 315 stopni), pozwalające efektywniej przetwarzać niektóre ruchy figur, na przykład po przekątnych.
Plansze bitowe mogą być łączone z listami bierek, które w początkach komputeryzacji były jedynym dostępnym (ze względu na ograniczenia sprzętu) sposobem przedstawiania pozycji, w celu zwiększenia efektywności niektórych operacji. Taka lista po prostu zawiera lokalizację wszystkich bierek.
Pozycje mogą być także przedstawiane w postaci tablic, na przykład 8×8 lub jednowymiarowej o długości 64. W takiej tablicy czarna wieża może być oznaczona na przykład liczbą –5, a biały pion – jedynką. Stosuje się także tablice o większych rozmiarach, na przykład 12×12 lub 16×16, aby efektywniej sprawdzać poprawność posunięć (czy pole docelowe znajduje się na szachownicy). Inną odmianą metody tablicowej jest 0x88.
Pozostałe metody to strumieniowa i Huffmana.

Sposób liczenia wariantów i oceny pozycji

Maszyna, czy to superkomputer wykorzystujący metodę brutalnej siły (ang. brute force), czy program naśladujący sposób myślenia człowieka, nie może wyjść poza algorytmy, jest pozbawiona wyobraźni, doświadczenia, skojarzeń. Moc obliczeniowa dzisiejszych komputerów wciąż jest dalece niewystarczająca w stosunku do liczby pozycji powstających po każdym posunięciu. Jeśli w danej pozycji białe mogą wykonać 30 dozwolonych posunięć, po każdym z nich czarne mają 30 dozwolonych odpowiedzi, a po każdej z nich także białe mają 30 odpowiedzi... Po kilku posunięciach liczba pozycji do oceny idzie w miliardy, a przecież nawet słaby amator liczy na więcej niż trzy – cztery do przodu... Metoda brutalnej siły, polegająca w czystej postaci na tym, że silnik w danej pozycji stara się policzyć całe wynikające z niej drzewo wariantów, aż do założonej głębi, czyli wszystkie możliwe posunięcia, wszystkie możliwe odpowiedzi na każde z posunięć, wszystkie możliwe odpowiedzi na każdą możliwą odpowiedź i tak dalej – nie wystarczy.

Kilka terminów spod maski

Jest wiele technik wykorzystywanych przy wybieraniu i liczeniu wariantów. W następnym podrozdziale pokażę, jak liczenie wariantów wygląda w praktyce, najpierw jednak w wielkim skrócie przedstawię kilka pojęć, które stoją za działaniem silnika.
algorytmie min-max, podstawie obliczeń szachowych, chodzi o minimalizowanie maksymalnych możliwych strat. Przyjmuje się, że obaj gracze mają tę samą wiedzę o pozycji (pełną informację), suma gry wynosi zero, czyli zysk jednego gracza równa się stracie (z odwróconym znakiem) drugiego, i gracze starają się zarówno maksymalizować swoje zyski (grać najsilniejsze posunięcia), jak i minimalizować straty (grać posunięcia najbardziej oddalające porażkę). W skrócie: ruch x białych jest najlepszy (nawet jeśli prowadzi do porażki) po uwzględnieniu najlepszych odpowiedzi czarnych, a najlepsza odpowiedź czarnych na ruch x jest wybierana po uwzględnieniu możliwych odpowiedzi białych – i tak dalej. Oczywiście algorytm ten nie uwzględnia praktycznej strony gry z punktu widzenia człowieka: blefowania, zakładania pułapek, tworzenia praktycznych problemów, komplikowania pozycji, gdy przeciwnik jest w niedoczasie, itp.
Algorytm („odcinanie”) alfa-beta (ang. alpha-beta pruning) pozwala ograniczyć liczbę ocenianych wariantów. Chodzi w nim o to, aby nie liczyć wariantu po znalezieniu lepszego. Nazwa pochodzi od wartości alfa i beta dla wybranej pozycji, które oznaczają, odpowiednio, najmniejszy możliwy i największy możliwy zysk gracza A (będącego na posunięciu). Wariant jest „odcinany”, gdy jego wartość beta spadnie poniżej bieżącej wartości alfa, co oznacza, że istnieje przynajmniej jedno lepsze rozwiązanie (już znane, o bieżącej wartości alfa). Innymi słowy, jeśli w danym wariancie gracz B przy najlepszej grze uniknie pozycji o wartościach beta większych od alfa, silnik przerywa analizę wariantu prowadzącego do tej pozycji.
Pogłębianie iteracyjne (ang. iterative deepening depth-first search, IDDFS) to niezwykle ważny sposób na zwiększenie efektywności algorytmu alfa-beta, bo pozwala liczyć warianty w kolejności bliskiej optymalnej: od najlepiej ocenianego do wstępnie odrzuconych, i to na każdej kolejnej głębokości drzewa. W skrócie: jest tworzona lista posunięć według ich oceny, a następnie posunięcia są w tej kolejności analizowane. Gdy silnik osiąga następną głębokość, ponownie analizuje warianty od „najlepszego” do „najgorszego”, oczywiście w nowej kolejności (choć nie musi się ona zmienić).
Killer heuristic zwiększa efektywność liczenia wariantów w kolejnych iteracjach przez sprawdzanie w danej podgałęzi drzewa w pierwszej kolejności tych posunięć, które spowodowały odcięcie pozostałych wariantów w innej pozycji na tej samej głębokości drzewa (te posunięcia to tzw. killer moves). Jeśli odcięcie najlepiej ocenianego wariantu nastąpiło dzięki znalezieniu nowego ruchu, zastępuje on wcześniejszy „killer move” (lub jeden z kilku przechowywanych przez silnik).
Heurystyka pustych posunięć (ang. null-move heuristic) jest oparta na założeniu, że jeśli rozpatrywana pozycja nie byłaby gorsza od innych ocenionych pozycji nawet w przypadku, gdyby strona na posunięciu zrezygnowała z wykonania ruchu (hipotetycznie, bo to byłoby wbrew regułom gry), to jest duża szansa, że to właśnie w niej zostanie znaleziony wariant odcinający pozostałe. Tak więc silnik pomija posunięcie, oblicza warianty w tak powstałej pozycji, a jeśli nastąpi odcięcie wcześniej ocenionych gałęzi, wykonuje obliczenia już bez pomijania żadnych ruchów.
Zmniejszanie głębi obliczania słabszych posunięć (ang. late move reduction) opiera się na założeniu, że skoro to warianty najlepiej oceniane przy danej głębi przeszukiwania drzewa mają największe szanse odciąć pozostałe, ogólna efektywność obliczeń zwiększy się, jeśli to tym najlepiej ocenianym wariantom przyporządkuje się więcej czasu procesora (policzy się je głębiej).
Niezwykle ważne jest zmniejszenie liczby obliczeń przez uniknięcie sprawdzania już ocenionych pozycji, do których prowadzi więcej niż jedna kolejność posunięć. Umożliwiają to tablice transpozycji (ang.transposition table), będące formą tablic mieszających (ang. hash table). Typowy rozmiar tablicy transpozycji na współczesnym domowym pececie to 128–512 MB (najnowsze wpisy wypierają najstarsze). Tablice te zawierają ocenę już policzonych pozycji, a zatem, co najważniejsze – także wynikających z niej wariantów, a silnik, zanim oceni nową, sprawdza w tablicy transpozycji, czy już nie pojawiła się w analizie. Ponadto jest w nich przechowywana kolejność posunięć w danej pozycji zależnie od przyporządkowanej im oceny.

6 komentarzy:

  1. No Panie Andrzeju chyba mały plagiacik - http://pclab.pl/art34801-5.html. Wypadałoby chociaż napisać, że artykuł ściągnięty z tej strony, a nie podawać się za autora..

    Pozdrawiam,
    Krzysztof Bulski

    OdpowiedzUsuń
  2. Chociaż teraz zobaczyłem, że w pierwszym poście napisał Pan skąd był ściągnięty artykuł i kto jest autorem. Więc z plagiacikiem przesadziłem:)
    Ale moim zdaniem powinien Pan w każdej części artykułu zamieszczać jego autora i źródło strony.

    OdpowiedzUsuń
  3. Na imię mam Krzysztof. Posądzanie mnie o plagiaty jest drobnym nietaktem. Bloga prowadzę kilka lat i nigdy nie podpisałem się pod cudzym tekstem twierdząc, że to ja jestem jego twórcą
    Oczywiście mogę co drugą linijkę publikować link do strony, ale myślę, że dopełniłem wszelkich formalności. Fragmenty są ponumerowane a wnikliwy Czytelnik powinien "dotrzeć" do fragmentu nr 1, gdzie jest autor.
    I jeszcze jedno - artykuł jest ciekawy i może pomóc wielu miłośnikom szachów i komputerów. To był jedyny cel jego kopiowania. Gdybym podał tylko link do strony i nazwisko autora, to każdy by o tym już dawno zapomniał.
    Myślę również, że autor winien być w jakiś sposób usatysfakcjonowany, bo jego opracowanie zostanie szeroko rozpropagowane.
    Tak więc proszę o więcej zaufania do Szacharni i uważniejsze przeglądania bloga.
    Pozdrawiam

    OdpowiedzUsuń
  4. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń
  5. Słowo autor (jest ono obligatoryjne w blogach z rozszerzeniem ...blogsopt.com) oznacza, kto prowadzi bloga.
    Jeśli chodzi o nawigację, to ja też jej nie wymyśliłem, tylko portal.
    Najłatwiej "coś" można znaleźć "zjeżdżając" w dół i po lewej stronie jest pod hasłem "Rozdziały (tematy)" alfabetyczny "spis treści".
    Również pod każdym postem jest taki podpis "rozdziały". Kliknięcie w tym wypadku na "szachy i komputery" spowoduje wyświetlenie wszystkich postów tak podpisanych. Myślę, że aż takie skomplikowane to nie jest. Ja, mimo że jestem tylko dodatkiem do klawiatury, do tego jakoś doszedłem.
    Posądzenie o plagiat wybaczam i proszę czytać Szacharnię.

    OdpowiedzUsuń
  6. Ma pan rację - przepraszam za oskarżenie o plagiat i o pomylenie pana z Andrzejem...

    Jednak dalej obstaje, że na koniec artykułu powinien pan napisać źródło strony i autora artykułu. Po wejściu na artykuł na pana stronie na samym dole wyraźnie wyświetla się autor: Krzysztof Długosz.

    Nawigacja na pana stronie nie jest łatwa i myślę, że mało który czytelnik dojdzie do fragmentu nr 1.

    Artykuł wpadł mi w oko, gdyż sam z niego korzystałem i mocno się zdziwiłem widząc na samym dole tekst "autor: Krzysztof Długosz".

    Pozdrawiam

    OdpowiedzUsuń