Nový protokol


Úvod

Tento dokument popisuje, jak spolu komunikují piškvorkový brain (umělá inteligence) a piškvorkový manažer (program, který zprostředkovává zápas). Komunikace probíhá přes dvě roury, které vytváří manažer. Jednou rourou posílá manažer příkazy brainu a druhou rourou posílá brain odpovědi manažeru. Důležité je, že brain komunikuje přes standardní vstup a výstup. Nemusí tedy nic vědět o rourách a může si myslet, že příkazy čte z klávesnice a odpovědi vypisuje na obrazovku. Proto může být brain vytvořen prakticky v libovolném programovacím jazyce, který umožňuje vytvářet konzolové aplikace. V zásadě lze příkazy číst třeba obyčejným readln,scanf nebo něčím podobným a odpovídat pomocí writeln, printf nebo něčím podobným. Je třeba dát pozor na to, že za printf je nutné zavolat funkci fflush(stdout), jinak krátké řádky mohou zůstat v bufferu, aniž by byly poslány. Druhou možností je použít nízkoúrovňové funkce ReadFile a WriteFile.

Příkazy putují do roury vždy jeden příkaz na řádce, po příkazu manažer posílá sekvenci CR LF (0x0d, 0x0a) - neboli konec řádky. Manažer očekává odpovědi ukončené CR LF, nebo jenom LF nebo jenom CR. Prázdné řádky ignoruje. Kvůli jednoduchosti může mít manažer omezenu maximální délku řádku. Pokud brain pošle moc dlouhou řádku, tak ji manažer ořízne. V žádném případě manažer nesmí spadnout (ani kdyby mu brain poslal gigabytovou zprávu).

Brain může a nebo také nemusí rozlišovat mezi velkými a malými písmeny. Naopak manažer vždy musí posílat příkazy napsané velkými písmeny a parametry za INFO pro změnu malými písmeny. Při zpracování odpovědi od brainu musí manažer rozpoznat příkazy napsané velkými i malými písmeny.

Pokud má brain jen jeden thread (vlákno výpočtu), pak je poměrně důležité, aby nečetl ze vstupu, když nemá, a nezapisoval na výstup, když nemá. Pokud se pokusí číst další příkaz ve chvíli, kdy se od něj očekává odpověď, pak dojde k zablokování (brain čeká na další příkaz, manažer čeká na odpověď - vzniká deadlock) a typicky to po timeoutu na tah skončí odstřelením a prohrou brainu. Jestliže se váš brain skládá ze dvou threadů, pak může první thread číst ze vstupu, zatímco druhý thread přemýšlí a zapisuje výsledek na výstup. V takovém případě je samozřejmě nutné oba thready navzájem synchronizovat pomocí událostí, semaforů nebo podobných objektů. Pro turnaj vůbec není důležité, kolik threadů brain obsahuje. Při turnaji si brain bohatě vystačí jen s jedním threadem. Pokud ale proti brainu hraje člověk, pak je výhodnější mít dva thready. Je pak například možné, aby člověk změnil časový limit ve chvíli, kdy už brain přemýšlí. Také pak člověk může přemýšlení brainu kdykoli přerušit, aniž by se musel ukončit brain.

Brain nemusí umět úplně všechny příkazy popsané v této dokumentaci. Povinné jsou pouze příkazy START, BEGIN, INFO, BOARD, TURN, END. Tyto příkazy budou použity při turnaji a brain je musí umět, pokud se chce soutěže zúčastnit. U příkazu INFO nemusí brain znát všechny jeho možné parametry a může je ignorovat. Některé příkazy se používají jen při hře proti člověku nebo pro různé ladicí účely, analýzy tahů a podobně.

Název brainu a pomocné soubory

V názvu brainu jsou povoleny pouze znaky A-Z, a-z, 0-9, pomlčka, podtržítko, tečka. Název brainu musí začínat na "pbrain-".
Příklad:
 pbrain-svine.exe
 pbrain-pisq5.exe
Pokud brain začíná na jiný prefix, tak to znamená, že komunikuje starou metodou přes soubory. Pokud se brain skládá z více souborů, pak je prefix pbrain- povinný jen u spustitelného souboru. Je-li brain zkomprimován do ZIP archivu, pak název ZIP souboru nemá prefix pbrain-. V ZIP souboru může být zároveň 32-bitový a 64-bitový exe soubor. Název 64-bitového exe souboru musí obsahovat 64. Například uvnitř MyPisq.ZIP může být zároveň pbrain-MyPisq.exe a pbrain-MyPisq64.exe. Manažer si automaticky zvolí správný exe soubor podle toho, jestli běží na 32-bitovém nebo 64-bitovém operačním systému.

Pracovní adresář si volí manažer. Brain musí počítat s tím, že pracovní adresář je jiný než ten, ve kterém se nachází spustitelný soubor brainu. Jestliže tedy brain kromě EXE a DLL souborů obsahuje také ještě nějaké datové soubory, pak se na ně musí odkazovat celou cestou. Cestu může brain zjistit například pomocí funkce GetModuleFileName. Druhou možností je podívat se na nultý parametr na příkazové řádce. Manažer musí při spouštění brainu na příkazovou řádku dát název exe souboru v takovém tvaru, aby ho brain mohl otevřít, tedy včetně exe přípony a případně cesty, pokud brain neleží v pracovním adresáři.

Pokud brain potřebuje ukládat na disk nějaké soubory, pak si v pracovním adresáři vytvoří složku, jejíž název musí být stejný jako název brainu. V této složce si pak brain může dělat prakticky cokoli, pokud tím nepřekročí maximální povolenou velikost, která je zveřejněna na webových stránkách turnaje (nyní je 20MB). Během turnaje se soubory v této složce nemažou. Manažer může všechny dočasné soubory odstranit až po skončení turnaje nebo při ukončení manažeru. Pro trvalé ukládání souborů slouží složka, jejíž název manažer brainu sdělí příkazem INFO folder.

Povinné příkazy

START [velikost]

Instrukce pro brain k inicializaci dat. Tímto příkazem se pouze inicializuje brain, ještě ale nemá provést žádný tah. Parametrem je celé číslo určující velikost hrací plochy. Pokud brainu velikost vyhovuje, pak odpoví OK. Jinak odpoví ERROR, za kterým následuje chybová hláška. Brain by měl umět hrát alespoň na ploše o velikost 20, protože taková velikost je použita při turnaji. Manažer na příkaz ERROR může reagovat vypsáním chybové hlášky a nebo může zkusit změnit velikost hrací plochy a pak restartovat brainy.
Příklad:
 Manažer pošle:
  START 20
 Brain odpoví:
  OK - parametr vyhovuje
  ERROR chybová hláška - parametr nevyhovuje nebo došlo k jiné chybě

TURN [X],[Y]

Říká brainu, na které souřadnice táhl soupeř. Souřadnice jsou číslovány od nuly. Brain odpoví souřadnicemi svého tahu.
Očekávaná odpověď:
 dvě čísla oddělená čárkou - kam táhne brain

Příklad:
 Manažer pošle:
  TURN 10,10
 Brain odpoví:
  11,10

BEGIN

Jednomu z brainů bude tento příkaz poslán po startu, což znamená, že brain má začít na prázdné ploše hrát. Druhý z brainů dostane po startu místo toho příkaz TURN s prvním tahem soupeře. Pokud si manažer sám vymýšlí zahájení, pak se příkaz BEGIN vůbec nepoužije a místo toho oba brainy na začátku dostanou příkaz BOARD.
Očekávaná odpověď:
 dvě čísla oddělená čárkou - kam táhne brain

Příklad:
 Manažer pošle:
  BEGIN
 Brain odpoví:
  10,10

BOARD

Tímto lze vnutit brainu úplně novou plochu. Vhodné např. pro pokračování nějaké rozehrané partie, pro funkce zpět/vpřed, pro automatická zahájení atd. Ve chvíli, kdy je poslán příkaz BOARD, je hrací plocha prázdná. Tento příkaz zpravidla bývá posílán po inicializaci (příkazy START, RECTSTART nebo RESTART). Nebude poslán brainu, ve kterém už je rozehrána nějaká hra. V takovém případě by brain nejdříve dostal příkaz RESTART a nebo by byl ukončen a spuštěn znovu.

Po tomto příkazu jsou poslána data tvořící plochu. Je to vždy jeden záznam na jeden řádek ve formátu:

 [X],[Y],[POLE]
kde [X] a [Y] jsou souřadnice a [POLE] je buď číslo 1 (vlastní piškvorka), nebo 2 (piškvorka soupeře), nebo 3 (pouze při kontinuální hře, označuje výherní řadu nebo chybný tah při Renju).

Pokud se hraje podle pravidel Renju, pak musí manažer poslat tahy v takovém pořadí, v jakém byly provedeny. Při standardním Gomoku nebo Piškvorkách může manažer poslat tahy v libovolném pořadí a brain se s tím musí nějak vypořádat. Data jsou ukončena samostatným řádkem DONE.

Tímto příkazem se od brainu očekává že bude z této pozice ihned táhnout, neboli čeká se odpověď jako u příkazu TURN nebo BEGIN.

Příklad:
 Manažer pošle:
  BOARD
  10,10,1
  10,11,2
  11,11,1
  9,10,2
  DONE
 Brain odpoví:
  9,9

INFO [klíč] [hodnota]

Manažer posílá brainu nějakou informaci. Brain může tuto informaci ignorovat. Pokud ale nechce prohrát, tak by se měl podle této informace řídit (například by neměl překračovat časové limity). Brain by neměl spoléhat na to, že mu manažer pošle všechny zde uvedené informace. Také by měl počítat s tím, že člověk může některé hodnoty v průběhu partie změnit. Proto se doporučuje, aby brain reagoval i na změny v průběhu partie. Během turnaje se časové a paměťové limity měnit nebudou.
 Parametry:
timeout_turn  - limit na tah (v milisekundách, 0=hraj co nejrychleji)
timeout_match - limit na zápas (v milisekundách, 0=bez limitu)
max_memory    - limit na maximální spotřebovanou paměť (v bajtech, 0=bez limitu)
time_left     - zbývající čas do konce partie (v milisekundách)
game_type     - 0=hra proti člověku, 1=hra proti brainu, 2=turnaj, 3=síťový turnaj
rule          - bitová maska neboli součet hodnot: 1=přesně pět v řadě vyhrává, 2=kontinuální hra, 4=renju
evaluate      - souřadnice X,Y aktuální pozice ukazatele myši
folder        - složka, kam si brain může zapisovat trvalé soubory
Informace o časových a paměťových limitech manažer posílá na začátku partie, obvykle po obdržení odpovědi OK na příkaz START. Je ale také povoleno informace poslat už před příkazem START. Informaci o zbývajícím čase manažer posílá před každým tahem (příkaz TURN, BEGIN nebo BOARD). Pokud brain překročí časový limit, pak zbývající čas může být záporný. Pokud čas na partii není omezen, pak je zbývající čas roven 2147483647. Pokud čas na partii omezen je, pak je manažer povinen posílat informaci o zbývajícím čase. Proto brain může ignorovat timeout_match a spoléhat se jen na time_left. Nulová hodnota času na tah znamená, že brain má odpovědět pokud možno co nejdříve (měl by například jenom spočítat ohodnocovací funkci a už neprohledávat do hloubky všechny možné tahy).

Do času na tah se nezapočítává doba inicializace brainu (příkazy START, RECTSTART, RESTART), ale ostatní příkazy (například BOARD, INFO) se do času na tah počítají. Čas na partii se měří od spuštění procesu až do konce hry, ale ne když hráč není na tahu.

INFO folder určuje, do které složky si brain může ukládat své soubory, které na disku zůstanou i po skončení manažeru. Tato složka je společná pro všechny brainy, případně i pro jiné aplikace. Proto je brain povinen si v dané složce vytvořit svoji podsložku, jejíž název je stejný jako název brainu. Do ní si může ukládat například znalosti a zkušenosti získané během hry. Jestliže manažer nepošle INFO folder, pak je ukládání trvalých souborů zakázáno, a proto se brain na tuto možnost nesmí spoléhat.

Na INFO evaluate by měla reagovat jen Debug verze brainu například tak, že vypíše do nějakého okna ohodnocení daného políčka. Release verze brainu by měla tento příkaz ignorovat.

Jak by se měl brain chovat když dostane INFO, kterému nerozumí:
- Ignorovat ho, pravděpodobně to není nic důležitého. Pokud by to bylo důležité, dostal by příkaz, kterému nerozumí.

Jak by se měl brain chovat když dostane INFO, kterému rozumí, ale je nepřijatelné (např. příliš malý limit na paměť):
- Brain musí s vrácením chyby počkat, až dostane příkaz TURN, BOARD nebo BEGIN. Během posílání info příkazu manažer nečte vstup.

Příklad:
 INFO timeout_match 300000
 INFO timeout_turn 10000
 INFO max_memory 83886080
 
 Očekávaná odpověď: žádná

END

Příkaz k ukončení brainu. Brain by se měl co nejrychleji ukončit (pokud to neudělá, bude odstřelen). Manažer by měl po poslání příkazu END čekat, dokud brain neskončí. To ale neznamená, že se by při zatuhnutí brainu měl zablokovat také manažer. Pokud brain neskončí během určitého časového limitu (například 1 sekunda), pak manažer brain násilně ukončí. Manažer by neměl rouru, která vede směrem od brainu k manažeru, uzavírat dříve než brain skončí.
 Očekávaná odpověď:
 Očekává se, že se brain co nejrychleji ukončí a nebude posílat žádnou odpověď.
 Před ukončením by měl po sobě smazat všechny dočasné soubory, pokud si někde nějaké vytvořil.

ABOUT

Od brainu se čeká, že na jedné řádce o sobě pošle stručné informace (jméno, autora, verzi,...). Každý údaj musí být uveden ve tvaru název, rovnítko, hodnota v uvozovkách, kde název je například name, version, author, country, www, email. Jednotlivé informace jsou odděleny čárkou, za kterou mohou následovat mezery. Manažer musí počítat s tím, že starší brainy odpovídaly na příkaz ABOUT libovolným textem čitelným pouze pro člověka. V žádném případě brain jako odpověď nesmí poslat více řádek textu.
Příklad:
 Manažer pošle:
  ABOUT
 Brain odpoví:
  name="SomeBrain", version="1.0", author="Nymand", country="USA"

Nepovinné příkazy

Rozšíření zde uvedené nemusí být implementované pro účast v turnaji, nicméně autor se může rozhodnout je implementovat, neboť mu mohou být užitečné.

RECTSTART [šířka],[výška]

Tento příkaz je podobný jako příkaz START až na to, že hrací plocha je obdélníková. Pokud je hrací plocha čtvercová, pak manažer musí použít příkaz START. Parametrem jsou dvě čísla oddělená čárkou. První rozměr náleží k souřadnici X, druhý rozměr souřadnici Y.
Příklad:
 Manažer pošle:
  RECTSTART 30,20
 Brain odpoví:
  OK - parametry vyhovují
  ERROR chybová hláška - parametry nevyhovují

RESTART

Tento příkaz se používá například tehdy, když je potřeba přerušit hru a začít novou hru. Příkaz nemá žádné parametry. Velikost hrací plochy zůstává beze změny. Brain na tento příkaz reaguje tak, že uvolní datové struktury předchozí hry a vytvoří si novou prázdnou hrací plochu. Pokud brain na tento příkaz odpoví OK, pak další komunikace pokračuje stejně jako po příkazu START. Pokud brain na tento příkaz odpoví UNKNOWN, pak manažer ukončí brain zasláním příkazu END a poté spustí brain znovu.
Příklad:
 Manažer pošle:
  RESTART
 Brain odpoví:
  OK

TAKEBACK [X],[Y]

Tento příkaz se používá pro vrácení posledního tahu. Brain na tento příkaz reaguje tak, že z hrací plochy odstraní kámen z políčka [X,Y] a pak odpoví OK.
Příklad:
 Manažer pošle:
  TAKEBACK 9,10
 Brain odpoví:
  OK

PLAY [X],[Y]

Vnucení tahu brainu - říká brainu, že svůj další tah má udělat na políčko dané souřadnicemi [X], [Y]. Používá se pouze jako odpověď na SUGGEST. V turnaji manažer brainu vždy vrátí tah, který brain poslal v SUGGEST.
 Očekávaná odpověď:
 Stejně jako na příkaz TURN nebo BEGIN - dvě čísla oddělená čárkou, neboli
 kam brain táhl. Brain se může rozhodnout tohle vnucení tahu ignorovat a táhnout jinam,
 pro manažer je relevantní co brain vrátí, ale silně se nedoporučuje tento příkaz
 neposlechnout.

Příklad:
 Brain odpověděl:
  SUGGEST 10,10
 Manažer pošle:
  PLAY 12,10
 Brain udělá tah na 12,10 a odpoví:
  12,10

Příkazy, které posílá brain

Následující příkazy může brain použít, pokud je potřebuje. Manažer všechny tyto příkazy musí znát.

UNKNOWN [chybová zpráva]

Takto brain musí reagovat na příkaz, který nezná. Obdržení neznámého příkazu tedy není důvodem ke skončení brainu. Parametrem příkazu je chybová zpráva. Manažer buď zobrazí chybovou zprávu, nebo se pokusí použít nějaké jiné příkazy. Například pokud brain takto odpoví na nepovinný příkaz, tak by měl manažer místo něj zkusit nějaký povinný příkaz. Pokud se s tím manažer neumí vypořádat, pak pošle příkaz END.

ERROR [chybová zpráva]

Takto brain odpoví na příkaz, kterému rozumí, ale nemůže ho z jakéhokoli důvodu provést (např. předtím dostal nevyhovující info hodnotu). Parametrem může být chybová zpráva, kterou manažer zobrazí uživateli a nebo ji zapíše do logovacího souboru. Manažer se také může pokusit provést příkaz nějak jinak.

MESSAGE [zpráva]

Zpráva, kterou manažer může logovat do souboru nebo ji vypisovat do nějakého okna. Brain by měl zprávu poslat ve chvíli, kdy je od něj očekávána odpověď na nějaký příkaz. Typicky tuto zprávu brain pošle těsně před tím, než vrátí souřadnice svého tahu. Uvnitř zprávy se nesmí vyskytovat znak konce řádku. Víceřádkový text lze poslat pomocí několika po sobě jdoucích MESSAGE příkazů.

Pokud brain posílá zprávu v jiném jazyce než angličtině, pak by si nejdříve měl zjistit, jaké kódování je nastavené na daném počítači. Například může použít funkci GetACP. Pokud tato funkce vrátí něco jiného než 1250, pak by brain neměl posílat zprávu v češtině, protože by nebyla zobrazena správně.

DEBUG [zpráva]

Používá se stejně jako MESSAGE, ale zpravidla obsahuje informace, kterým rozumí jen autor brainu nebo které nemusejí být užitečné pro lidského hráče.
Příklad:
 Manažer pošle:
  TURN 10,15
 Brain odpoví:
  DEBUG Zatím nejlepší tah [10,14] alfa=10025 beta=8641
  DEBUG Zatím nejlepší tah [11,14] alfa=10125 beta=8641
  MESSAGE Mám to vyhraný
  10,16

SUGGEST [X],[Y]

Tohle je rozšíření protokolu, které se může hodit pro debugování a porovnávání brainů. [X] a [Y] jsou souřadnice, kam chce brain táhnout. Normálně brain jako odpověď vrací řádku obsahující pouze tyto souřadnice. Pokud je před souřadnicemi navíc slovo SUGGEST, pak tím brain dává manažeru najevo, že toto rozšíření protokolu chce používat. Tímto má manažer možnost na druhé straně tah, který tento algoritmus vymyslel, změnit a vnutit mu jiný, který pak on ve svém vnitřním stavu provede. Brain tedy po odeslání SUGGEST nemění svůj vnitřní stav. Manažer na toto odpoví vždy buď příkazem PLAY, kterým mu vnutí tah, nebo END.

Historie změn