Kapitola 23: AI v praxi 5 – Herní inteligence

Jak naučit počítač hrát šachy, piškvorky nebo Go? Počítač nehraje intuicí. Počítač počítá. Představuje si budoucnost. "Když já zahraju sem, on zahraje tam, a pak já..." Tímto způsobem si v hlavě staví obrovský strom možností a hledá cestu k vítězství. V této kapitole naučíme Prolog hrát piškvorky, a to tak, že ho jen tak neporazíte.

23.1 Herní strom a Minimax

Základem herní AI je algoritmus zvaný Minimax.

HERNÍ STROM (GAME TREE) Graf, kde každý uzel je stav hry (rozestavení figurek) a hrany jsou možné tahy. Kořen je současný stav, listy jsou konce hry (výhra/prohra).
MINIMAX Algoritmus pro hry dvou hráčů. Předpokládá, že já chci maximalizovat svůj zisk (MAX) a soupeř chce můj zisk minimalizovat (MIN). Počítač hledá tah, který vede k nejlepšímu výsledku, i když soupeř hraje perfektně.
Piškvorky a myšlenky robota
Obrázek 23.1: Robot hraje piškvorky a vizualizuje si herní strom, aby našel nejlepší tah.

23.2 Piškvorky (Tic-Tac-Toe) – Strategie

Pro jednoduché piškvorky 3x3 nemusíme stavět celý strom (i když bychom mohli). Stačí nám sada chytrých pravidel seřazených podle priority:

  1. Vítězství: Pokud můžu vyhrát teď hned, udělám to.
  2. Blokování: Pokud soupeř může vyhrát v příštím tahu, musím mu to zkazit.
  3. Střed: Pokud je volný střed, obsadím ho (strategicky nejlepší pole).
  4. Rohy/Strany: Pokud nic jiného, obsadím roh nebo stranu.
  5. Náhodný tah: Pokud nic jiného, zahraju kamkoliv.
% Reprezentace desky: Seznam 9 prvků [1,2,3, 4,5,6, 7,8,9]
% Prázdné pole je proměnná nebo speciální atom 'e' (empty).
% Hráč je 'x', počítač je 'o'.

% --- Výherní kombinace ---
% Řádky
vyhra([H,H,H, _,_,_, _,_,_], H).
vyhra([_,_,_, H,H,H, _,_,_], H).
vyhra([_,_,_, _,_,_, H,H,H], H).
% Sloupce
vyhra([H,_,_, H,_,_, H,_,_], H).
vyhra([_,H,_, _,H,_, _,H,_], H).
vyhra([_,_,H, _,_,H, _,_,H], H).
% Diagonály
vyhra([H,_,_, _,H,_, _,_,H], H).
vyhra([_,_,H, _,H,_, H,_,_], H).

% --- Pomocné predikáty ---
% Zjistí, zda je pole prázdné
je_volny(Deska, Index) :-
    nth1(Index, Deska, e).

% Zahraje na dané pole
zahraj(Deska, Index, Hrac, NovaDeska) :-
    nth1(Index, Deska, e, Zbytek), % Najdi prázdné pole a odstraň ho
    nth1(Index, NovaDeska, Hrac, Zbytek). % Vlož na stejné místo hráče

% Najde možný tah pro daného hráče
najdi_tah(Deska, Hrac, NovaDeska) :-
    between(1, 9, Index), % Zkus indexy 1 až 9
    je_volny(Deska, Index),
    zahraj(Deska, Index, Hrac, NovaDeska).

% --- Strategie počítače (prioritní pravidla) ---

% 1. Zkus vyhrát
tah_pocitace(Deska, NovaDeska) :-
    najdi_tah(Deska, o, NovaDeska), % Zkus dát 'o' někam
    vyhra(NovaDeska, o), !.         % Pokud to vede k výhře, BEREME TO a končíme (!).

% 2. Zabraň prohře (blokuj soupeře)
tah_pocitace(Deska, NovaDeska) :-
    najdi_tah(Deska, x, TestDeska), % Co by zahrál soupeř ('x')?
    vyhra(TestDeska, x),            % Vyhrál by tím?
    % Pokud ano, musíme zahrát na TO SAMÉ místo my ('o')
    zablokuj(Deska, TestDeska, NovaDeska), !.

% Pomocný predikát pro zablokování
zablokuj(Deska, TestDeska, NovaDeska) :-
    % Najdi rozdíl mezi Deska a TestDeska (to je tah soupeře)
    nth1(Index, Deska, e),
    nth1(Index, TestDeska, x),
    zahraj(Deska, Index, o, NovaDeska). % Zahraj tam 'o'

% 3. Obsaď střed (index 5)
tah_pocitace(Deska, NovaDeska) :-
    je_volny(Deska, 5),
    zahraj(Deska, 5, o, NovaDeska), !.

% 4. Obsaď roh (indexy 1, 3, 7, 9)
tah_pocitace(Deska, NovaDeska) :-
    member(RohIndex, [1, 3, 7, 9]),
    je_volny(Deska, RohIndex),
    zahraj(Deska, RohIndex, o, NovaDeska), !.

% 5. Jinak hraj náhodně na volné místo
tah_pocitace(Deska, NovaDeska) :-
    najdi_tah(Deska, o, NovaDeska).

Klíčový koncept: Předvídání budoucnosti

To, co dělá AI "inteligentní", je schopnost simulace. Prolog si v paměti "zkusí" zahrát tah, podívá se na výsledek (vyhraju?), a pokud se mu nelíbí, vrátí se zpět (backtracking) a zkusí jiný. To vše se děje ve zlomku vteřiny, než se na obrazovce objeví křížek.

Otázky k zamyšlení

  1. Proč je pravidlo pro "blokování" až na druhém místě? Co by se stalo, kdyby bylo první? (Počítač by se jen bránil a nesnažil by se vyhrát, i kdyby mohl).
  2. Jak byste implementovali "Heuristiku"? (Např. pravidlo: "Je lepší mít dva symboly v rohu než dva uprostřed strany").
  3. Proč je Minimax těžký pro šachy? (Strom možností je příliš velký, nelze ho projít celý. Musíme se dívat jen pár tahů dopředu).

🧪 Laboratoř: Herní designér