Эхлэгчдэд зориулсан алхам алхмаар заавар
Хэрэгтэй зүйлс
- FlipSight бүртгэл. Нэвтэрсний дараа бот бүртгүүлж, холбогч программыг татаж авах боломжтой.
- Ботын нэг зураг: 5 MB-аас ихгүй, өргөн, өндөр нь 175 px-ээс багагүй GIF, JPG эсвэл PNG файл.
- Бот ажиллуулах өөрийн компьютер Ботын нүүдлийг холбогч ажиллаж буй таны компьютер дээр тооцдог. Нэг хөдөлгүүр байсан ч компьютерийн хүчин чадал, хөдөлгүүрийн тохиргооноос хамаарч хүч нь өөр байж болох бөгөөд компьютер эсвэл тохиргоогоо солиход чансаа ч үүнийг дагаж өөрчлөгдөж болно.
- Python 3, холбогч программыг ажиллуулдаг үнэгүй программ. 3.9 буюу түүнээс хойших хувилбар ажиллана; 3.11 буюу түүнээс хойших хувилбарыг зөвлөж байна. Үүнийг 5-р алхамд шалгана.
- Өөрийн ботын хөдөлгүүр. Холбох програмд турших зориулалттай дасгалын хөдөлгүүр багтсан.
1. Ботоо бүртгүүлэх
Нэвтэрч ороод ботын хуудсыг (othelloclub.com/mn/flipsight/bot) нээнэ. Дээд талын Ботоо бүртгүүлэх хэсгийн Ботын нэр (2–24 тэмдэгт) талбарт нэр бичнэ. Дэмжих тоглоом хэсэгт одоохондоо зөвхөн Стандарт-г сонгосон хэвээр үлдээнэ. Ботын зураг оруулах хэсгээс зураг сонгоод Ботоо бүртгүүлэх товчийг дарна.
Амжилттай бол ингэж харагдана: fsbm_-ээр эхэлсэн урт бичвэртэй Холболтын токен (нэг удаа харуулна) хэсэг гарч ирнэ.
2. Токеноо хадгалах
Энэ урт бичвэр бол токен, зөвхөн таны ботод зориулсан нууц үг юм. Холбогч программ үүгээр энэ ботын нэрийн өмнөөс ажиллаж байгаагаа серверт батална. Бүтнээр нь хуулж, текст засварлагч гэх мэт түр газар буулгана. Хэсгийг хаасны дараа яг ижил токеныг дахин харах боломжгүй.
Токеныг нууц үг шиг хадгална. Хэнд ч бүү үзүүл, дэлгэцийн зургийг нь бүү нийтэл. Алдсан эсвэл хэн нэгэн харсан бол ботын жагсаалтаас Удирдах хэсгийг нээж Холболтын токен үүсгэх товчийг дарна. Шинэ токен авмагц хуучин нь шууд ажиллахаа болино.
3. Холбогч программыг татах
Python жишээ татах товчийг дарж ZIP файлыг татаад задална. Энэ заавар задалсан хавтсыг "бот хавтас" гэж нэрлэнэ. Үүнийг ширээний дэлгэц гэх мэт амархан олдох газар байршуулна.
Амжилттай бол ингэж харагдана: бот хавтсанд README.md файл болон tools хавтас байна.
4. Бот хавтсанд терминал нээх
Терминал бол команд бичдэг цонх юм. Өөрийн системд тохируулан дараах байдлаар нээнэ.
macOS: Command+Space дарж, Terminal гэж бичээд нээнэ. cd гэж бичээд нэг зай авч, бот хавтсыг цонх руу чирээд Enter дарна.
Linux: файл менежерт бот хавтас дээр хулганы баруун товч дарж Open in Terminal (Терминалд нээх) цэсийг сонгоно. Цэсний нэр дистрибутиваас хамаарч өөр байж болно. Ийм цэс байхгүй бол терминал нээгээд macOS-ийнх шиг cd ашиглана.
Windows: бот хавтсыг File Explorer-оор нээнэ. Дээд талын хаягийн мөрөнд powershell гэж бичээд Enter дарна. Тэр хавтсанд PowerShell цонх нээгдэнэ.
Шалгах: доорх командыг бичээд Enter дарна. Жагсаалтад README.md болон tools гарч ирвэл амжилттай. Энэ команд macOS, Linux, Windows PowerShell дээр ижил.
ls5. Python шалгах
Мөн тэр цонхонд өөрийн системийн нэг командыг хуулж, буулгаад Enter дарна. Кодын хэсэг бүрийн баруун дээд буланд байгаа хуулах товчийг ашиглаж болно.
macOS / Linux
python3 --versionWindows PowerShell
py --versionАмжилттай бол ингэж харагдана: Python 3.11.9 гэх мэт 3-аар эхэлсэн хувилбар. 3.9 буюу түүнээс хойших хувилбар ажиллана. Команд олдохгүй бол Python-г доорх байдлаар суулгаж, цонхоо хаагаад 4-р алхмаас дахин эхэлнэ.
macOS: python.org-оос macOS суулгагчийг (.pkg) татаж суулгана. Дараа нь Applications доторх Python хавтаснаас Install Certificates.command-г нэг удаа ажиллуулна. Энэ нь аюулгүй (HTTPS) холболтод хэрэгтэй гэрчилгээг бэлтгэнэ.
Linux: python3-ийг дистрибутивынхаа программ хангамжийн менежер эсвэл багц менежерээр суулгана.
Windows: python.org-оос Python суулгах менежерийг (Python install manager) суулгана.
6. Токен оруулах
Токеныг орчны хувьсагчид хийнэ. Орчны хувьсагч бол зөвхөн энэ терминалын цонх дотор байдаг түр тохиргоо юм. Түүний нэр FS_BOT_TOKEN. Доороос өөрийн системийн нэг мөр командыг хуулж, буулгаад Enter-ийг нэг удаа дарна. Тэгэхэд Bot token гарч ирээд таныг оруулахыг хүлээнэ. Одоо 2-р алхамд хуулсан токеноо буулгаад Enter дарна.
macOS / Linux
printf 'Bot token: '; read -r -s FS_BOT_TOKEN; printf '\n'; export FS_BOT_TOKENWindows PowerShell
$env:FS_BOT_TOKEN = [Net.NetworkCredential]::new('', (Read-Host 'Bot token' -AsSecureString)).PasswordmacOS, Linux дээр буулгасан токен харагдахгүй, Windows дээр тэмдэгтүүдийн оронд * харагдана. Аль аль нь хэвийн. Токеныг командад бичдэггүй тул командын түүхэнд үлдэхгүй. Тохиргоо зөвхөн энэ цонхонд хүчинтэй. Цонхоо хаасан эсвэл шинэ цонх нээсэн бол 4, 6-р алхмыг давтана.
Windows: PowerShell-д Ctrl+V эсвэл хулганы баруун товшилтоор буулгана. Энэ нэг мөр команд нь Windows-той хамт ирдэг Windows PowerShell 5.1 болон шинэ PowerShell 7 хоёуланд нь ажиллах бичлэгтэй боловч бодит Windows компьютер дээр хараахан туршаагүй.
Амжилттай бол ингэж харагдана: алдаагүйгээр дараагийн командын мөр буцаж гарна.
7. Холбогч программыг эхлүүлэх
Мөн тэр цонхонд доорх командыг байгаагаар нь хуулж, буулгаад Enter дарна. Доторх файлын нэрийг бүү өөрчил. Таны бот дасгалын хөдөлгүүрээр холбогдоно. Энэ нь хамгийн бага дугаартай зөв нүдэнд тавьдаг маш сул хөдөлгүүр юм.
macOS / Linux
python3 tools/bot_match_client.py --engine 'python3 tools/bot_match_example_engine.py'Windows PowerShell
py tools/bot_match_client.py --engine 'py tools/bot_match_example_engine.py'Команд ажиллаж байх үед бичиг гарахгүй, дараагийн оролтын мөр буцаж ирэхгүй байх нь хэвийн. Ботоо онлайн байлгахын тулд энэ цонхыг нээлттэй байлгаж, холболтын програм болон хөдөлгүүрийг үргэлж ажиллуулан, компьютер унтах горимд орохоос сэргийлээрэй. Цонхыг хаах эсвэл Ctrl+C дарахад хоёр програм зогсож, бот офлайн болно. Дахин онлайн болгохын тулд дээрх командыг дахин ажиллуулна. Холболтын програм бусад ботын тоглолтын хүсэлтийг автоматаар зөвшөөрнө.
Бот дасгалын хөдөлгүүрээр ажиллаж байх хугацаанд автомат тоглолт авахгүй бөгөөд бусад боттой тоглосон тоглолт, өөрөө хүсэлт илгээснийг оруулаад, чансаанд тооцогдохгүй. Өөрийн хөдөлгүүрээр дахин асаавал (10-р алхам) тэр үеэс эхлэн хослол авч, чансаанд тооцогдоно.
Амжилттай бол ингэж харагдана: ботын хуудасны Бүртгэлтэй ботууд жагсаалтад таны ботын нэрийн баруун талын цэг ногоон байна. Хулганаар дээр нь очиход Онлайн гэж харагдана. Саарал (Офлайн) байвал Шинэчлэх товчийг дарна.
8. Эхний өрөгөөр шалгах
Ботын хуудасны Миний тоглох бот хэсгээс өөрийн ботыг сонгоно. FlipSight ботууд жагсаалтаас дурын бот сонгож, Урих товчийг дараад нээгдсэн цонхонд баталгаажуулна. Бүх төрлийн тоглоомд FlipSight ботуудын нүүдлийг сервер тооцоолдог тул тоглоомын өрөөг нээлттэй байлгах шаардлагагүй. Автомат хослол асаалттай бол (анхдагч) холбогч программ ажиллаж байх хугацаанд сайт ботын тоглолт зохион байгуулна.
Амжилттай бол ингэж харагдана: тоглоомын өрөөнд хоёр самбар харагдаж, таны ботын ээлж бүрд чулуу тавигдана. Дасгалын хөдөлгүүр маш сул тул ялагдах нь хэвийн.
9. Цонх хаасны дараа ч ажиллуулах (сонголттой)
7-р алхмын оронд доорх командаар эхлүүлбэл цонхоо хаасны дараа ч бот ажилласаар байна. Үүнийг токен оруулсан цонхондоо (6-р алхам) ажиллуулна. Компьютер унтарсан эсвэл унтах горимд орвол зогсоно. Өрөг явагдаж байхад зогсоовол тэр өрөгт цагаар эсвэл холболт тасарснаар ялагдана.
macOS / Linux
macOS / Linux: эхлүүлэх командыг ажиллуулсны дараа цонхоо хааж болно. Мессежүүд бот хавтсан дахь bot.log файлд бичигдэнэ. Зогсоохын тулд шинэ терминал нээж, зогсоох командыг ажиллуулна. Зөвхөн хэрэгтэй хайрцгаа хуулна: хоёр хайрцгийг зэрэг буулгавал бот эхэлмэгцээ зогсоно.
Эхлүүлэх
nohup python3 tools/bot_match_client.py --engine 'python3 tools/bot_match_example_engine.py' > bot.log 2>&1 &Зогсоох
pkill -f bot_match_client.pyWindows PowerShell
Windows: taskbar дээр жижигрүүлсэн цонх гарч ирэх ба бот түүн дотор ажиллана. Одоогийн PowerShell цонхыг хааж болно. Зогсоохын тулд жижигрүүлсэн цонхыг нээгээд Ctrl+C дарах эсвэл тэр цонхыг хаана.
Эхлүүлэх
Start-Process py -ArgumentList 'tools/bot_match_client.py --engine "py tools/bot_match_example_engine.py"' -WorkingDirectory $PWD -WindowStyle Minimized10. Өөрийн хөдөлгүүр рүү шилжих
Дасгалын хөдөлгүүрээр холболтыг шалгасны дараа өөрийн хөдөлгүүрт шилжинэ. Edax, Egaroucid-д доорх тусгай тохиргоо, бусад NBoard дэмждэг хөдөлгүүрт --nboard, өөрийн хөдөлгүүрт JSON ашиглана. Токен хэвээр үлдэнэ.
Хувилбар тоглоомыг (Anti, 10x10, Octagon, сонгодог Reversi) зөвхөн таны хөдөлгүүр дүрмийг нь мэддэг үед Дэмжих тоглоом хэсэгт сонгоно. Бусад бот болон хүмүүс сонгосон тоглоом бүрд таны ботыг урьж болно. Өөрчлөхийн тулд ботын жагсаалтаас Удирдах хэсгийг нээж, Дэмжих тоглоом-г засаад Хадгалах товчийг дарна. Өрөг явагдаж байх эсвэл урилга хүлээгдэж байх үед өөрчлөх боломжгүй.
Тоглоом тус бүрийн хөдөлгүүрийн хүсэлтийн жишээ
Edax зэрэг NBoard дэмждэг хөдөлгүүр холбох
NBoard нь NTest-тэй хамт ашиглаж болох Отеллогийн дүрстэй програм юм. NBoard протокол нь энэ програм ба хөдөлгүүрийн нийтэд нээлттэй харилцах хэлбэр бөгөөд NTest, Edax зэрэг үүнийг дэмждэг хөдөлгүүртэй ажиллана.
Доорх суулгах, ажиллуулах жишээнд Edax 4.6 болон Egaroucid for Console 7.8.2-ыг ашигласан.
Edax 4.6 нь холболтын програмд багтаагүй. Edax 4.6-ийн Assets хэсгээс үйлдлийн системдээ тохирох файлыг татаж, ботын хавтсанд тавиад доорх бэлтгэх командаар задлаарай. Windows, Linux командууд x86-64 компьютерт зориулагдсан.
Windows PowerShell (x86-64): edax-4.6-MS-windows-x86.zip
Бэлтгэл (зөвхөн эхний удаа)
Expand-Archive -LiteralPath edax-4.6-MS-windows-x86.zip -DestinationPath edax-4.6Эхлүүлэх
py tools/bot_match_client.py --edax "edax-4.6\wEdax-x86-64.exe"Linux (x86-64): edax-4.6-linux-x86.tar.gz
Бэлтгэл (зөвхөн эхний удаа)
mkdir -p edax-4.6
tar -xzf edax-4.6-linux-x86.tar.gz -C edax-4.6
chmod +x edax-4.6/lEdax-x86-64Эхлүүлэх
python3 tools/bot_match_client.py --edax "edax-4.6/lEdax-x86-64"macOS: edax-reversi-4.6.tar.gz
Edax 4.6-ийн албан ёсны macOS ажиллах файл байхгүй. Ижил хувилбарын Source code (tar.gz) болон edax-4.6-linux-x86.tar.gz-ийг татна. Mac програмыг эх кодоос бүтээж, Linux архиваас зөвхөн нийтлэг үнэлгээний data/eval.dat файлыг авна. Xcode Command Line Tools хэрэгтэй. Бэлтгэх командууд эх кодыг хөрвүүлнэ.
Бэлтгэл (зөвхөн эхний удаа)
xcode-select --installtar -xzf edax-reversi-4.6.tar.gz
mv edax-reversi-4.6 edax-4.6
mkdir -p edax-4.6/bin
tar -xzf edax-4.6-linux-x86.tar.gz -C edax-4.6 data/eval.dat
(cd edax-4.6/src && make build ARCH=native OS=osx)Эхлүүлэх
python3 tools/bot_match_client.py --edax "edax-4.6/bin/mEdax-native"Edax-г доорх --edax сонголтод ажиллах файлын замыг өгч бас холбож болно. Тусдаа адаптер хэрэггүй; холбогч үлдсэн тоглолтын цагаас нүүдэл бүрийн бодох хугацааг хуваарилна.
Командын замыг өөрийн ажиллах файлын бүтэн замаар солино. Замд хоосон зай байвал давхар хашилтад хийнэ. Үнэлгээний файл автоматаар олдохгүй бол --edax-eval-аар eval.dat-ийн замыг заана.
NBoard холболт зөвхөн ердийн 8×8 өрөг тоглоно. Энэ ботын Дэмжих тоглоом хэсэгт зөвхөн Стандарт-г сонгосон хэвээр үлдээнэ. Хувилбар тоглоом ирвэл холбогч программ хөдөлгүүрээс асуухгүй, нүүдэл хийгдэхгүй, өрөг цуцлагдах эсвэл цагаар ялагдана.
Egaroucid: --egaroucid
Egaroucid for Console-г бэлтгэнэ үү. Дэлгэцтэй програмын оронд консоль файлыг сонгож, resources хавтсыг байранд нь үлдээнэ. macOS, Linux дээр албан ёсны заавраар бүтээсэн файлыг ашиглана. Холбогч setboard, settime, go командаар байрлал ба үлдсэн хугацааг дамжуулах тул адаптер хэрэггүй.
Windows PowerShell
py tools/bot_match_client.py --egaroucid "egaroucid\Egaroucid_for_console.exe"macOS / Linux
python3 tools/bot_match_client.py --egaroucid "egaroucid/bin/Egaroucid_for_Console.out"Хоёр арга зөвхөн энгийн 8×8 тоглоом дэмжинэ. Хоёр өрөг зэрэг явахад өрөг бүрд нэг хөдөлгүүр ажиллана. --max-think-seconds нь нэг нүүдлийн хамгаалалтын хязгаар (анхдагч 10 секунд). Egaroucid хязгаарт хүрвэл хайлтыг зогсоож, зөвшөөрөгдөх нөөц нүүдэл хийн, дараагийн ээлжид хөдөлгүүрийг дахин асаана.
Өөрөө хийсэн хөдөлгүүр: JSON-оор холбох
Өөрөө бичсэн хөдөлгүүрээ холбох гэж байгаа бол л энэ хэсгийг уншина. Edax, Egaroucid эсвэл өөр NBoard хөдөлгүүр ашиглаж байгаа бол дээрх алхмуудаар ажил аль хэдийн дууссан тул энэ хэсгийг алгасаж болно.
Таны ботын ээлж ирэх бүрд холбогч программ my_adapter.py-г нэг удаа ажиллуулна. Тэр одоогийн байрлалыг нэг мөр болгон өгнө (чулуунууд хаана байгаа, хэний ээлж, аль нүд зөв, хэдий хугацаа үлдсэн), my_adapter.py нэг мөрөөр нэг нүд хариулж, холбогч программ тэр нүүдлийг сервер дээр хийнэ. my_adapter.py нь дунд нь байрлах жижиг Python файл бөгөөд таны хөдөлгүүрээс нүүдлийг асууна. Сервертэй холбогдох, токен, нүүдэл илгээх ажлыг холбогч программ хариуцдаг тул энэ файл тэдгээртэй огт харьцахгүй.
bot_match_client.py→ my_adapter.pybot_match_client.py← my_adapter.pyТаны хөдөлгүүр аль төрөл вэ?
- Python кодоор нүүдлээ сонгодог хөдөлгүүр: доорх жишээ A-г ашиглана.
- Ажиллуулах бүрд нэг мөр хариу хэвлээд хаагддаг программын файл: доорх жишээ B-г ашиглана.
- Нээлттэй байж командыг тасралтгүй солилцдог програм файл: NBoard-г дэмждэг бол дээрх --nboard-оор холбоно. Өөр протокол бол B жишээг тэр протоколд тааруулж засаад, my_adapter.py хөдөлгүүрийг нээлттэй байлгаж нэг нэг мөрөөр давталтаар солилцохоор хийнэ.
1-р алхам: зөвхөн холболтыг шалгах файл (my_adapter.py)
Бот хавтсанд (README.md болон tools байгаа газар) my_adapter.py нэртэй файл үүсгээд доорх кодыг яг хэвээр нь буулгаж хадгална. Энэ файл ямар ч хөдөлгүүр ашиглахгүй бөгөөд зүгээр л эхний зөв нүдээр хариулна. Хөдөлгүүрээ холбохоос өмнө холболт ажиллаж байгааг батлахад зориулагдсан.
import json
import sys
def choose_move(position):
legal = position["legal_moves"]
return legal[0] if legal else -1
line = sys.stdin.readline()
position = json.loads(line)
move = choose_move(position)
print(json.dumps({"move": move}), flush=True)
Холбохоос өмнө оролт, гаралтыг шалгах
1-р хайрцгийн команд жишээ байрлалыг адаптерт шууд өгнө. Энэ нь нэг мөр хэвлэх ёстой: {"move": 19}. Тэр мөрийг харсны дараа 2-р хайрцгийн командаар холбогч программыг энэ адаптертай эхлүүлнэ. Үүнийг 6-р алхмын токен байгаа цонхонд ажиллуулна. Хоёр хайрцгийг тус тусад нь ажиллуулна. Хэрэв таны хөдөлгүүр энэ JSON форматыг өөрөө уншдаг бол түүний командыг --engine-ийн шууд ард бичиж болно.
1. Адаптерыг дангаар нь турших
macOS / Linux
printf '%s\n' '{"board":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[19,26,37,44],"game_mode":"std","board_size":8,"blocked_squares":[],"placed":{"1":0,"2":0},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}' | python3 my_adapter.pyWindows PowerShell
'{"board":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[19,26,37,44],"game_mode":"std","board_size":8,"blocked_squares":[],"placed":{"1":0,"2":0},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}' | py my_adapter.py2. Холбогч программыг адаптертай эхлүүлэх
macOS / Linux
python3 tools/bot_match_client.py --engine 'python3 my_adapter.py'Windows PowerShell
py tools/bot_match_client.py --engine 'py my_adapter.py'2-р алхам: хөдөлгүүрээ дууддаг файл руу шилжих
1-р алхам ажилласны дараа my_adapter.py-ийн бүх агуулгыг доорх жишээ A эсвэл B-ээр солино. Зөвхөн EDIT гэж тэмдэглэсэн мөрүүдийг өөрчилж, бусдыг нь хэвээр үлдээнэ. Дараа нь дээрх туршилтын команд 1-ийг дахин ажиллуулж, нэг мөр хариу гарч байгааг шалгана. Нүүдлийг таны хөдөлгүүр сонгосон тул 19-өөс өөр нүд гарах нь хэвийн.
Жишээ A: Python функцээр нүүдлээ сонгодог хөдөлгүүр
Энэ жишээнд my_engine.py нэртэй файл дотор нүүдэл сонгодог search функц байгаа гэж үзнэ. EDIT 1 дээр файлын нэр, функцийн нэрийг, EDIT 2 дээр дамжуулах утгуудыг өөрийн хөдөлгүүрт тааруулж өөрчилнө. Функц нь нүдний дугаар (0-ээс 63) эсвэл d3 зэрэг координат буцаах ёстой.
import json
import sys
from pathlib import Path
from my_engine import search # EDIT 1: your engine file and function name
def think_ms(position):
# Time for this move: share the remaining clock over my remaining moves.
my_moves_left = position["board"].count(0) // 2 + 1
share = position["remaining_ms"] / my_moves_left
return int(min(share, position["budget_ms"]) * 0.8)
def choose_move(position):
if not position["legal_moves"]:
return -1
# EDIT 2: pass what your function needs
return search(
board=position["board"],
color=position["color"],
legal_moves=position["legal_moves"],
time_limit_ms=think_ms(position),
)
position = json.loads(sys.stdin.readline())
legal = position["legal_moves"]
try:
move = choose_move(position)
except Exception as error:
# The engine failed: note why in my_adapter.log and play the first legal square.
with open(Path(__file__).with_name("my_adapter.log"), "a") as log:
log.write(repr(error) + "\n")
move = legal[0] if legal else -1
print(json.dumps({"move": move}), flush=True)Жишээ B: программын файл хэлбэртэй хөдөлгүүр
Энэ жишээнд программ нь самбарын 64 тэмдэг, нүүх тал, миллисекундээр илэрхийлсэн бодох хугацаа бүхий нэг мөрийг уншиж, D3 зэрэг координатын нэг мөрөөр хариулна гэж үзнэ (. = хоосон, X = хар, O = цагаан). Хөдөлгүүр бүр өөрийн форматтай тул EDIT 1 дээр программын файлын нэрийг, EDIT 2 дээр хөдөлгүүрт илгээх мөрийг, EDIT 3 дээр хариуг унших хэсгийг өөрийн хөдөлгүүрт тааруулж өөрчилнө.
my_adapter.py → my_engine
...........................OX......XO........................... X 1777my_engine → my_adapter.py
D3import json
import subprocess
import sys
from pathlib import Path
# EDIT 1: your engine program file (kept in the same folder as my_adapter.py)
ENGINE = Path(__file__).with_name("my_engine.exe" if sys.platform == "win32" else "my_engine")
def think_ms(position):
# Time for this move: share the remaining clock over my remaining moves.
my_moves_left = position["board"].count(0) // 2 + 1
share = position["remaining_ms"] / my_moves_left
return int(min(share, position["budget_ms"]) * 0.8)
def choose_move(position):
if not position["legal_moves"]:
return -1
# EDIT 2: build the line your engine reads
board = "".join(".XO"[cell] for cell in position["board"])
color = "X" if position["color"] == 1 else "O"
reply = subprocess.run(
[str(ENGINE)],
input=f"{board} {color} {think_ms(position)}\n",
text=True,
capture_output=True,
check=True,
timeout=position["budget_ms"] / 1000 * 0.9,
)
# EDIT 3: take the square out of your engine's answer
return reply.stdout.strip()
position = json.loads(sys.stdin.readline())
legal = position["legal_moves"]
try:
move = choose_move(position)
except Exception as error:
# The engine failed: note why in my_adapter.log and play the first legal square.
with open(Path(__file__).with_name("my_adapter.log"), "a") as log:
log.write(repr(error) + "\n")
move = legal[0] if legal else -1
print(json.dumps({"move": move}), flush=True)Бодох хугацаа: ботын өрөгт бот тус бүр өрөг бүрд 1 минутын хугацаатай тул нэг нүүдэл дээр удаан бодвол цагаар хурдан ялагдана. Жишээн дэх think_ms нь үлдсэн хугацааг (remaining_ms) таны үлдсэн нүүдлийн тоонд хувааж, энэ нүүдлийн хугацааг тогтооно. budget_ms бол энэ нүүдэлд зарцуулах хугацаа биш. Энэ нь холбогч программ хариуг хүлээх хамгийн урт хугацаа юм (анхдагчаар 10 секунд). Хариу түүнээс хожуу ирвэл бот тэр өрөгт үргэлжлүүлж чадахгүй бөгөөд цагаар ялагдана. Тиймээс хөдөлгүүртээ budget_ms биш, think_ms-ийг дамжуулна.
Ямар нэг зүйл эвдэрсэн үед: хөдөлгүүрийг дуудах нь амжилтгүй болбол жишээ файлууд шалтгааныг my_adapter.log-д бичиж, оронд нь эхний зөв нүдийг тавина. Нүүдлүүд хачин санагдвал эхлээд тэр файлыг нээнэ. Холбогч программ адаптерын алдааны мэдээллийг дэлгэцэд харуулдаггүй. print-ийг зөвхөн нэг мөр хариунд ашиглаж, алдаа хайх бичвэрийг файлд бичнэ.
Хурд: холболтын програм тоглолт бүрд my_adapter.py-г ажиллуулсаар байж нүүдэл бүрд нэг мөр илгээнэ. Жишээ шиг нэг мөр хариулаад хаагддаг файл дараагийн нүүдэлд дахин ажилладаг тул хөдөлгүүр тань ч бас бүр дахин асна. Хөдөлгүүр удаан асдаг эсвэл өмнөх нүүдлүүдийн тооцоог үргэлжлүүлэх шаардлагатай бол my_adapter.py-г «нэг мөр уншаад нэг мөр хариулах»-ыг давтдаг болгоно уу. Оролтыг эцэс хүртэл бүү унш, хариулт бүрийн дараа flush хийнэ.
Энэ хэсгийн үлдсэн нь холбогч программ болон my_adapter.py юу солилцдог тухай лавлах материал юм. Дээрх жишээ файлуудыг яг хэвээр нь ашиглаж байгаа бол унших шаардлагагүй.
Оролтын JSON (холбогч → адаптер)
Энэ нь ажиллуулах код биш, холбогчоос илгээдэг өгөгдлийн жишээ юм. Python файл болгон хадгалах шаардлагагүй. Тоглолтын үеэр холбогч ээлж бүрд одоогийн өгөгдлийг автоматаар илгээнэ.
Доорх нь ердийн 8×8 эхлэлийн байрлалын жишээ. Жинхэнэ тоглолтод одоогийн байрлалыг холбогч программ бөглөнө. board нь нүднүүдийг a1-ээс баруун тийш, дараа нь дараагийн мөрийг жагсаана; 0=хоосон, 1=хар, 2=цагаан. color=1 нь харын нүүдлийг асууна. legal_moves нь таны тавьж болох нүднүүдийг жагсаана. remaining_ms нь өрөгийн үлдсэн цаг, budget_ms нь холбогч программ энэ нүүдлийн хариуг хүлээх хамгийн урт хугацаа бөгөөд хоёулаа миллисекундээр (1000 = 1 секунд). Хувилбар тоглоомын талбар, жишээ доорх хувилбар тоглоомын хэсэгт бий.
{"board":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[19,26,37,44],"game_mode":"std","board_size":8,"blocked_squares":[],"placed":{"1":0,"2":0},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Хариу JSON (адаптер → холбогч)
Доорх хариунуудын нэгийг мөр шилжүүлгээр төгссөн нэг мөр JSON болгон бичнэ. move нь нүдний дугаар эсвэл координат бөгөөд том жижиг үсэг ялгахгүй. 8×8 дээр d3 нь (3−1)×8+3 = 19. Үргэлж хүлээн авсан legal_moves-оос сонгоно. Ботуудын хос дээр зөв нүүдэл байхгүй бол -1 эсвэл pass илгээнэ; хүнтэй тоглолтод албадан өнжихийг сервер шийднэ. stdout руу зөвхөн хариуны мөрийг бичиж, өөр мессеж бичихгүй.
{"move":19}{"move":"d3"}{"move":-1}Тоглоом тус бүрийн хөдөлгүүрийн хүсэлтийн жишээ
Холбогч программ --engine хөдөлгүүрт илгээдэг харын эхний хүсэлтийн жишээнүүд бөгөөд дүрмийн кодоор үүсгэсэн. Бүх төрлийн жинхэнэ тоглолт санамсаргүй 12 чулуутай байрлалаас эхэлдэг тул board болон legal_moves тоглолт бүрд өөр байна. Эдгээр жишээ тогтмол байхын тулд эхлэлийн нүүдлүүдийг самбарын төвд ойр сонгосон. Жинхэнэ тоглолтод match_id болон цагийн утга ч өөр байна.
game_mode: std, anti, grand, octagon, reversi-ийн аль нэг. Хүнтэй тоглолтын XOT нь std болж ирнэ.board_size: 8, grand болон octagon-д 10.board: board_size² урттай массив. a1-ээс баруун тийш, дараа нь дараагийн мөрийг уншина. 0=хоосон (Octagon-ий хаалттай нүдийг оролцуулан), 1=хар, 2=цагаан.blocked_squares: Octagon-ий ашиглах боломжгүй нүд. Бусад тоглоомд хоосон массив.placed: Өнгө бүрийн одоог хүртэл тавьсан чулуу, эхлэлийн санамсаргүй нүүдлийг оролцуулан; түлхүүр нь "1", "2" мөрүүд. Сонгодог Reversi-ийн 32 чулууны хязгаарт ашиглана.
Anti (anti)
Оролтын JSON (холбогч → адаптер)
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 1,
"legal_moves": [2, 3, 12, 25, 42, 44, 45],
"game_mode": "anti",
"board_size": 8,
"blocked_squares": [],
"placed": {
"1": 4,
"2": 4
},
"remaining_ms": 60000,
"match_id": 123,
"leg": 0,
"revision": 0,
"history": [],
"round_no": null,
"room_created_at": null,
"budget_ms": 10000
}Хариу JSON (адаптер → холбогч)
{"move":2}Grand (10x10) (grand)
Оролтын JSON (холбогч → адаптер)
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 1,
"legal_moves": [13, 14, 25, 42, 63, 65, 66],
"game_mode": "grand",
"board_size": 10,
"blocked_squares": [],
"placed": {
"1": 4,
"2": 4
},
"remaining_ms": 60000,
"match_id": 123,
"leg": 0,
"revision": 0,
"history": [],
"round_no": null,
"room_created_at": null,
"budget_ms": 10000
}Хариу JSON (адаптер → холбогч)
{"move":13}Octagon (octagon)
Оролтын JSON (холбогч → адаптер)
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 1,
"legal_moves": [13, 14, 25, 42, 63, 65, 66],
"game_mode": "octagon",
"board_size": 10,
"blocked_squares": [0, 1, 10, 8, 9, 19, 80, 90, 91, 89, 98, 99],
"placed": {
"1": 4,
"2": 4
},
"remaining_ms": 60000,
"match_id": 123,
"leg": 0,
"revision": 0,
"history": [],
"round_no": null,
"room_created_at": null,
"budget_ms": 10000
}Хариу JSON (адаптер → холбогч)
{"move":13}Сонгодог реверси (reversi)
Оролтын JSON (холбогч → адаптер)
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 1,
"legal_moves": [18, 25, 33, 41, 42, 50, 51],
"game_mode": "reversi",
"board_size": 8,
"blocked_squares": [],
"placed": {
"1": 6,
"2": 6
},
"remaining_ms": 60000,
"match_id": 123,
"leg": 0,
"revision": 0,
"history": [],
"round_no": null,
"room_created_at": null,
"budget_ms": 10000
}Хариу JSON (адаптер → холбогч)
{"move":18}Түгээмэл асуудал
| Шинж тэмдэг | Шалтгаан ба засвар |
|---|---|
| Бот саарал цэгтэй (офлайн). | Холбогч программын цонх ажилласаар байгаа эсэхийг шалгана. Цонхоо хаах, Ctrl+C дарах эсвэл компьютер унтах горимд орох үед зогсоно. 6, 7-р алхмыг давтаад Шинэчлэх товчийг дарна. |
Команд олдсонгүй гэж гарна.command not found / is not recognized | Python суулгаагүй, эсвэл суулгасны дараа цонхоо дахин нээгээгүй. 5-р алхмыг үзээд шинэ цонх нээж 4-р алхмаас дахин эхэлнэ. |
Файлыг нээх боломжгүй гэж гарна.can't open file | Та бот хавтсаас гадна ажиллуулсан байна. 4-р алхмын адилаар бот хавтас руу шилжиж, ls-ээр README.md болон tools жагсаалтад байгаа эсэхийг шалгана. |
Токен байхгүй гэж гараад хаагдана.FS_BOT_TOKEN is missing or invalid | Энэ цонхонд токен алга. Шинэ цонх нээсэн бол 6-р алхмыг давтана. |
Токеныг татгалзсан гэж гараад зогсоно.Bot credential rejected | Токеныг буруу буулгасан эсвэл хуучин токен байна. Шинэ токен үүсгэсэн эсвэл ботыг идэвхгүй болгосны дараа хуучин токен ажиллахаа болино. Хамгийн сүүлийн токеноор 6-р алхмаас дахин эхэлнэ. |
Нэг алдааны мөр дахин дахин гарна.Connection/state error | Интернэт холболтоо шалгана. macOS дээр 5-р алхмын Install Certificates.command-г ажиллуулсан эсэхээ шалгана. Зөвхөн өрөгийн үеэр гарч байвал сервер таны хөдөлгүүрийн нүүдлийг буруу гэж татгалзаж байж магадгүй. Холбогч программ ижил нүүдлийг дахин илгээдэг тул хөдөлгүүрийг засах шаардлагатай. |
| Урих товч ажиллахгүй, эсвэл урилгыг зөвшөөрөхгүй байна. | Хоёр бот хоёулаа ногоон цэгтэй байх ёстой. Миний тоглох бот хэсэгт таны бот сонгогдсон эсэхийг шалгана. Өөр өрөг тоглож байгаа бот шинэ урилга хүлээж авахгүй. Зөвшөөрөгдөөгүй урилга 120 секундын дараа хүчингүй болно. |
Бот нүүдэл хийхгүй, дараа нь цагаар ялагдах эсвэл өрөг цуцлагдана.Engine failed for match | Хөдөлгүүр цагтаа хариулаагүй, эсвэл хариу нь буруу форматтай байсан. Хөдөлгүүрийн команд болон нэг мөр JSON гаралтыг шалгана. Бот эхэлснээс хойш 30 секундэд эхний нүүдлээ хийхгүй бол өрөг цуцлагдана. |
| Хувилбар тоглоомын урилга ирэхгүй байна. | Урилгын цонхонд зөвхөн хоёр бот хоёулаа дэмждэг тоглоом харагдана. Тухайн тоглоом таны ботын Дэмжих тоглоом хэсэгт сонгогдсон, нөгөө бот ч бас дэмждэг эсэхийг шалгана. NBoard-оор холбогдсон ботод зөвхөн Стандарт сонгогдсон байх ёстой. |
Нэр томьёо
| Нэр томьёо | Утга |
|---|---|
| API | Программууд хүсэлт, хариу илгээх тохиролцсон арга. Үүнийг холбогч программ таны өмнөөс хийнэ. |
| Токен | Зөвхөн таны ботод зориулсан нууц үг. Холбогч программ үүгээр аль бот болохоо серверт батална. |
| Терминал | Команд бичдэг цонх. Windows дээр PowerShell ашиглана. |
| Орчны хувьсагч | Нэг терминалын цонхноос эхлүүлсэн программуудад дамжуулдаг түр тохиргоо. Цонхыг хаахад алга болно. |
| JSON | Өгөгдлийг бичвэр хэлбэрээр бичих формат. Жишээ: {"move":19} |
| Хөдөлгүүр | Байрлалыг харж нүүдэл сонгодог программ. |
| Адаптер | Таны хөдөлгүүр болон холбогч программын хооронд өгөгдөл хөрвүүлдэг жижиг программ. |
| NBoard | NBoard нь NTest-тэй хамт ашиглаж болох Отеллогийн дүрстэй програм юм. NBoard протокол нь энэ програм ба хөдөлгүүрийн нийтэд нээлттэй харилцах хэлбэр бөгөөд NTest, Edax зэрэг үүнийг дэмждэг хөдөлгүүртэй ажиллана. |
| Зөв нүүдэл | Одоо тавьж болох нүд. Сервер эдгээрийг legal_moves-д жагсаана. |
Татах
Татахын тулд нэвтэрнэ үү. .zip нь заавар, холбогч, жишээ хөдөлгүүртэй; .json нь API тодорхойлолт, .md нь заавар юм.
Дэлгэрэнгүй тодорхойлолт
Энэ хуудасны үлдсэн хэсэг нь хөдөлгүүр эсвэл API-тай шууд ажилладаг хөгжүүлэгчдэд зориулсан дэлгэрэнгүй лавлагаа юм.
Холбогч программын тохиргоо
tools/bot_match_client.py-ийн тохиргоо. --engine болон --nboard / --edax / --egaroucid-оос яг нэгийг заавал зааж өгнө. Токеныг хэзээ ч тохиргоогоор өгөхгүй; зөвхөн FS_BOT_TOKEN орчны хувьсагчаас уншина. Гарах код: 0 хэвийн зогсолт, 2 токеныг татгалзсан, 3 --max-runtime-д хүрсэн.
| Параметрүүд | Тайлбар |
|---|---|
--engine "COMMAND" | Тоглолт бүрд энэ командыг нэг удаа асааж ажиллуулсаар, оролтыг нь хаалгүйгээр нүүдэл бүрд JSON нэг мөр солилцоно. Нэг мөр хариулаад хаагддаг хөдөлгүүрийг дараагийн нүүдэлд дахин асаана. |
--nboard "COMMAND" | Өрөг бүрд нэг, нийт хоёр NBoard хөдөлгүүрийг ажиллуулсаар байлгана. Зөвхөн ердийн (std). |
--edax PATH | Edax-г доорх --edax сонголтод ажиллах файлын замыг өгч бас холбож болно. Тусдаа адаптер хэрэггүй; холбогч үлдсэн тоглолтын цагаас нүүдэл бүрийн бодох хугацааг хуваарилна. |
--edax-eval PATH | Edax-ийн eval.dat файлын зам. Заагаагүй бол ажиллах файлын хавтас эсвэл түүний дээд хавтас дахь data/eval.dat-г хайна. |
--egaroucid PATH | Egaroucid for Console-г бэлтгэнэ үү. Дэлгэцтэй програмын оронд консоль файлыг сонгож, resources хавтсыг байранд нь үлдээнэ. macOS, Linux дээр албан ёсны заавраар бүтээсэн файлыг ашиглана. Холбогч setboard, settime, go командаар байрлал ба үлдсэн хугацааг дамжуулах тул адаптер хэрэггүй. |
--nboard-depth N | NBoard хөдөлгүүрт set depth N илгээнэ. 0-ээс 60; 0 бол хөдөлгүүрийн анхдагч утгыг хэвээр үлдээнэ. (--edax: 0 → 60). |
--max-think-seconds S | Нүүдэл бүрд хөдөлгүүрийг хүлээх дээд секунд. Анхдагч 10, дээд тал нь 300. Үлдсэн цагаас 0.75 секунд хассанаас хэзээ ч урт байхгүй. Энэ нь холбогч программын хамгаалалтын хязгаар; серверт нэг нүүдлийн хугацааны хязгаар байхгүй. 0 утга нь нэг нүүдлийн хязгаарыг авч, тоглолтын үлдсэн хугацааг ашиглана. |
--engine-name NAME | Ботын мэдээлэлд мэдээлэх хөдөлгүүрийн нэр (120 тэмдэгтээс ихгүй). Команд эсвэл зам бүү оруул. |
--cpu-name NAME | Мэдээлэх CPU-ийн нэр (120 тэмдэгтээс ихгүй). Орхивол автоматаар илрүүлнэ. |
--once-match ID | Зөвхөн энэ тоглолтыг боловсруулж, тоглолт дуусахад (finished, aborted, expired, rejected) гарна. Хүнтэй тоглолтын сөрөг ID ч ажиллана. Туршилтад --max-runtime-тай хослуулна. |
--max-runtime S | Ийм олон секундын дараа хөдөлгүүрүүдийг цэвэрлэж гарна (гарах код 3). |
--no-stream | Үйл явдлын урсгал ашиглахгүй; зөвхөн асууж шалгана. |
--api URL, --stream-url URL | API болон урсгалын хаяг. Ихэвчлэн анхдагч утгыг нь үлдээнэ. Зөвхөн HTTPS хүлээн авах ба токен хамт илгээгддэг тул урсгал API хост дээр байх ёстой. |
API-г өөрөө хэрэгжүүлэх
Урилга болон байрлалыг agent_poll эсвэл баталгаажсан үйл явдлын урсгалаар хүлээн авна. Та bot_b байгаа хүлээгдэж буй урилгад agent_accept илгээж, дараа нь явагдаж буй тоглолтын өрөг бүрд зөвхөн таны ээлж болсон байрлалыг тооцоолно. match_id, өрөг, revision тус бүрд нэгээс илүүгүй удаа илгээж, төлөв өөрчлөгдвөл хуучирсан тооцоог орхино. Хүнтэй тоглолт сөрөг match_id, leg=0 ашиглах ба round_no, room_created_at-ийг яг хүлээн авсан хэвээр нь илгээх ёстой. Энгийн өрөөнд албадан өнжихийг сервер шийднэ; өнжих нүүдлийг зөвхөн ботуудын хос илгээнэ.
agent_poll / bot-stream → pending (bot_b = my_id)
→ agent_accept → running → legs[0] + legs[1]
→ agent_move(match_id, leg, revision, move) → finished / abortedХувилбар тоглоом
Бот зөвхөн Дэмжих тоглоом хэсэгт сонгосон тоглоомыг хүлээн авна. Хөдөлгүүрийн хүсэлт болон тоглолтын төлөв дэх game_mode нь ямар тоглоом болохыг заана. Самбарын хэмжээ, хаалттай нүд, зөв нүдийг сервер тооцоолдог тул хөдөлгүүр зөвхөн хүлээн авсан legal_moves-оос сонгоход хангалттай. 10×10 эсвэл сонгодог Reversi-ийн нүүдлийг ердийн 8×8 нүүдэл үүсгэгчээр бүү үүсгэ.
| Тоглоом | game_mode | Самбар | Эхлэлийн чулуу | Цаг (өрөг тус бүр, өнгө тус бүр) | Харын эхний legal_moves |
|---|---|---|---|---|---|
| Стандарт | std | 8×8 | Санамсаргүй 12 чулуу | 60,000 ms | Байрлалаас хамаарна |
| Anti | anti | 8×8 | Санамсаргүй 12 чулуу | 60,000 ms | Байрлалаас хамаарна |
| Grand (10x10) | grand | 10×10 | Санамсаргүй 12 чулуу | 60,000 ms | Байрлалаас хамаарна |
| Octagon | octagon | 10×10 (88) | Санамсаргүй 12 чулуу | 60,000 ms | Байрлалаас хамаарна |
| Сонгодог реверси | reversi | 8×8 | Санамсаргүй 12 чулуу | 60,000 ms | Байрлалаас хамаарна |
Нийтлэг дүрэм: Хар (1) эхэлж нүүнэ. Хоёр өрөг ижил байрлалаас өнгөө сольж эхлээд зэрэг явагдана. Ботуудын хос дээр танд зөв нүүдэл байхгүй бол legal_moves хоосон массив болж ирэх ба бот өөрөө move=-1 (өнжих) илгээх ёстой. Сервер таны өмнөөс өнжихгүй, таны цаг үргэлжлэн явна. Зөв нүүдэл байхад өнжих нь дүрмийн зөрчил. Аль ч өнгө нүүж чадахгүй болоход өрөг дуусна. Хоосон нүдийг хэнд ч өгөхгүй; хоёр өрөгийн зөвхөн бодит чулууг нэмж тооцох ба нийлбэр тэнцүү бол тэнцээ. Ботын бүх өрөг санамсаргүй үүсгэсэн 12 чулуутай байрлалаас эхэлнэ. Бүх төрлийн тоглоомд өрөг бүрд бот тус бүр 1 минутын хугацаатай.
Anti: чулуу тавих, эргүүлэх нь ердийн Othello-тэй ижил. Хоёр өрөгт нийт цөөн чулуутай тал ялна.
10x10: 10×10 самбар (100 нүд) дээрх ердийн дүрэм. Эхлэлийн байрлал нь төвийн дөрвөн нүд; ботуудын хос үүн дээр санамсаргүй 8 нүүдэл нэмж, 12 чулуутайгаар эхэлнэ.
Octagon: самбар болон эхлэлийн байрлал нь 10x10-тай ижил боловч булан бүрийн гурван нүд, нийт 12 нүдийг ашиглах боломжгүй (тоглох боломжтой 88 нүд). Хаалттай нүд blocked_squares-д нүдний дугаараар, board-д хоосон нүдтэй ижил 0 утгаар ирнэ. Массив тоон дарааллаар биш. Хаалттай нүдэнд тавьж болохгүй, чулууны шугам тэнд тасарна.
Сонгодог Reversi: дүрмийн дагуу хоосон самбараас эхэлнэ. Төвийн дөрвөн нүдний (27, 28, 35, 36) аль нэг нь хоосон байх үед зөвхөн тэнд тавих ба юу ч эргэхгүй. Дөрвүүлээ дүүрсний дараа ердийн дүрэм үйлчилнэ. Өнгө бүр эхний дөрвөн нүүдлийг оролцуулан дээд тал нь 32 чулуу тавина. placed нь өнгө бүрийн одоог хүртэл тавьсан чулууг тоолно; түлхүүр нь "1" (хар), "2" (цагаан) мөрүүд. Ботуудын хос сервер төвийн дөрвөн нүүдлийг оролцуулан санамсаргүй 12 чулуу тавьсны дараа эхэлдэг тул эхний хүсэлтэд хоёр өнгийн placed утгын нийлбэр 12 байна (ихэвчлэн {"1":6,"2":6}). 32 чулуугаа бүгдийг нь тавьсан өнгө хоосон legal_moves хүлээн авч, ээлж бүртээ -1 илгээнэ.
Тоглоом тус бүрийн хөдөлгүүрийн хүсэлтийн жишээ
Холбогч программ --engine хөдөлгүүрт илгээдэг харын эхний хүсэлтийн жишээнүүд бөгөөд дүрмийн кодоор үүсгэсэн. Бүх төрлийн жинхэнэ тоглолт санамсаргүй 12 чулуутай байрлалаас эхэлдэг тул board болон legal_moves тоглолт бүрд өөр байна. Эдгээр жишээ тогтмол байхын тулд эхлэлийн нүүдлүүдийг самбарын төвд ойр сонгосон. Жинхэнэ тоглолтод match_id болон цагийн утга ч өөр байна.
Anti (anti)
{"board":[0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,0,0,0,0,0,1,2,2,1,0,0,0,0,2,2,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[2,3,12,25,42,44,45],"game_mode":"anti","board_size":8,"blocked_squares":[],"placed":{"1":4,"2":4},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Grand (10x10) (grand)
{"board":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,1,2,2,1,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[13,14,25,42,63,65,66],"game_mode":"grand","board_size":10,"blocked_squares":[],"placed":{"1":4,"2":4},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Octagon (octagon)
{"board":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,1,2,2,1,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[13,14,25,42,63,65,66],"game_mode":"octagon","board_size":10,"blocked_squares":[0,1,10,8,9,19,80,90,91,89,98,99],"placed":{"1":4,"2":4},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Сонгодог реверси (reversi)
{"board":[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,2,2,1,1,0,0,0,0,2,2,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[18,25,33,41,42,50,51],"game_mode":"reversi","board_size":8,"blocked_squares":[],"placed":{"1":6,"2":6},"remaining_ms":60000,"match_id":123,"leg":0,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Хөдөлгүүрийн хүсэлтийн талбар
| Талбар | Төрөл | Тайлбар |
|---|---|---|
game_mode | string | std, anti, grand, octagon, reversi-ийн аль нэг. Хүнтэй тоглолтын XOT нь std болж ирнэ. |
board_size | integer 8 | 10 | 8, grand болон octagon-д 10. |
board | integer[board_size²] | board_size² урттай массив. a1-ээс баруун тийш, дараа нь дараагийн мөрийг уншина. 0=хоосон (Octagon-ий хаалттай нүдийг оролцуулан), 1=хар, 2=цагаан. |
blocked_squares | integer[] | Octagon-ий ашиглах боломжгүй нүд. Бусад тоглоомд хоосон массив. |
placed | {"1": integer, "2": integer} | Өнгө бүрийн одоог хүртэл тавьсан чулуу, эхлэлийн санамсаргүй нүүдлийг оролцуулан; түлхүүр нь "1", "2" мөрүүд. Сонгодог Reversi-ийн 32 чулууны хязгаарт ашиглана. |
legal_moves | integer[] | Одоо тавьж болох нүд. Хоосон бол move=-1 гэж хариулна. |
color | integer 1 | 2 | Нүүх ээлжтэй өнгө. 1=хар, 2=цагаан. |
budget_ms | integer | Энэ нүүдэлд өгсөн хугацаа, миллисекундээр: --max-think-seconds болон үлдсэн цагаас 0.75 секунд хассан утгын бага нь. Хэтэрвэл холбогч программ хөдөлгүүрийг зогсооно. |
remaining_ms | integer | Энэ өрөг дэх таны өнгөний үлдсэн цаг, энэ ээлжинд аль хэдийн зарцуулсан хугацааг хассаны дараах, миллисекундээр. |
match_id | integer ≠ 0 | Тоглолтын ID. Хүнтэй тоглолтод сөрөг (-өрөөний дугаар). |
leg | integer 0 | 1 | Өрөгийн дугаар 0 эсвэл 1. Хүнтэй тоглолтод үргэлж 0. |
revision | integer | Энэ өрөгийн төлөвийн дугаар. agent_move-д өөрчлөхгүйгээр илгээнэ. |
history | array | Энэ өрөгт хийсэн нүүдлүүд. Шийдвэрээ board-оор гаргана. |
round_no | integer | null | Хүнтэй тоглолтын тойргийн дугаар. Ботуудын хосод null. |
room_created_at | string | null | Хүнтэй тоглох өрөө үүссэн цаг. Ботуудын хосод null. |
Өөр ботыг хувилбар тоглоомд урих
agent_challenge-д game_mode нэмнэ; анхдагч нь std. Хоёр бот хоёулаа supported_games-д үүнийг агуулсан байх ёстой. Өрсөлдөгчийн тоглоомыг agent_poll хариуны bots[].supported_games-оос уншина. Аль нэг бот тухайн тоглоомгүй бол доорх алдаатай HTTP 409 хариу ирнэ.
{"action":"agent_challenge","target_id":2,"game_mode":"anti"}
{"action":"agent_challenge","target_name":"Opponent","game_mode":"grand"}HTTP 409
{"ok":false,"error":"unsupported game mode","server_now_ms":1800000000000}supported_games өөрчлөх
Бүртгэлийн маягт Стандарт сонгосон байдлаар эхэлнэ, хадгалсан жагсаалтгүй хуучин ботууд std дэмжинэ. Жагсаалтыг зөвхөн ботын вэб хуудасны Удирдах хэсэгт өөрчилж болох ба ботын токеноор (API) хэзээ ч өөрчлөхгүй. Тоглолт явагдаж байх эсвэл зөвшөөрөл хүлээж байх үед өөрчлөлтийг татгалзана. Хоосон жагсаалт хадгалах боломжгүй.
NBoard ба хувилбар тоглоом
--nboard холболт зөвхөн ердийн (std) тоглоомыг дэмжинэ. Хувилбар тоглоом ирэхэд холбогч программ хөдөлгүүрээс асуухгүй, тэр ээлжийг орхино (Engine failed for match мессеж). Нүүдэл илгээгдэхгүй тул өрөг эхний нүүдлээс өмнө цуцлагдах, эсвэл хожим тэр өрөгт цагаар ялагдана. NBoard ботод дэмжих цорын ганц тоглоом болгож ердийнийг өгнө.
Хүн ба бүртгэлтэй бот
Хүмүүс таны ботыг бүртгэсэн дурын тоглоомд нь урьж болно. Ердийн тоглоомыг дэмждэг бол STD, XOT хоёулаа ирж болно. XOT нь game_mode std-тэй ирэх ба аль хэдийн 8 нүүдэл хийгдсэн самбараас эхэлнэ (тэдгээр нь history-д багтана). Цагийг урьсан хүн сонгох ба өрөг чансаанд нөлөөлөхгүй. Хүнтэй тоглолт нэг өрөг (leg 0), сөрөг match_id-тай. Нүүх боломжгүй үеийн өнжихийг сервер шийддэг тул -1 бүү илгээ. Автомат тааруулалт асаалттай онлайн бүртгэлтэй ботууд дэмждэг STD/XOT хурдан тоглолтод мөн оролцоно. Гишүүдийн хурдан тоглолт рейтингтэй, зочдынх рейтинггүй байна.
Буруу нүүдэл ба цаг
Буруу нүүдэл эсвэл хуучирсан revision-ийг HTTP 409 (illegal_move, stale_revision, not_your_turn)-ээр татгалзах ба самбар өөрчлөгдөхгүй. Энэ хооронд цаг явсаар байна. Холбогч программ ижил нүүдлийг ижил revision-тэй дахин илгээдэг тул хөдөлгүүрийг засахгүй бол тэр өрөгт эцэст нь цагаар ялагдана. Серверт нэг нүүдлийн хязгаар байхгүй, зөвхөн өнгө бүрийн үлдсэн цагийг шалгана. 10 секунд бол холбогч программын --max-think-seconds-ийн анхдагч утга.
Баталгаажуулалт
HTTPS, JSON POST, Authorization: Bearer ашиглана. Токен нэг ботод хамаарна. URL, нийтэд нээлттэй код, логт бүү оруул.
Content-Type: application/json
Authorization: Bearer <FS_BOT_TOKEN>POST https://othelloclub.com/flipsight/bot_match_api.php
Тоглолтын дүрэм
Ботын бүх өрөг санамсаргүй үүсгэсэн 12 чулуутай байрлалаас эхэлнэ. Өнгөө сольж хоёр тоглолтыг зэрэг явуулна. Нийт чулуугаар ялагчийг тогтооно; Anti-д цөөн чулуутай нь ялна.
Ботын бүх өрөг санамсаргүй үүсгэсэн 12 чулуутай байрлалаас эхэлнэ. Бүх төрлийн тоглоомд өрөг бүрд бот тус бүр 1 минутын хугацаатай.
Бот эхэлснээс хойш 30 секундэд эхний нүүдлээ хийхгүй бол тоглолт цуцлагдаж, чансаанд тооцогдохгүй. Тоглолтын үеэр нэг ботын холболт 30 секундээс удаан тасарч, нөгөө нь холбогдсон байвал холбогдсон бот хожно (finish_reason: disconnect), үр дүн чансаанд тооцогдоно.
Бүх төрлийн тоглоомд FlipSight ботын нүүдлийг сервер тооцоолно. Вэбээс болон API-аар (agent_challenge) ирсэн урилгыг хоёуланг нь хүлээн авч, сервер тоглолтыг шууд эхлүүлдэг тул тоглоомын өрөөг нээлттэй байлгах шаардлагагүй. Серверийн тооцоолол 30 секундээс удаан зогсвол тоглолт цуцлагдана (finish_reason: technical), чансаанд тооцогдохгүй. Хувилбар тоглоомын нүүдлийг тооцоолох нь хүнд тул FlipSight боттой хувилбар тоглолт нэг дор хамгийн ихдээ 2 явагдана. Дүүрсэн бол HTTP 409 болон site bot variant matches are full ирнэ; түр хүлээгээд дахин урина уу.
Автомат ботын тоглолт: сайт ботын тоглолтын хоёр өрөөг үргэлж ажиллуулна. Автомат хослол асаалттай бүртгэлтэй бот онлайн, тоглолтгүй байх үед ойролцоо чансаатай боттой (эхлээд өөр бүртгэлтэй бот, байхгүй бол FlipSight бот) энгийн (std) ботын тоглолтын урилга тэр ботод ирнэ (тэр бот bot_b). Холбогч программ урилгыг автоматаар хүлээн авч, тоглолт эхэлнэ. Бот 120 секундэд хүлээн авахгүй эсвэл татгалзвал 10 минутын турш автомат хослолоос хасагдана. Автомат тоглолт чансаанд тооцогдоно. Аренийн тоглолтын үеэр ч ботын автомат тоглолтууд үргэлжилнэ. Автомат хослол анхдагчаар асаалттай бөгөөд ботын хуудасны Удирдах хэсгээс унтрааж болно. Дасгалын хөдөлгүүрээр асаасан бот (environment.practice нь true) автомат тоглолтоос хасагдах бөгөөд энэ хугацаанд бусад боттой тоглосон тоглолт чансаанд тооцогдохгүй.
Хүний шууд урилга нь дэмждэг тоглоом, хугацааг сонгон ердийн өрөөнд нэг тоглолт хийнэ. Сервер шууд урилгад үргэлж рейтинг тооцохгүй. Автомат тааруулалт асаалттай онлайн бүртгэлтэй ботууд дэмждэг STD/XOT хурдан тоглолтод мөн оролцоно. Гишүүдийн хурдан тоглолт рейтингтэй, зочдынх рейтинггүй байна. Бүртгэлтэй бот нь ботын удирдлагын зэрэг тоглолтын тоо (анхдагч 2)-оос илүү тоглолт авахгүй. Хүнтэй хийх нэг тоглолт ба ботуудын нэг тоглолт (2 самбар) тус бүр 1 гэж тоологдоно.
pending → running → finished / aborted
pending → rejected / expired
kind=human: id=-room_id, legs[0], round_no, room_created_at
agent_move: move=19 / "d3" / "D3" (8×8)
10×10: "j10" = "J0" = 99
pass: -1 / "pass" / "PA" / "PS" / "--" (paired games only)
index=row*board_size+column (0-based)Тоглолтын явц
Ботын бүх өрөг санамсаргүй үүсгэсэн 12 чулуутай байрлалаас эхэлнэ. Өнгөө сольж хоёр тоглолтыг зэрэг явуулна. Нийт чулуугаар ялагчийг тогтооно; Anti-д цөөн чулуутай нь ялна.
Та bot_a бол оролцогчийн дугаар 0, bot_b бол 1. Оролцогч 0 нь legs[0]-д хараар (1), legs[1]-д цагаанаар (2) тоглоно; оролцогч 1 эсрэгээрээ. leg.status нь active, leg.turn нь таны өнгөтэй тэнцүү үед таны ээлж. Хоёр өрөгт зэрэг таны ээлж байж болно.
Зөв нүүдэлгүй бол move -1 (өнжих)-ийг өөрөө илгээх ёстой; сервер таны өмнөөс өнжихгүй. Хүнтэй тоглох үед сервер өнжихийг энгийн тоглоомын өрөөтэй адил шийднэ.
Таны ээлжинд үлдсэн хугацаа = clocks_ms[таны өнгө - 1] - (server_now_ms - turn_started_ms). clocks_ms нь өнгөний дарааллаар (хар, цагаан); totals ба winner нь оролцогчийн дарааллаар (winner 0 эсвэл 1, тэнцвэл null).
Нүдний дугаар
Нүдний дугаар = мөр × 8 + багана, тиймээс a1=0, h1=7, a2=8, h8=63. Жишээ нь 19 нь d3, 37 нь f5. board массив мөн ижил дараалалтай: 0=хоосон, 1=хар, 2=цагаан.
a b c d e f g h
1 0 1 2 3 4 5 6 7
2 8 9 10 11 12 13 14 15
3 16 17 18 19 20 21 22 23
4 24 25 26 27 28 29 30 31
5 32 33 34 35 36 37 38 39
6 40 41 42 43 44 45 46 47
7 48 49 50 51 52 53 54 55
8 56 57 58 59 60 61 62 6310×10 (grand, octagon) дээр нүд = мөр × 10 + багана. Баганууд a-аас j хүртэл, арав дахь мөрийг координатад 10 эсвэл 0 гэж бичнэ. a1=0, j1=9, a2=10, j10=99 (j0-тэй ижил). Нэг координат самбарын хэмжээ бүрд өөр дугаартай: d3 нь 8×8 дээр 19, 10×10 дээр 23.
a b c d e f g h i j
1 0 1 2 3 4 5 6 7 8 9
2 10 11 12 13 14 15 16 17 18 19
3 20 21 22 23 24 25 26 27 28 29
4 30 31 32 33 34 35 36 37 38 39
5 40 41 42 43 44 45 46 47 48 49
6 50 51 52 53 54 55 56 57 58 59
7 60 61 62 63 64 65 66 67 68 69
8 70 71 72 73 74 75 76 77 78 79
9 80 81 82 83 84 85 86 87 88 89
10 90 91 92 93 94 95 96 97 98 99Octagon (octagon)
a b c d e f g h i j
1 ## ## 2 3 4 5 6 7 ## ##
2 ## 11 12 13 14 15 16 17 18 ##
3 20 21 22 23 24 25 26 27 28 29
4 30 31 32 33 34 35 36 37 38 39
5 40 41 42 43 44 45 46 47 48 49
6 50 51 52 53 54 55 56 57 58 59
7 60 61 62 63 64 65 66 67 68 69
8 70 71 72 73 74 75 76 77 78 79
9 ## 81 82 83 84 85 86 87 88 ##
10 ## ## 92 93 94 95 96 97 ## ##Үйл явдлын урсгал
Ижил Bearer токеноор GET https://othelloclub.com/flipsight_api/bot-stream-д холбогдож, мөр бүрд нэг JSON үйл явдал (NDJSON) авна: hello холболтыг баталгаажуулна, match нь таны аль нэг тоглолт өөрчлөгдсөнийг заана (ботуудын хоорондох тоглолтын үйл явдал бүтэн тоглолтын объектыг агуулна), ping нь 10 секунд тутам холболтыг хадгална. match ирвэл agent_poll-ыг нэг удаа дуудна. Холболт тасарвал 1-ээс 30 секунд хүртэл өсөх хугацаагаар дахин холбогдож, энэ хооронд асуулгаа үргэлжлүүлнэ. Урсгал холбогдсон үед таны бот онлайн харагдана; бот бүр 3 хүртэл урсгал нээж болно.
Үйл явдлын жишээ
curl -N 'https://othelloclub.com/flipsight_api/bot-stream' \
-H "Authorization: Bearer $FS_BOT_TOKEN"
{"type":"hello","bot_id":1,"server_now_ms":1800000000000}
{"type":"match","match":{"id":123,"bot_a":1,"bot_b":2,"status":"running","state":{...}},"server_now_ms":1800000000500}
{"type":"match","match":{"id":-45,"kind":"human","room_id":45},"server_now_ms":1800000003000}
{"type":"ping","server_now_ms":1800000010000}Хөдөлгүүрийн холбогч
FlipSight ботын холболтын програм (Python 3.9+, зөвхөн стандарт сан) Windows, macOS, Linux дээр ажиллаж, хөдөлгүүрийг хоёр аргаар холбоно. --engine тоглолт бүрд хөдөлгүүрийг нэг удаа асааж ажиллуулсаар байх ба нүүдэл бүрд JSON нэг мөр илгээж {"move": нүд} нэг мөр уншина. Нэг мөр хариулаад хаагддаг хөдөлгүүр дараагийн нүүдэлд дахин асдаг тул ажилласаар байна, харин оролтыг эцэс хүртэл уншдаг хөдөлгүүр (sys.stdin.read() гэх мэт) хэзээ ч хариулахгүй тул нэг нэг мөрөөр уншуулна уу. Хүсэлтийн legal_moves нь хууль ёсны нүднүүдийн жагсаалт; хоосон бол -1 гэж хариулна. --nboard нь NBoard протоколын хөдөлгүүрийг тоглолт бүрд нэгийг ажиллуулсаар байх ба хайлтын гүнийг --nboard-depth-ээр тогтооно.
Edax-г доорх --edax сонголтод ажиллах файлын замыг өгч бас холбож болно. Тусдаа адаптер хэрэггүй; холбогч үлдсэн тоглолтын цагаас нүүдэл бүрийн бодох хугацааг хуваарилна.
Egaroucid for Console-г бэлтгэнэ үү. Дэлгэцтэй програмын оронд консоль файлыг сонгож, resources хавтсыг байранд нь үлдээнэ. macOS, Linux дээр албан ёсны заавраар бүтээсэн файлыг ашиглана. Холбогч setboard, settime, go командаар байрлал ба үлдсэн хугацааг дамжуулах тул адаптер хэрэггүй.
Оролтын JSON (холбогч → адаптер)
Энэ нь ажиллуулах код биш, холбогчоос илгээдэг өгөгдлийн жишээ юм. Python файл болгон хадгалах шаардлагагүй. Тоглолтын үеэр холбогч ээлж бүрд одоогийн өгөгдлийг автоматаар илгээнэ.
{"board":[0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,0,0,0,0,0,1,2,2,1,0,0,0,0,2,2,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"color":1,"legal_moves":[2,3,12,25,42,44,45],"game_mode":"std","board_size":8,"blocked_squares":[],"placed":{"1":4,"2":4},"remaining_ms":40000,"match_id":123,"leg":1,"revision":0,"history":[],"round_no":null,"room_created_at":null,"budget_ms":10000}Хариу JSON (адаптер → холбогч)
{"move":2}Төлөв синхрончлох
Урсгал холбогдсон үед үйл явдал ирэхэд болон 10 секунд тутам agent_poll дуудна. Урсгалгүй асуух үед тоглолтын үеэр секунд тутам, сул үед 5 секунд тутам дуудах ба хэзээ ч секундэд нэгээс олон удаа дуудахгүй. Сүлжээний хугацаа таны цагаас хасагдана. Нүүдлийн хариу алдагдвал шинэ төлөвийг асууж, revision өөрчлөгдөөгүй үед л ижил нүүдлийг дахин илгээнэ.
API үйлдлүүд
Хариуны жишээ нь хэлбэрийг харуулна. Хуулах товч зөвхөн хүсэлтийг хуулах ба API дуудахгүй.
POST agent_poll
Төлөв авах
| Параметрүүд | Төрөл | Заавал | Тайлбар |
|---|---|---|---|
action | string "agent_poll" | Заавал | Дуудах үйлдлийн нэр |
environment | object | Сонголттой | Холбогч ажиллаж буй компьютерийн CPU, OS, хөдөлгүүрийн нэр (тус бүр 120 тэмдэгт хүртэл, сонголттой) болон practice (true эсвэл false, сонголттой). practice нь true бол бот дасгал хийж байна гэсэн үг: автомат тоглолтоос хасагдах бөгөөд энэ хугацаанд хүссэн эсвэл зөвшөөрсөн ботын тоглолт чансаанд тооцогдохгүй. Холбогч дасгалын хөдөлгүүрээр асахдаа энэ утгыг өөрөө илгээнэ. Сервер хамгийн сүүлд авсан утгыг санадаг тул дасгал дуусахад practice-гүй эсвэл false утгатай илгээнэ. |
Хүсэлтийн жишээ
curl 'https://othelloclub.com/flipsight/bot_match_api.php' \
-H "Authorization: Bearer $FS_BOT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"action":"agent_poll","environment":{"cpu":"Apple M4","engine":"MyEngine","os":"Darwin"}}'Хариуны жишээ
{
"ok": true,
"bots": [
{
"id": 1,
"name": "Opponent",
"owner_id": "example",
"owner_name": "Example",
"owner": {
"player_id": "example",
"name": "Example",
"photo": "/img/no_profile.gif",
"country_code": "",
"country_name": "",
"country_flag_url": "",
"donor": false,
"verified_player_id": ""
},
"engine_level": null,
"rating": {
"rating": 1200,
"rd": 300,
"official": false,
"official_progress": {
"kind": "provisional",
"current": 0,
"required": 50
},
"color": "pz-rating-unofficial",
"high_rating": 1200,
"wins": 0,
"losses": 0,
"draws": 0,
"streak": 0,
"best_streak": 0
},
"supported_games": ["std"],
"auto_match": true,
"bio": "",
"registered_at": "2026-11-12 18:00:00",
"registered_at_ts": 1794474000,
"environment": {
"cpu": "Apple M4",
"engine": "MyEngine",
"os": "Darwin",
"practice": false
},
"is_builtin": false,
"online": true,
"disabled": false,
"deleted": false,
"photo": "/flipsight/bot_match_api.php?action=photo&bot_id=1&v=1794474000000"
},
{
"id": 2,
"name": "MyBot",
"owner_id": "example",
"owner_name": "Example",
"owner": {
"player_id": "example",
"name": "Example",
"photo": "/img/no_profile.gif",
"country_code": "",
"country_name": "",
"country_flag_url": "",
"donor": false,
"verified_player_id": ""
},
"engine_level": null,
"rating": {
"rating": 1200,
"rd": 300,
"official": false,
"official_progress": {
"kind": "provisional",
"current": 0,
"required": 50
},
"color": "pz-rating-unofficial",
"high_rating": 1200,
"wins": 0,
"losses": 0,
"draws": 0,
"streak": 0,
"best_streak": 0
},
"supported_games": ["std", "anti"],
"auto_match": true,
"bio": "",
"registered_at": "2026-11-12 18:00:00",
"registered_at_ts": 1794474000,
"environment": {
"cpu": "Apple M4",
"engine": "MyEngine",
"os": "Darwin",
"practice": false
},
"is_builtin": false,
"online": true,
"disabled": false,
"deleted": false,
"photo": "/flipsight/bot_match_api.php?action=photo&bot_id=2&v=1794474000000"
}
],
"record_bots": [],
"matches": [
{
"id": 123,
"bot_a": 1,
"bot_b": 2,
"game_mode": "std",
"time_limit_sec": 60,
"status": "running",
"state": {
"version": 1,
"game_mode": "std",
"time_limit_sec": 60,
"status": "active",
"revision": 1,
"started_ms": 1799999980000,
"last_now_ms": 1799999984200,
"finished_ms": null,
"opening_moves": [19, 20, 29, 34, 26, 11, 43, 37],
"opening_history": [
{
"color": 1,
"move": 19
},
{
"color": 2,
"move": 20
},
{
"color": 1,
"move": 29
},
{
"color": 2,
"move": 34
},
{
"color": 1,
"move": 26
},
{
"color": 2,
"move": 11
},
{
"color": 1,
"move": 43
},
{
"color": 2,
"move": 37
}
],
"legs": [
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 2, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"turn": 2,
"black_participant": 0,
"placed": {
"1": 5,
"2": 4
},
"clocks_ms": [55800, 60000],
"turn_started_ms": 1799999984200,
"revision": 1,
"history": [
{
"color": 1,
"participant": 0,
"move": 44,
"at_ms": 1799999984200
}
],
"status": "active",
"discs": [5, 8],
"finished_ms": null,
"legal_moves": [18, 21, 22, 25, 30, 33, 38, 42, 50, 51, 52]
},
{
"board": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"turn": 1,
"black_participant": 1,
"placed": {
"1": 4,
"2": 4
},
"clocks_ms": [60000, 60000],
"turn_started_ms": 1799999980000,
"revision": 0,
"history": [],
"status": "active",
"discs": [3, 9],
"finished_ms": null,
"legal_moves": [2, 3, 12, 25, 42, 44, 45]
}
],
"totals": [14, 11],
"winner": null,
"finish_reason": null,
"board_size": 8,
"blocked_squares": []
},
"auto": false,
"expires_ms": 1800000080000,
"ranked": true,
"rating_applied": false,
"rating_before": [null, null],
"rating_after": [null, null],
"created_at": "2026-11-12 19:00:00"
}
],
"me": "example",
"bot": {
"id": 2,
"name": "MyBot",
"owner_id": "example",
"owner_name": "Example",
"owner": {
"player_id": "example",
"name": "Example",
"photo": "/img/no_profile.gif",
"country_code": "",
"country_name": "",
"country_flag_url": "",
"donor": false,
"verified_player_id": ""
},
"engine_level": null,
"rating": {
"rating": 1200,
"rd": 300,
"official": false,
"official_progress": {
"kind": "provisional",
"current": 0,
"required": 50
},
"color": "pz-rating-unofficial",
"high_rating": 1200,
"wins": 0,
"losses": 0,
"draws": 0,
"streak": 0,
"best_streak": 0
},
"supported_games": ["std", "anti"],
"auto_match": true,
"bio": "",
"registered_at": "2026-11-12 18:00:00",
"registered_at_ts": 1794474000,
"environment": {
"cpu": "Apple M4",
"engine": "MyEngine",
"os": "Darwin",
"practice": false
},
"is_builtin": false,
"online": true,
"disabled": false,
"deleted": false,
"photo": "/flipsight/bot_match_api.php?action=photo&bot_id=2&v=1794474000000"
},
"server_now_ms": 1800000000000
}Тоглолтын объект (matches[])
| Талбар | Төрөл | Тайлбар |
|---|---|---|
id | integer | Тоглолтын ID (хүнтэй тоглоход сөрөг) |
kind | string | Хүнтэй тоглоход human |
bot_a | integer | Оролцогч 0-ийн ботын ID (хүн бол 0) |
bot_b | integer | Оролцогч 1-ийн ботын ID (хүн бол 0) |
game_mode | string | Тоглоом (std, anti, grand, octagon, reversi) |
time_limit_sec | integer | Өрөг тус бүр, өнгө тус бүрд өгөх секунд |
status | string | pending, running, finished, aborted, rejected, expired |
expires_ms | integer | Зөвшөөрөх эцсийн хугацаа (миллисекунд) |
ranked | boolean | Тоглолт чансаанд тооцогдох эсэх |
state.status | string | active, finished эсвэл aborted |
state.game_mode | string | Тоглоом (std, anti, grand, octagon, reversi) |
state.board_size | integer 8 | 10 | Нэг талын нүдний тоо, 8 эсвэл 10 |
state.blocked_squares | integer[] | Ашиглах боломжгүй нүд (зөвхөн Octagon, эрэмбэлээгүй) |
state.legs | array | Өрөгүүд (ботуудын хооронд 2, хүнтэй 1) |
state.totals | [integer, integer] | Оролцогч тус бүрийн хоёр өрөгийн чулууны нийлбэр |
state.winner | integer | null | Хожсон оролцогч 0 эсвэл 1, тэнцвэл null |
state.finish_reason | string | null | discs, timeout, double_timeout, disconnect, no_first_move |
Өрөгийн объект (state.legs[])
| Талбар | Төрөл | Тайлбар |
|---|---|---|
board | integer[64 | 100] | 64 / 100 нүд, 0=хоосон 1=хар 2=цагаан |
turn | integer | Нүүх өнгө, 1 (хар) эсвэл 2 (цагаан) |
legal_moves | integer[] | Нүүх ээлжтэй өнгөний зөв нүд. Дууссан өрөгт хоосон |
placed | {"1": integer, "2": integer} | Өнгө бүрийн тавьсан чулуу, түлхүүр нь "1" (хар), "2" (цагаан) |
black_participant | integer | Энэ өрөгт хараар тоглох оролцогч |
clocks_ms | [number, number] | Өнгөний дарааллаарх (хар, цагаан) үлдсэн хугацааны суурь утга |
turn_started_ms | integer | Одоогийн ээлж эхэлсэн серверийн цаг |
revision | integer | Энэ өрөг өөрчлөгдөх бүрд 1-ээр нэмэгдэнэ |
status | string | active, finished, timeout, stopped |
history | array | Хийсэн нүүдлүүд (color, participant, move, at_ms) |
discs | [integer, integer] | Өнгөний дарааллаарх (хар, цагаан) чулууны тоо |
result_discs | [integer, integer] (optional) | Цагаар ялагдсан өрөгт өгөх сонголттой шүүгчийн оноо [хар, цагаан]. Нийлбэрийг чулууны тооны оронд үүгээр тооцно. Цаг нь дууссан тал болон түүний өрсөлдөгчийн оноо: std ба reversi 0-ээс 64, grand 0-ээс 100, octagon 0-ээс 88, anti 64-өөс 0. Нөгөө өрөг үргэлжилж, хоёр өрөг дууссаны дараа нийлбэрээр ялагчийг тогтооно. Өмнө нь дууссан бичлэгийг дахин тооцохгүй. |
POST agent_challenge
Урих
Өрсөлдөгчийг target_id (ботын дугаар) эсвэл target_name (ботын нэр)-ээр заана; эдгээрийг agent_poll хариултын bots жагсаалтаас харна. FlipSight-ийн суурилсан ботуудыг (is_builtin: true) бүх төрлийн тоглоомд API-аар урьж болох бөгөөд сервер тоглолтыг шууд эхлүүлнэ. Суурилсан боттой хувилбар тоглолт аль хэдийн 2 явагдаж байвал HTTP 409 болон site bot variant matches are full алдаа ирнэ.
| Параметрүүд | Төрөл | Заавал | Тайлбар |
|---|---|---|---|
action | string "agent_challenge" | Заавал | Дуудах үйлдлийн нэр |
target_id | integer ≥ 1 | Сонголттой | Урих ботын ID |
target_name | string | Сонголттой | Урих ботын нэр (target_id-ийн оронд) |
game_mode | string std | anti | octagon | grand | reversi | Сонголттой | Ботуудын хосын тоглоом. Анхдагч нь std. Хоёр бот хоёулаа дэмжих ёстой. Стандарт / Anti / Octagon / Grand (10x10) / Сонгодог реверси |
Хүсэлтийн жишээ
curl 'https://othelloclub.com/flipsight/bot_match_api.php' \
-H "Authorization: Bearer $FS_BOT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"action":"agent_challenge","target_id":2,"game_mode":"anti"}'Хариуны жишээ
{
"ok": true,
"match_id": 123,
"server_now_ms": 1800000000000
}POST agent_accept
Зөвшөөрөх
| Параметрүүд | Төрөл | Заавал | Тайлбар |
|---|---|---|---|
action | string "agent_accept" | Заавал | Дуудах үйлдлийн нэр |
match_id | integer ≥ 1 | Заавал | Тоглолтын ID (хүнтэй тоглоход сөрөг) |
Хүсэлтийн жишээ
curl 'https://othelloclub.com/flipsight/bot_match_api.php' \
-H "Authorization: Bearer $FS_BOT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"action":"agent_accept","match_id":123}'Хариуны жишээ
{
"ok": true,
"match": {
"id": 123,
"status": "running",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}POST agent_reject
Татгалзах
| Параметрүүд | Төрөл | Заавал | Тайлбар |
|---|---|---|---|
action | string "agent_reject" | Заавал | Дуудах үйлдлийн нэр |
match_id | integer ≥ 1 | Заавал | Тоглолтын ID (хүнтэй тоглоход сөрөг) |
Хүсэлтийн жишээ
curl 'https://othelloclub.com/flipsight/bot_match_api.php' \
-H "Authorization: Bearer $FS_BOT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"action":"agent_reject","match_id":123}'Хариуны жишээ
{
"ok": true,
"match": {
"id": 123,
"status": "rejected",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}POST agent_move
Нүүдэл илгээх
| Параметрүүд | Төрөл | Заавал | Тайлбар |
|---|---|---|---|
action | string "agent_move" | Заавал | Дуудах үйлдлийн нэр |
match_id | integer ≠ 0 | Заавал | Тоглолтын ID (хүнтэй тоглоход сөрөг) |
round_no | integer ≥ 0 | Сонголттой | Зөвхөн хүнтэй тоглоход: тоглолтын объектын round_no |
room_created_at | string | Сонголттой | Зөвхөн хүнтэй тоглоход: тоглолтын объектын room_created_at |
leg | integer 0 | 1 | Заавал | Өрөг 0 эсвэл 1 (хүнтэй тоглоход 0) |
revision | integer ≥ 0 | Заавал | Нүүдлийг тооцоолсон өрөгийн revision; өрөг өөрчлөгдсөн бол 409 stale_revision |
move | integer -1..99 | string | Заавал | Нүд 0-(board_size²−1), өнжихөд -1 / d3 / D3 / pass |
Хүсэлтийн жишээ
curl 'https://othelloclub.com/flipsight/bot_match_api.php' \
-H "Authorization: Bearer $FS_BOT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"action":"agent_move","match_id":123,"leg":1,"revision":0,"move":2}'Хариуны жишээ
{
"ok": true,
"match": {
"id": 123,
"status": "running",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}Алдаа
Алдаа {"ok": false, "error": "…"} хэлбэртэй. 401 бол зогсоож токеноо шалгана. 409 бол одоогийн төлөвийг асууж ээлж, revision, зөв нүүдлийг шалгана. 429 нь нэг ботод хэт олон урсгал байна гэсэн үг. Холболтын алдаа болон 503-ыг өсөх хугацаагаар дахин оролдох ба буруу нүүдлийг хэзээ ч дахин илгээхгүй.
{"ok":false,"error":"stale_revision","server_now_ms":1800000000000}| HTTP | error |
|---|---|
| 400 | JSON object required / unknown action |
| 401 | invalid bot credential |
| 403 | access denied / invalid csrf |
| 405 | POST required |
| 409 | stale_revision / not_your_turn / illegal_move / leg_finished / match not running / match timed out / stale room revision / invalid move coordinate / move outside board / unsupported game mode / both bots must be connected / bot already has an active match / bot busy / challenge expired or answered / site bot variant matches are full / target bot not found |
| 413 | request too large |
| 429 | too many streams (bot-stream) |
| 503 | bot match storage unavailable |