Yeni başlayanlar için adım adım rehber
Gerekenler
- Bir FlipSight hesabı. Giriş yaptıktan sonra bot kaydedebilir ve bağlantı programını indirebilirsiniz.
- Bir bot fotoğrafı: en fazla 5 MB, genişliği ve yüksekliği en az 175 px olan bir GIF, JPG veya PNG dosyası.
- Botu çalıştıracağın kendi bilgisayarın Botunuzun hamleleri, bağlantı programının çalıştığı bilgisayarda hesaplanır. Aynı motorla bile güç, bilgisayarın performansına ve motor ayarlarına göre değişebilir; bilgisayarı veya ayarları değiştirirseniz puan da buna göre değişebilir.
- Python 3, bağlantı programını çalıştıran ücretsiz bir program. 3.9 veya sonrası çalışır; 3.11 veya sonrası önerilir. Bunu 5. adımda kontrol edeceksiniz.
- Kendi bot motorun. Bağlantı programına test için bir alıştırma motoru dahildir.
1. Botunuzu kaydedin
Giriş yapın ve bot sayfasını (othelloclub.com/tr/flipsight/bot) açın. Üstteki Botumu kaydet kutusunda Bot adı (2–24 karakter) alanına bir ad yazın. Desteklenen oyunlar bölümünde şimdilik yalnızca Standart işaretli kalsın. Bot fotoğrafı yükle alanından bir resim seçin, sonra Botumu kaydet düğmesine basın.
Başarılıysa şöyle görünür: Bağlantı belirteci (yalnız bir kez gösterilir) kutusu, fsbm_ ile başlayan uzun bir metinle açılır.
2. Belirteci saklayın
Bu uzun metin belirteçtir, yani yalnızca botunuza ait bir paroladır. Bağlantı programı, bu bot adına konuştuğunu sunucuya bununla kanıtlar. Tamamını kopyalayın ve metin düzenleyici gibi geçici bir yere yapıştırın. Kutuyu kapattıktan sonra aynı belirteci bir daha göremezsiniz.
Belirteci bir parola gibi koruyun. Kimseye göstermeyin ve ekran görüntüsünü paylaşmayın. Kaybederseniz veya biri görürse bot listesinde Yönet bölümünü açın ve Bağlantı belirteci oluştur düğmesine basın. Yeni belirteci aldığınızda eskisi hemen çalışmaz olur.
3. Bağlantı programını indirin
ZIP dosyasını indirmek için Python örneklerini indir düğmesine basın ve dosyayı çıkarın. Bu rehber çıkarılan klasöre "bot klasörü" der. Klasörü masaüstü gibi kolay bulunan bir yere koyun.
Başarılıysa şöyle görünür: bot klasöründe README.md dosyası ve tools klasörü vardır.
4. Bot klasöründe bir terminal açın
Terminal, komut yazdığınız bir penceredir. Sisteminize göre aşağıdaki gibi açın.
macOS: Command+Space tuşlarına basın, Terminal yazın ve açın. cd yazıp bir boşluk bırakın, bot klasörünü pencereye sürükleyin, sonra Enter'a basın.
Linux: dosya yöneticisinde bot klasörüne sağ tıklayın ve "Uçbirimde Aç" (Open in Terminal) seçeneğini seçin. Menü adı dağıtıma göre değişebilir. Böyle bir menü yoksa bir terminal açın ve macOS'taki gibi cd kullanın.
Windows: bot klasörünü Dosya Gezgini'nde açın. Üstteki adres çubuğuna powershell yazın ve Enter'a basın. O klasörde bir PowerShell penceresi açılır.
Kontrol: aşağıdaki komutu yazın ve Enter'a basın. Listede README.md ve tools görünüyorsa başarılıdır. Bu komut macOS, Linux ve Windows PowerShell'de aynıdır.
ls5. Python'u kontrol edin
Aynı pencerede sisteminize uygun tek komutu kopyalayın, yapıştırın ve Enter'a basın. Her kod kutusunun sağ üstündeki kopyalama düğmesini kullanabilirsiniz.
macOS / Linux
python3 --versionWindows PowerShell
py --versionBaşarılıysa şöyle görünür: Python 3.11.9 gibi 3 ile başlayan bir sürüm. 3.9 veya sonrası çalışır. Komut bulunamazsa Python'u aşağıdaki gibi kurun, pencereyi kapatın ve 4. adımdan yeniden başlayın.
macOS: python.org'dan macOS yükleyicisini (.pkg) indirin ve kurun. Sonra Uygulamalar içindeki Python klasöründen Install Certificates.command dosyasını bir kez çalıştırın. Bu, güvenli (HTTPS) bağlantılar için gereken sertifikaları hazırlar.
Linux: python3'ü dağıtımınızın yazılım yöneticisi veya paket yöneticisiyle kurun.
Windows: python.org'dan Python kurulum yöneticisini (Python install manager) kurun.
6. Belirteci girin
Belirteci bir ortam değişkenine koyun. Ortam değişkeni, yalnızca bu terminal penceresinin içinde var olan geçici bir ayardır. Adı FS_BOT_TOKEN'dır. Aşağıdan sisteminize uygun tek satırlık komutu kopyalayın, yapıştırın ve Enter'a bir kez basın. Ardından Bot token görünür ve girişinizi bekler. Şimdi 2. adımda kopyaladığınız belirteci yapıştırın ve Enter'a basın.
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 ve Linux'ta yapıştırılan belirteç görünmez, Windows'ta ise karakterleri yerine * görürsünüz. İkisi de normaldir. Belirteç komutun içine yazılmadığı için komut geçmişinde kalmaz. Ayar yalnızca bu pencerede geçerlidir. Pencereyi kapattıysanız veya yeni bir pencere açtıysanız 4. ve 6. adımları tekrarlayın.
Windows: PowerShell'de Ctrl+V ile veya sağ tıklayarak yapıştırın. Bu tek satırlık komut, Windows ile birlikte gelen Windows PowerShell 5.1'de ve daha yeni PowerShell 7'de çalışan bir yazım kullanır, ancak henüz gerçek bir Windows bilgisayarda test edilmedi.
Başarılıysa şöyle görünür: hata olmadan bir sonraki komut için istem geri gelir.
7. Bağlantı programını başlatın
Aynı pencerede aşağıdaki komutu olduğu gibi kopyalayın, yapıştırın ve Enter'a basın. İçindeki dosya adlarını değiştirmeyin. Botunuz alıştırma motoruyla bağlanır. Bu motor çok zayıftır ve numarası en küçük yasal kareye oynar.
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'Komut çalışırken metin göstermemesi ve komut istemine dönmemesi normaldir. Botunu çevrimiçi tutmak için bu pencereyi açık, bağlantı programını ve motoru çalışır durumda tut; bilgisayarın uykuya geçmesini önle. Bu pencereyi kapatmak veya Ctrl+C tuşlarına basmak iki programı da durdurur ve botun çevrimdışı olur. Yeniden bağlamak için yukarıdaki komutu tekrar çalıştır. Bağlantı programı diğer botlardan gelen maç isteklerini otomatik kabul eder.
Bot alıştırma motoruyla çalıştığı sürece otomatik maç almaz ve diğer botlarla oynadığı maçlar, sizin istedikleriniz de dahil, puana yansımaz. Kendi motorunuzla yeniden başlatın (adım 10); o andan itibaren eşleştirilir ve puan alır.
Başarılıysa şöyle görünür: bot sayfasındaki Kayıtlı botlar listesinde botunuzun adının sağındaki nokta yeşildir. Üzerine gelince Çevrimiçi görünür. Gri ise (Çevrimdışı) Yenile düğmesine basın.
8. İlk oyunla test edin
Bot sayfasında Oynayan botum alanından botunuzu seçin. FlipSight botları listesinden herhangi bir bot seçin, Meydan oku düğmesine basın ve açılan pencerede onaylayın. Tüm oyun türlerinde FlipSight botlarının hamlelerini sunucu hesaplar; oyun odasını açık tutmanız gerekmez. Otomatik eşleştirme açıksa (varsayılan) site, bağlantı programı çalıştığı sürece bot maçları da ayarlar.
Başarılıysa şöyle görünür: oyun odasında iki tahta görünür ve botunuzun her sırasında bir taş konur. Alıştırma motoru çok zayıf olduğu için kaybetmek normaldir.
9. Pencere kapanınca da çalışsın (isteğe bağlı)
7. adım yerine aşağıdaki komutla başlatırsanız bot, pencereyi kapattıktan sonra da çalışmaya devam eder. Komutu belirteci girdiğiniz (6. adım) pencerede çalıştırın. Bilgisayar kapanırsa veya uyku moduna geçerse durur. Oyun sırasında durdurursanız o oyunu süreden veya bağlantı kopmasından kaybedersiniz.
macOS / Linux
macOS / Linux: başlatma komutunu çalıştırdıktan sonra pencereyi kapatabilirsiniz. Mesajlar bot klasöründeki bot.log dosyasına yazılır. Durdurmak için yeni bir terminal açın ve durdurma komutunu çalıştırın. Yalnızca gereken kutuyu kopyalayın: iki kutuyu birlikte yapıştırırsanız bot başlar başlamaz durur.
Başlat
nohup python3 tools/bot_match_client.py --engine 'python3 tools/bot_match_example_engine.py' > bot.log 2>&1 &Durdur
pkill -f bot_match_client.pyWindows PowerShell
Windows: görev çubuğunda simge durumuna küçültülmüş bir pencere belirir ve bot onun içinde çalışır. Şu anki PowerShell penceresini kapatabilirsiniz. Durdurmak için küçültülmüş pencereyi açıp Ctrl+C'ye basın veya o pencereyi kapatın.
Başlat
Start-Process py -ArgumentList 'tools/bot_match_client.py --engine "py tools/bot_match_example_engine.py"' -WorkingDirectory $PWD -WindowStyle Minimized10. Kendi motorunuza geçin
Bağlantıyı test ettikten sonra kendi motorunuza geçin: Edax veya Egaroucid için aşağıdaki özel seçenekler, diğer uyumlu motorlar için --nboard, kendi motorunuz için JSON kullanın. Belirteç aynı kalır.
Bir varyant oyunu (Anti, 10x10, Octagon, klasik Reversi) Desteklenen oyunlar bölümünde yalnızca motorunuz o oyunun kurallarını biliyorsa işaretleyin. Diğer botlar ve insanlar, işaretli her oyunda botunuza meydan okuyabilir. Değiştirmek için bot listesinde Yönet bölümünü açın, Desteklenen oyunlar seçimini düzenleyin ve Kaydet düğmesine basın. Bir oyun sürerken veya bekleyen bir meydan okuma varken değiştiremezsiniz.
Oyunlara göre motor isteği örnekleri
Edax gibi NBoard destekleyen bir motor bağla
NBoard, NTest ile kullanılabilen grafik arayüzlü bir Othello programıdır. NBoard protokolü, programın motorlarla iletişim için yayımladığı biçimdir ve NTest ile Edax gibi bu biçimi destekleyen motorlarla çalışır.
Aşağıdaki kurulum ve çalıştırma örneklerinde Edax 4.6 ve Egaroucid for Console 7.8.2 kullanılır.
Edax 4.6 bağlantı programına dahil değildir. Edax 4.6 sayfasındaki Assets bölümünden işletim sistemine uygun dosyayı indir, bot klasörüne koy ve aşağıdaki hazırlık komutlarıyla aç. Windows ve Linux komutları x86-64 bilgisayarlar içindir.
Windows PowerShell (x86-64): edax-4.6-MS-windows-x86.zip
Hazırlık (yalnızca ilk sefer)
Expand-Archive -LiteralPath edax-4.6-MS-windows-x86.zip -DestinationPath edax-4.6Başlat
py tools/bot_match_client.py --edax "edax-4.6\wEdax-x86-64.exe"Linux (x86-64): edax-4.6-linux-x86.tar.gz
Hazırlık (yalnızca ilk sefer)
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-64Başlat
python3 tools/bot_match_client.py --edax "edax-4.6/lEdax-x86-64"macOS: edax-reversi-4.6.tar.gz
Edax 4.6 için resmi macOS çalıştırılabilir dosyası yoktur. Aynı sürümden Source code (tar.gz) ve edax-4.6-linux-x86.tar.gz dosyalarını indir. Mac programını kaynak koddan derle; Linux arşivinden yalnızca ortak değerlendirme dosyası data/eval.dat alınır. Xcode Command Line Tools gerekir. Hazırlık komutları kaynak kodu derler.
Hazırlık (yalnızca ilk sefer)
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)Başlat
python3 tools/bot_match_client.py --edax "edax-4.6/bin/mEdax-native"Edax aşağıdaki --edax seçeneğine yalnızca çalıştırılabilir dosya yolu verilerek de bağlanabilir. Ayrı bağdaştırıcı gerekmez; bağlayıcı hamle süresini oyunda kalan zamana göre paylaştırır.
Komuttaki yolu kendi programınızın tam yoluyla değiştirin. Boşluk içeren yolları çift tırnak içine alın. Değerlendirme dosyası otomatik bulunmazsa --edax-eval ile eval.dat yolunu belirtin.
NBoard bağlantısı yalnızca standart 8×8 oyunları oynar. Bu bot için Desteklenen oyunlar bölümünde yalnızca Standart işaretli kalsın. Bir varyant oyunu gelirse bağlantı programı motora sormaz, hamle yapılmaz ve oyun iptal edilir ya da süreden kaybedilir.
Egaroucid: --egaroucid
Egaroucid for Console hazırlayın. Konsol uygulamasını seçin ve resources klasörünü yerinde tutun. macOS ve Linux’ta resmî yönergelere göre derlenmiş programı kullanın. Konum ve kalan süre setboard, settime ve go komutlarıyla gönderilir; bağdaştırıcı gerekmez.
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"İki kip de yalnızca standart 8×8 destekler; eşzamanlı her oyun için bir motor çalışır. --max-think-seconds hamle güvenlik sınırıdır (varsayılan 10 saniye). Egaroucid sınıra ulaşırsa arama durdurulur, yasal bir yedek hamle oynanır ve motor sonraki tur yeniden başlatılır.
Kendi yazdığınız motor: JSON ile bağlanın
Bu bölümü yalnızca kendi yazdığınız bir motoru bağlamak istiyorsanız okuyun. Edax, Egaroucid veya başka bir NBoard motoru kullanıyorsanız yukarıdaki adımlarla işiniz zaten bitmiştir ve bu bölümü atlayabilirsiniz.
Sıra botunuza her geldiğinde bağlantı programı my_adapter.py dosyasını bir kez çalıştırır. Geçerli konumu tek satır olarak verir (taşların yeri, sıranın kimde olduğu, hangi karelerin yasal olduğu, ne kadar süre kaldığı), my_adapter.py tek satırda bir kareyle yanıt verir ve bağlantı programı bu hamleyi sunucuda oynar. my_adapter.py, arada duran ve hamleyi motorunuza soran küçük bir Python dosyasıdır. Sunucu bağlantısını, belirteci ve hamle gönderimini bağlantı programı üstlenir, bu yüzden bu dosya onlarla hiç uğraşmaz.
bot_match_client.py→ my_adapter.pybot_match_client.py← my_adapter.pyMotorunuz hangi türden?
- Hamlesini Python koduyla seçen bir motor: aşağıdaki örnek A'yı kullanın.
- Her çalıştırıldığında tek bir yanıt satırı yazdırıp kapanan bir program dosyası: aşağıdaki örnek B'yi kullanın.
- Açık kalan ve sürekli komut alışverişi yapan bir program dosyası: NBoard destekliyorsa yukarıdaki --nboard ile bağlayın. Başka bir protokolse örnek B'yi o protokole uyarlayın ve my_adapter.py'nin motoru açık tutup bir döngüde her seferinde bir satır alışverişi yapmasını sağlayın.
Adım 1: yalnızca bağlantıyı denetleyen bir dosya (my_adapter.py)
Bot klasöründe (README.md ve tools'un bulunduğu yer) my_adapter.py adlı bir dosya oluşturun, aşağıdaki kodu olduğu gibi yapıştırın ve kaydedin. Bu dosya hiçbir motor kullanmaz ve yalnızca ilk yasal kareyle yanıt verir. Motorunuzu bağlamadan önce bağlantının çalıştığını doğrulamak için vardır.
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)
Bağlanmadan önce girdi ve çıktıyı kontrol edin
1 numaralı kutudaki komut, örnek konumu doğrudan adaptöre verir. Tek satır yazdırmalıdır: {"move": 19}. Bu satırı gördüğünüzde 2 numaralı kutudaki komut, 6. adımdaki belirtecin bulunduğu pencerede bağlantı programını bu adaptörle başlatır. İki kutuyu ayrı ayrı çalıştırın. Motorunuz bu JSON biçimini kendisi okuyorsa, komutunu doğrudan --engine'den sonra yazabilirsiniz.
1. Adaptörü tek başına deneyin
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. Bağlantı programını adaptörle başlatın
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'Adım 2: motorunuzu çağıran bir dosyaya geçin
Adım 1 çalıştıktan sonra my_adapter.py dosyasının tüm içeriğini aşağıdaki örnek A veya B ile değiştirin. Yalnızca EDIT ile işaretli satırları değiştirin, gerisini olduğu gibi bırakın. Ardından yukarıdaki test komutu 1'i yeniden çalıştırın ve tek bir yanıt satırının göründüğünü denetleyin. Hamleyi motorunuz seçtiği için 19 dışında bir kare çıkması normaldir.
Örnek A: hamlesini bir Python fonksiyonuyla seçen motor
Bu örnek, hamleyi seçen search fonksiyonunu içeren my_engine.py adlı bir dosya olduğunu varsayar. EDIT 1 yazan yerde dosya adını ve fonksiyon adını, EDIT 2 yazan yerde de fonksiyona verilen değerleri kendi motorunuza göre değiştirin. Fonksiyon kare numarasını (0 ile 63 arası) veya d3 gibi bir koordinatı döndürmelidir.
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)Örnek B: program dosyası olan bir motor
Bu örnek, programın 64 tahta karakteri, hamle sırası olan taraf ve milisaniye cinsinden düşünme süresi içeren tek bir satır okuduğunu ve D3 gibi tek bir koordinat satırıyla yanıt verdiğini varsayar (. = boş, X = siyah, O = beyaz). Her motorun kendi biçimi vardır, bu yüzden EDIT 1 yazan yerde program dosyasının adını, EDIT 2 yazan yerde motora gönderilen satırı ve EDIT 3 yazan yerde yanıtı okuyan kısmı kendi motorunuza göre değiştirin.
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)Düşünme süresi: bot oyunlarında her botun oyun başına süresi 1 dakikadır, bu yüzden tek bir hamlede uzun düşünmek kısa sürede süreden kaybettirir. Örneklerdeki think_ms, kalan süreyi (remaining_ms) kalan hamle sayınıza bölerek bu hamlenin süresini belirler. budget_ms bu hamleye harcanacak süre değildir. Bağlantı programının yanıtı beklediği en uzun süredir (varsayılan olarak 10 saniye). Yanıt bundan geç gelirse bot o oyuna devam edemez ve oyunu süreden kaybeder. Bu yüzden motorunuza budget_ms değerini değil, think_ms değerini verin.
Bir şey bozulduğunda: motor çağrısı başarısız olursa örnek dosyalar nedenini my_adapter.log dosyasına yazar ve onun yerine ilk yasal kareyi oynar. Hamleler tuhaf görünüyorsa önce bu dosyayı açın. Bağlantı programı adaptörün hata iletilerini ekranda göstermez. print komutunu yalnızca tek yanıt satırı için kullanın, hata ayıklama metinlerini ise bir dosyaya yazın.
Hız: bağlantı programı her oyun için my_adapter.py'yi çalışır tutar ve her hamlede bir satır gönderir. Örneklerdeki gibi bir satır yanıtlayıp kapanan bir dosya sonraki hamlede yeniden başlatılır, bu yüzden motorunuz da her seferinde yeniden başlar. Motor yavaş açılıyorsa veya önceki hamlelerin çalışmasını sürdürmesi gerekiyorsa my_adapter.py'yi bir döngüye çevirin: bir satır oku, bir satır yanıtla, tekrarla. Girdiyi sonuna kadar okumayın ve her yanıttan sonra flush yapın.
Bu bölümün geri kalanı, bağlantı programı ile my_adapter.py arasında nelerin alınıp verildiğini anlatan başvuru bilgisidir. Yukarıdaki örnek dosyaları olduğu gibi kullanıyorsanız okumanız gerekmez.
Girdi JSON’u (bağlayıcı → adaptör)
Bu, çalıştırılabilir kod değil, bağlayıcının gönderdiği örnek veridir. Python dosyası olarak kaydetmeyin. Oyun sırasında güncel veriler her turda otomatik olarak gönderilir.
Aşağıda standart 8×8 başlangıç konumunun bir örneği var. Gerçek oyunlarda geçerli konumu bağlantı programı doldurur. board, kareleri a1'den sağa doğru, sonra bir sonraki satırı sıralar; 0=boş, 1=siyah, 2=beyaz. color=1 siyah için hamle ister. legal_moves oynayabileceğiniz kareleri listeler. remaining_ms kalan oyun saatidir, budget_ms ise bağlantı programının bu hamlenin yanıtını beklediği en uzun süredir; ikisi de milisaniye cinsindendir (1000 = 1 saniye). Varyant oyunların alanları ve örnekleri aşağıdaki varyant oyunlar bölümündedir.
{"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}Yanıt JSON’u (adaptör → bağlayıcı)
Aşağıdaki yanıtlardan birini, sonunda satır sonu olan tek bir JSON satırı olarak yazın. move bir kare numarası veya bir koordinattır; büyük/küçük harf fark etmez. 8×8 tahtada d3 = (3−1)×8+3 = 19. Her zaman aldığınız legal_moves içinden seçin. Bot eşleşmelerinde yasal hamle yoksa -1 veya pass gönderin; insanlarla oyunlarda zorunlu pasları sunucu çözer. stdout'a yalnızca yanıt satırını yazın, başka mesaj yazmayın.
{"move":19}{"move":"d3"}{"move":-1}Oyunlara göre motor isteği örnekleri
Bağlantı programının bir --engine motoruna gönderdiği, siyah için ilk istek örnekleri; kural koduyla üretilmiştir. Her türden gerçek oyun 12 taşlı rastgele bir konumdan başlar, bu yüzden board ve legal_moves her oyunda farklıdır. Bu örneklerin sabit kalması için açılış hamleleri tahtanın ortasına yakın seçildi. Gerçek oyunlarda match_id ve saat değerleri de farklıdır.
game_mode: std, anti, grand, octagon, reversi değerlerinden biri. İnsanlarla oyunlarda XOT, std olarak gelir.board_size: 8; grand ve octagon için 10.board: Uzunluğu board_size² olan dizi. a1'den sağa doğru, sonra bir sonraki satır okunur. 0=boş (Octagon'un engelli kareleri dahil), 1=siyah, 2=beyaz.blocked_squares: Octagon'da kullanılamayan kareler. Diğer oyunlarda boş dizi.placed: Her rengin şimdiye kadar koyduğu taşlar, rastgele açılış hamleleri dahil; anahtarlar "1" ve "2" dizgileridir. Klasik Reversi'nin 32 taş sınırı için kullanılır.
Anti (anti)
Girdi JSON’u (bağlayıcı → adaptör)
{
"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
}Yanıt JSON’u (adaptör → bağlayıcı)
{"move":2}Grand (10x10) (grand)
Girdi JSON’u (bağlayıcı → adaptör)
{
"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
}Yanıt JSON’u (adaptör → bağlayıcı)
{"move":13}Octagon (octagon)
Girdi JSON’u (bağlayıcı → adaptör)
{
"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
}Yanıt JSON’u (adaptör → bağlayıcı)
{"move":13}Klasik Reversi (reversi)
Girdi JSON’u (bağlayıcı → adaptör)
{
"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
}Yanıt JSON’u (adaptör → bağlayıcı)
{"move":18}Sık karşılaşılan sorunlar
| Belirti | Neden ve çözüm |
|---|---|
| Bot gri nokta gösteriyor (çevrimdışı). | Bağlantı programının penceresinin hâlâ çalıştığını kontrol edin. Pencereyi kapatınca, Ctrl+C'ye basınca veya bilgisayar uyku moduna geçince durur. 6. ve 7. adımları tekrarlayın, sonra Yenile düğmesine basın. |
Komutun bulunamadığını söylüyor.command not found / is not recognized | Python kurulu değil veya kurulumdan sonra pencere yeniden açılmadı. 5. adıma bakın, yeni bir pencere açın ve 4. adımdan yeniden başlayın. |
Dosyanın açılamadığını söylüyor.can't open file | Komutu bot klasörünün dışında çalıştırdınız. 4. adımdaki gibi bot klasörüne geçin ve ls ile README.md ve tools'un listelendiğini kontrol edin. |
Belirtecin eksik olduğunu söyleyip kapanıyor.FS_BOT_TOKEN is missing or invalid | Bu pencerede belirteç yok. Yeni bir pencere açtıysanız 6. adımı tekrarlayın. |
Belirtecin reddedildiğini söyleyip duruyor.Bot credential rejected | Belirteç yanlış yapıştırılmış veya eski bir belirteç. Yeni belirteç oluşturduktan veya botu devre dışı bıraktıktan sonra eski belirteç artık çalışmaz. En son belirteçle 6. adımdan yeniden başlayın. |
Aynı hata satırı sürekli çıkıyor.Connection/state error | İnternet bağlantısını kontrol edin. macOS'ta 5. adımdaki Install Certificates.command dosyasını çalıştırdığınızı kontrol edin. Hata yalnızca oyunlar sırasında çıkıyorsa sunucu, motorunuzun hamlesini yasa dışı diye reddediyor olabilir. Bağlantı programı aynı hamleyi yeniden gönderir; bu yüzden motorun düzeltilmesi gerekir. |
| Meydan okuma düğmesi çalışmıyor veya meydan okuma kabul edilmiyor. | İki botun da noktası yeşil olmalıdır. Oynayan botum alanında botunuzun seçili olduğunu kontrol edin. Başka bir oyunda olan bot yeni meydan okuma almaz. Kabul edilmeyen meydan okumanın süresi 120 saniye sonra dolar. |
Bot hamle yapmıyor, sonra süreden kaybediyor veya oyun iptal ediliyor.Engine failed for match | Motor zamanında yanıt vermedi veya yanıtı yanlış biçimdeydi. Motor komutunu ve tek satırlık JSON çıktısını kontrol edin. Bir bot başlangıçtan sonraki 30 saniye içinde ilk hamlesini yapmazsa oyun iptal edilir. |
| Varyant oyun meydan okumaları gelmiyor. | Meydan okuma penceresi yalnızca iki botun da desteklediği oyunları listeler. Oyunun botunuzun Desteklenen oyunlar bölümünde işaretli olduğunu ve diğer botun da desteklediğini kontrol edin. NBoard ile bağlanan bir botta yalnızca Standart işaretli olmalıdır. |
Sözlük
| Terim | Anlamı |
|---|---|
| API | Programların istek ve yanıt göndermesi için üzerinde anlaşılmış bir yol. Bunu bağlantı programı sizin için yapar. |
| Belirteç | Yalnızca botunuza ait bir parola. Bağlantı programı hangi bot olduğunu sunucuya bununla kanıtlar. |
| Terminal | Komut yazdığınız bir pencere. Windows'ta PowerShell kullanın. |
| Ortam değişkeni | Bir terminal penceresinden başlatılan programlara verilen geçici bir ayar. Pencere kapanınca kaybolur. |
| JSON | Verileri metin olarak yazma biçimi. Örnek: {"move":19} |
| Motor | Bir konuma bakıp hamle seçen program. |
| Adaptör | Motorunuzla bağlantı programı arasında veri dönüştüren küçük bir program. |
| NBoard | NBoard, NTest ile kullanılabilen grafik arayüzlü bir Othello programıdır. NBoard protokolü, programın motorlarla iletişim için yayımladığı biçimdir ve NTest ile Edax gibi bu biçimi destekleyen motorlarla çalışır. |
| Yasal hamle | Şu anda oynayabileceğiniz bir kare. Sunucu bunları legal_moves içinde listeler. |
İndirmeler
İndirmek için giriş yapın. .zip kılavuz, bağlayıcı ve örnek motoru içerir; .json API belirtimi, .md ise kılavuzdur.
Ayrıntılı belirtim
Bu sayfanın geri kalanı, bir motorla veya doğrudan API ile çalışan geliştiriciler için ayrıntılı başvuru bilgisidir.
Bağlantı programı seçenekleri
tools/bot_match_client.py seçenekleri. --engine ve --nboard / --edax / --egaroucid seçeneklerinden tam olarak biri gereklidir. Belirteç hiçbir zaman seçenek olarak verilmez; yalnızca FS_BOT_TOKEN ortam değişkeninden okunur. Çıkış kodları: 0 normal durma, 2 belirteç reddedildi, 3 --max-runtime süresine ulaşıldı.
| Parametreler | Açıklama |
|---|---|
--engine "COMMAND" | Bu komutu her oyun için bir kez başlatır ve girdisini kapatmadan her hamlede bir JSON satırı alışverişi yapar. Bir satır yanıtlayıp kapanan motor sonraki hamlede yeniden başlatılır. |
--nboard "COMMAND" | Her oyun için bir NBoard motoru, toplam iki motor açık tutar. Yalnızca standart (std). |
--edax PATH | Edax aşağıdaki --edax seçeneğine yalnızca çalıştırılabilir dosya yolu verilerek de bağlanabilir. Ayrı bağdaştırıcı gerekmez; bağlayıcı hamle süresini oyunda kalan zamana göre paylaştırır. |
--edax-eval PATH | Edax eval.dat dosyasının yolu. Belirtilmezse program klasöründe veya üst klasöründe data/eval.dat aranır. |
--egaroucid PATH | Egaroucid for Console hazırlayın. Konsol uygulamasını seçin ve resources klasörünü yerinde tutun. macOS ve Linux’ta resmî yönergelere göre derlenmiş programı kullanın. Konum ve kalan süre setboard, settime ve go komutlarıyla gönderilir; bağdaştırıcı gerekmez. |
--nboard-depth N | NBoard motoruna set depth N gönderir. 0 ile 60 arası; 0 motorun varsayılanını korur. (--edax: 0 → 60). |
--max-think-seconds S | Her hamlede motoru beklemek için en fazla saniye. Varsayılan 10, en fazla 300. Hiçbir zaman kalan saatten 0,75 saniye eksiğinden uzun olmaz. Bu, bağlantı programının bir güvenlik sınırıdır; sunucuda hamle başına süre sınırı yoktur. 0, hamle başına sınırı kaldırır ve oyunda kalan süreyi kullanır. |
--engine-name NAME | Bot bilgisinde bildirilen motor adı (en fazla 120 karakter). Komut veya yol yazmayın. |
--cpu-name NAME | Bildirilecek CPU adı (en fazla 120 karakter). Verilmezse otomatik algılanır. |
--once-match ID | Yalnızca bu maçı işler ve maç sona erince çıkar (finished, aborted, expired, rejected). İnsanlarla oyunların negatif kimlikleri de çalışır. Testlerde --max-runtime ile birlikte kullanın. |
--max-runtime S | Bu kadar saniye sonra motorları kapatır ve çıkar (çıkış kodu 3). |
--no-stream | Olay akışını kullanmaz; yalnızca sorgulama yapar. |
--api URL, --stream-url URL | API ve akış adresleri. Normalde varsayılanları bırakın. Yalnızca HTTPS kabul edilir ve belirteç de gönderildiği için akış API sunucusunda olmalıdır. |
API'yi kendiniz uygulamak
Meydan okumaları ve konumları agent_poll ile veya kimliği doğrulanmış olay akışıyla alın. bot_b olduğunuz bekleyen meydan okumalar için agent_accept gönderin; ardından süren bir maçın her oyununda yalnızca sıranın sizde olduğu konumları hesaplayın. Her match_id, oyun ve revision için en fazla bir kez gönderin; durum değişince eskimiş işi bırakın. İnsanlarla oyunlarda match_id negatiftir ve leg=0 olur; round_no ve room_created_at tam olarak alındığı gibi gönderilmelidir. Normal odalarda zorunlu pasları sunucu yönetir; pas gönderen yalnızca bot eşleşmeleridir.
agent_poll / bot-stream → pending (bot_b = my_id)
→ agent_accept → running → legs[0] + legs[1]
→ agent_move(match_id, leg, revision, move) → finished / abortedVaryant oyunlar
Bot yalnızca Desteklenen oyunlar bölümünde işaretli oyunları alır. Oyunu, motor isteklerindeki ve maç durumundaki game_mode belirtir. Tahta boyutunu, engelli kareleri ve yasal kareleri sunucu hesaplar; bu yüzden motorun yalnızca aldığı legal_moves içinden seçmesi yeterlidir. 10×10 veya klasik Reversi hamlelerini standart 8×8 hamle üretimiyle üretmeyin.
| Oyun | game_mode | Tahta | Başlangıç taşları | Süre (oyun başına, renk başına) | Siyahın ilk legal_moves değeri |
|---|---|---|---|---|---|
| Standart | std | 8×8 | Rastgele 12 taş | 60,000 ms | Konuma göre değişir |
| Anti | anti | 8×8 | Rastgele 12 taş | 60,000 ms | Konuma göre değişir |
| Grand (10x10) | grand | 10×10 | Rastgele 12 taş | 60,000 ms | Konuma göre değişir |
| Octagon | octagon | 10×10 (88) | Rastgele 12 taş | 60,000 ms | Konuma göre değişir |
| Klasik Reversi | reversi | 8×8 | Rastgele 12 taş | 60,000 ms | Konuma göre değişir |
Ortak kurallar: Siyah (1) önce oynar. İki oyun da aynı konumdan renkler değiştirilerek başlar ve aynı anda oynanır. Bot eşleşmelerinde yasal hamleniz yoksa legal_moves boş dizi olarak gelir ve bot move=-1 (pas) değerini kendisi göndermelidir. Sunucu sizin yerinize pas geçmez ve saatiniz işlemeye devam eder. Yasal hamle varken pas geçmek yasa dışıdır. Hiçbir renk hamle yapamadığında oyun biter. Boş kareler kimseye verilmez; iki oyundaki yalnızca gerçek taşlar toplanır, toplamlar eşitse berabere biter. Tüm bot oyunları 12 taşlı rastgele bir konumdan başlar. Tüm oyun türlerinde her botun oyun başına süresi 1 dakikadır.
Anti: taş koyma ve çevirme standart Othello'daki gibidir. İki oyunda toplam daha az taşı olan taraf kazanır.
10x10: 10×10 tahtada (100 kare) standart kurallar. Başlangıç dizilişi ortadaki dört karedir; bot eşleşmeleri buna 8 rastgele hamle ekler ve 12 taşla başlar.
Octagon: tahta ve başlangıç dizilişi 10x10 ile aynıdır, ama her köşedeki üç kare, toplam 12 kare kullanılamaz (88 oynanabilir kare). Engelli kareler blocked_squares içinde kare numarası olarak, board içinde ise boş kareyle aynı değer olan 0 olarak gelir. Dizi sayı sırasında değildir. Engelli kareye oynayamazsınız ve taş dizileri orada kesilir.
Klasik Reversi: kurallara göre oyun boş tahtadan başlar. Ortadaki dört kareden (27, 28, 35, 36) biri boş olduğu sürece yalnızca oraya taş konur ve hiçbir taş çevrilmez. Dördü de dolunca standart kurallar geçerlidir. Her renk, ilk dört hamle dahil en fazla 32 taş koyar. placed her rengin şimdiye kadar koyduğu taşları sayar; anahtarları "1" (siyah) ve "2" (beyaz) dizgileridir. Bot eşleşmeleri, sunucu ortadaki dört hamle dahil 12 rastgele taş koyduktan sonra başlar; bu yüzden ilk istekte iki placed değerinin toplamı 12 olur (genellikle {"1":6,"2":6}). 32 taşın hepsini koymuş bir renk boş legal_moves alır ve her sırasında -1 gönderir.
Oyunlara göre motor isteği örnekleri
Bağlantı programının bir --engine motoruna gönderdiği, siyah için ilk istek örnekleri; kural koduyla üretilmiştir. Her türden gerçek oyun 12 taşlı rastgele bir konumdan başlar, bu yüzden board ve legal_moves her oyunda farklıdır. Bu örneklerin sabit kalması için açılış hamleleri tahtanın ortasına yakın seçildi. Gerçek oyunlarda match_id ve saat değerleri de farklıdır.
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}Klasik Reversi (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}Motor isteği alanları
| Alan | Tür | Açıklama |
|---|---|---|
game_mode | string | std, anti, grand, octagon, reversi değerlerinden biri. İnsanlarla oyunlarda XOT, std olarak gelir. |
board_size | integer 8 | 10 | 8; grand ve octagon için 10. |
board | integer[board_size²] | Uzunluğu board_size² olan dizi. a1'den sağa doğru, sonra bir sonraki satır okunur. 0=boş (Octagon'un engelli kareleri dahil), 1=siyah, 2=beyaz. |
blocked_squares | integer[] | Octagon'da kullanılamayan kareler. Diğer oyunlarda boş dizi. |
placed | {"1": integer, "2": integer} | Her rengin şimdiye kadar koyduğu taşlar, rastgele açılış hamleleri dahil; anahtarlar "1" ve "2" dizgileridir. Klasik Reversi'nin 32 taş sınırı için kullanılır. |
legal_moves | integer[] | Şu anda oynayabileceğiniz kareler. Boşsa move=-1 ile yanıt verin. |
color | integer 1 | 2 | Hamle sırası olan renk. 1=siyah, 2=beyaz. |
budget_ms | integer | Bu hamle için verilen süre, milisaniye cinsinden: --max-think-seconds ile kalan saatten 0,75 saniye eksiğinin küçüğü. Aşılırsa bağlantı programı motoru durdurur. |
remaining_ms | integer | Bu oyunda renginizin kalan saati, bu sırada kullanılan süre düşüldükten sonra, milisaniye cinsinden. |
match_id | integer ≠ 0 | Maç kimliği. İnsanlarla oyunlarda negatiftir (-oda numarası). |
leg | integer 0 | 1 | Oyun numarası, 0 veya 1. İnsanlarla oyunlarda her zaman 0. |
revision | integer | Bu oyunun durum numarası. agent_move ile değiştirmeden gönderin. |
history | array | Bu oyunda oynanan hamleler. Kararı board'a göre verin. |
round_no | integer | null | İnsanla oyunun tur numarası. Bot eşleşmelerinde null. |
room_created_at | string | null | İnsanla oyun odasının oluşturulma zamanı. Bot eşleşmelerinde null. |
Başka bir bota varyant oyunda meydan okumak
agent_challenge isteğine game_mode ekleyin; varsayılanı std'dir. İki botun da supported_games listesinde bu oyun olmalıdır. Rakibin oyunlarını agent_poll yanıtındaki bots[].supported_games alanından okuyun. Botlardan birinde oyun yoksa yanıt, aşağıdaki hatayla HTTP 409 olur.
{"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 değiştirme
Kayıt formu Standart işaretli olarak başlar; kayıtlı listesi olmayan eski botlar std destekler. Listeyi yalnızca bot web sayfasındaki Yönet bölümünden değiştirebilirsiniz; bot belirteciyle (API) asla değiştiremezsiniz. Bir maç sürerken veya kabul beklerken değişiklik reddedilir. Boş liste kaydedilemez.
NBoard ve varyantlar
--nboard bağlantısı yalnızca standart (std) oyunu destekler. Bir varyant oyunu geldiğinde bağlantı programı motora sormaz ve o sırayı bırakır (Engine failed for match mesajı). Hamle gönderilmediği için oyun ilk hamleden önce iptal edilir veya o oyun daha sonra süreden kaybedilir. NBoard botuna desteklenen tek oyun olarak standardı verin.
İnsanlara karşı kayıtlı botlar
İnsanlar botunuza, kayıtlı olduğu her oyunda meydan okuyabilir. Bot standart oyunu destekliyorsa hem STD hem XOT gelebilir. XOT, game_mode std ile gelir ve 8 hamlenin zaten oynandığı bir tahtadan başlar (bu hamleler history içindedir). Süreyi meydan okuyan kişi seçer ve oyun puanlı değildir. İnsanla oyunun tek bir oyunu (leg 0) ve negatif bir match_id değeri vardır. Hamle mümkün olmadığında pasları sunucu yönetir; bu yüzden -1 göndermeyin. Otomatik eşleştirmesi açık olan çevrimiçi kayıtlı botlar, desteklenen STD/XOT hızlı maçlarına da katılır. Üyelerin hızlı maçları puanlı, misafirlerinki puansızdır.
Yasa dışı hamleler ve süre
Yasa dışı bir hamle veya eskimiş revision, HTTP 409 (illegal_move, stale_revision, not_your_turn) ile reddedilir ve tahta değişmez. Bu sırada saat işlemeye devam eder. Bağlantı programı aynı hamleyi aynı revision ile yeniden gönderir; bu yüzden motor düzeltilmezse o oyun sonunda süreden kaybedilir. Sunucuda hamle başına sınır yoktur, yalnızca her rengin kalan saati kontrol edilir. 10 saniye, bağlantı programının varsayılan --max-think-seconds değeridir.
Kimlik doğrulama
HTTPS, JSON POST ve Authorization: Bearer kullanın. Belirteç tek bir bota aittir. URL, herkese açık kod veya günlüklere koymayın.
Content-Type: application/json
Authorization: Bearer <FS_BOT_TOKEN>POST https://othelloclub.com/flipsight/bot_match_api.php
Maç kuralları
Tüm bot oyunları 12 taşlı rastgele bir konumdan başlar. Renkler değiştirilerek iki oyun aynı anda oynanır. Toplam taş sayısı kazananı belirler; Anti oyununda az taş kazanır.
Tüm bot oyunları 12 taşlı rastgele bir konumdan başlar. Tüm oyun türlerinde her botun oyun başına süresi 1 dakikadır.
Bir bot başlangıçtan sonraki 30 saniye içinde ilk hamlesini yapmazsa maç iptal edilir ve puanlanmaz. Maç sırasında bir botun bağlantısı 30 saniyeden uzun süre koparken diğeri bağlıysa bağlı bot kazanır (finish_reason: disconnect) ve sonuç puanlanır.
FlipSight botunun hamlelerini her oyun türünde sunucu hesaplar. Hem web üzerinden hem de API ile (agent_challenge) gelen davetler kabul edilir ve sunucu maçı hemen başlatır; oyun odasını açık tutmanız gerekmez. Sunucunun hesaplaması 30 saniyeden uzun durursa maç iptal edilir (finish_reason: technical) ve puana yansımaz. Varyantları hesaplamak ağır olduğundan FlipSight botlarıyla aynı anda en fazla 2 varyant maçı oynanır. Yerler doluysa HTTP 409 ve site bot variant matches are full döner; biraz sonra yeniden deneyin.
Otomatik bot maçları: site her zaman iki bot maçı odası açık tutar. Otomatik eşleştirmesi açık olan kayıtlı bir bot çevrimiçiyken ve oynamıyorken, benzer puanlı bir bota karşı (önce başka bir kayıtlı bot, yoksa bir FlipSight botu) standart (std) bot maçı daveti alır ve bot_b olur. Bağlantı programı daveti otomatik kabul eder ve maç başlar. Bot 120 saniye içinde kabul etmez veya reddederse 10 dakika boyunca otomatik eşleştirmenin dışında kalır. Otomatik maçlar puana yansır. Otomatik bot maçları Arena oyunları sırasında da devam eder. Otomatik eşleştirme varsayılan olarak açıktır ve bot sayfasındaki Yönet bölümünden kapatılabilir. Alıştırma motoruyla başlatılan bot (environment.practice true) otomatik maçların dışında kalır ve bu sürede diğer botlarla oynadığı maçlar puana yansımaz.
Bir kişinin doğrudan meydan okuması, desteklenen oyun ve süreyle normal odada tek oyun olarak oynanır. Sunucu doğrudan meydan okumaları her zaman puansız yapar. Otomatik eşleştirmesi açık olan çevrimiçi kayıtlı botlar, desteklenen STD/XOT hızlı maçlarına da katılır. Üyelerin hızlı maçları puanlı, misafirlerinki puansızdır. Kayıtlı bir bot yalnızca eşzamanlı oyun ayarının izin verdiği kadar oyun kabul eder (varsayılan 2). İnsana karşı bir oyun ve bir bot maçı (iki tahta) her biri 1 sayılır.
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)Maç akışı
Tüm bot oyunları 12 taşlı rastgele bir konumdan başlar. Renkler değiştirilerek iki oyun aynı anda oynanır. Toplam taş sayısı kazananı belirler; Anti oyununda az taş kazanır.
bot_a iseniz katılımcı numaranız 0, bot_b iseniz 1'dir. Katılımcı 0, legs[0]'da siyah (1), legs[1]'de beyaz (2) oynar; katılımcı 1 bunun tersidir. leg.status active olduğunda ve leg.turn renginize eşit olduğunda sıra sizdedir. Sıra iki oyunda aynı anda sizde olabilir.
Yasal hamleniz yoksa move -1 (pas) değerini kendiniz göndermelisiniz; sunucu sizin yerinize pas geçmez. İnsana karşı oyunlarda sunucu pasları normal oyun odalarındaki gibi işler.
Sıra sizdeyken kalan süre = clocks_ms[renginiz - 1] - (server_now_ms - turn_started_ms). clocks_ms renk sırasındadır (siyah, beyaz); totals ve winner katılımcı sırasındadır (winner 0 veya 1, beraberlikte null).
Hücre numaraları
Hücre numarası = satır × 8 + sütun; yani a1=0, h1=7, a2=8 ve h8=63. Örneğin 19 d3, 37 ise f5'tir. board dizisi aynı sırayı kullanır: 0=boş, 1=siyah, 2=beyaz.
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 tahtada (grand, octagon) kare = satır × 10 + sütun. Sütunlar a'dan j'ye kadardır ve onuncu satır koordinatlarda 10 veya 0 olarak yazılır. a1=0, j1=9, a2=10, j10=99 (j0 ile aynı). Aynı koordinatın numarası tahta boyutuna göre farklıdır: d3, 8×8'de 19, 10×10'da 23'tür.
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 ## ##Olay akışı
Aynı Bearer belirteciyle GET https://othelloclub.com/flipsight_api/bot-stream adresine bağlanarak satır başına bir JSON olayı (NDJSON) alın: hello bağlantıyı doğrular, match maçlarınızdan birinin değiştiğini bildirir (botlar arası olaylar tam maç nesnesini içerir), ping ise bağlantıyı canlı tutmak için 10 saniyede bir gelir. match aldığınızda agent_poll'u bir kez çağırın. Bağlantı koparsa 1'den 30 saniyeye kadar artan gecikmeyle yeniden bağlanın ve bu sırada sorgulamaya devam edin. Akış bağlıyken botunuz çevrimiçi görünür; her bot en fazla 3 akış açabilir.
Olay örnekleri
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}Motor adaptörü
FlipSight bot bağlantı programı (Python 3.9+, yalnızca standart kütüphane) Windows, macOS ve Linux'ta çalışır ve motoru iki şekilde bağlar. --engine motoru her oyun için bir kez başlatır, her hamlede bir JSON satırı gönderir ve bir {"move": kare} satırı okur. Bir satır yanıtlayıp kapanan motor, sonraki hamlede yeniden başlatıldığı için çalışmaya devam eder; ancak girdiyi sonuna kadar okuyan motor (sys.stdin.read() vb.) hiç yanıt vermez, bu yüzden her seferinde bir satır okuyun. İstekteki legal_moves yasal kareleri listeler; liste boşsa -1 yanıtlayın. --nboard bir NBoard motorunu her oyun için bir tane olmak üzere çalışır durumda tutar; derinliği --nboard-depth ile ayarlayın.
Edax aşağıdaki --edax seçeneğine yalnızca çalıştırılabilir dosya yolu verilerek de bağlanabilir. Ayrı bağdaştırıcı gerekmez; bağlayıcı hamle süresini oyunda kalan zamana göre paylaştırır.
Egaroucid for Console hazırlayın. Konsol uygulamasını seçin ve resources klasörünü yerinde tutun. macOS ve Linux’ta resmî yönergelere göre derlenmiş programı kullanın. Konum ve kalan süre setboard, settime ve go komutlarıyla gönderilir; bağdaştırıcı gerekmez.
Girdi JSON’u (bağlayıcı → adaptör)
Bu, çalıştırılabilir kod değil, bağlayıcının gönderdiği örnek veridir. Python dosyası olarak kaydetmeyin. Oyun sırasında güncel veriler her turda otomatik olarak gönderilir.
{"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}Yanıt JSON’u (adaptör → bağlayıcı)
{"move":2}Durum eşitleme
Akış bağlıyken bir olay geldiğinde ve 10 saniyede bir agent_poll çağırın. Akış olmadan maç sırasında saniyede bir, boştayken 5 saniyede bir sorgulayın; asla saniyede birden sık sorgulamayın. Ağ süresi sizin saatinizden düşer. Hamle yanıtı kaybolursa yeni durumu sorgulayın ve aynı hamleyi yalnızca revision hâlâ aynıysa yeniden gönderin.
API işlemleri
Yanıt örnekleri biçimi gösterir. Kopyala düğmesi yalnızca isteği kopyalar ve API'yi çağırmaz.
POST agent_poll
Durumu al
| Parametreler | Tür | Zorunlu | Açıklama |
|---|---|---|---|
action | string "agent_poll" | Zorunlu | Çağrılacak işlemin adı |
environment | object | İsteğe bağlı | Bağlantı programının çalıştığı bilgisayarın CPU, işletim sistemi ve motor adı (her biri en fazla 120 karakter, isteğe bağlı) ile practice (true veya false, isteğe bağlı). practice true ise bot alıştırma yapıyor demektir: otomatik maçların dışında kalır ve bu sürede istenen veya kabul edilen bot maçları puana yansımaz. Bağlantı programı alıştırma motoruyla başlatıldığında bu değeri kendisi gönderir. Sunucu son değeri hatırlar; alıştırma bitince değeri practice olmadan ya da false ile gönderin. |
İstek örneği
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"}}'Yanıt örneği
{
"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
}Maç nesnesi (matches[])
| Alan | Tür | Açıklama |
|---|---|---|
id | integer | Maç ID'si (insana karşı oyunlarda negatif) |
kind | string | İnsana karşı oyunlarda human |
bot_a | integer | Katılımcı 0'ın bot ID'si (insan için 0) |
bot_b | integer | Katılımcı 1'in bot ID'si (insan için 0) |
game_mode | string | Oyun (std, anti, grand, octagon, reversi) |
time_limit_sec | integer | Oyun başına, renk başına verilen saniye |
status | string | pending, running, finished, aborted, rejected, expired |
expires_ms | integer | Kabul için son süre (milisaniye) |
ranked | boolean | Maçın puanlı olup olmadığı |
state.status | string | active, finished veya aborted |
state.game_mode | string | Oyun (std, anti, grand, octagon, reversi) |
state.board_size | integer 8 | 10 | Bir kenardaki kare sayısı, 8 veya 10 |
state.blocked_squares | integer[] | Kullanılamayan kareler (yalnızca Octagon, sırasız) |
state.legs | array | Oyunlar (botlar arasında 2, insana karşı 1) |
state.totals | [integer, integer] | Katılımcı başına iki oyunun taş toplamları |
state.winner | integer | null | Kazanan katılımcı 0 veya 1, beraberlikte null |
state.finish_reason | string | null | discs, timeout, double_timeout, disconnect, no_first_move |
Oyun nesnesi (state.legs[])
| Alan | Tür | Açıklama |
|---|---|---|
board | integer[64 | 100] | 64 / 100 hücre, 0=boş 1=siyah 2=beyaz |
turn | integer | Hamle sırası olan renk, 1 (siyah) veya 2 (beyaz) |
legal_moves | integer[] | Hamle sırası olan rengin yasal kareleri. Bitmiş oyunlarda boş |
placed | {"1": integer, "2": integer} | Renk başına konan taşlar, anahtarlar "1" (siyah) ve "2" (beyaz) |
black_participant | integer | Bu oyunda siyahla oynayan katılımcı |
clocks_ms | [number, number] | Renk sırasına göre kalan süre taban değerleri (siyah, beyaz) |
turn_started_ms | integer | Geçerli sıranın başladığı sunucu zamanı |
revision | integer | Bu oyun her değiştiğinde 1 artar |
status | string | active, finished, timeout, stopped |
history | array | Oynanan hamleler (color, participant, move, at_ms) |
discs | [integer, integer] | Renk sırasına göre taş sayıları (siyah, beyaz) |
result_discs | [integer, integer] (optional) | Süre nedeniyle kaybedilen bir oyun için isteğe bağlı hakem skoru [siyah, beyaz]; toplamda taşlar yerine bu skor kullanılır. Süresi biten taraf ve rakibi için skorlar: std ve reversi 0 ile 64 arası, grand 0 ile 100 arası, octagon 0 ile 88 arası, anti 64 ile 0 arası. Diğer oyun devam eder ve iki oyun bittikten sonra kazananı toplamlar belirler. Daha önce bitmiş kayıtlar yeniden hesaplanmaz. |
POST agent_challenge
Meydan oku
Rakibi target_id (bot numarası) veya target_name (bot adı) ile belirtin; bunlar agent_poll yanıtındaki bots listesinde bulunur. Yerleşik FlipSight botlarına (is_builtin: true) her oyun türünde API ile davet gönderilebilir ve sunucu maçı hemen başlatır. Yerleşik botlarla zaten 2 varyant maçı sürüyorsa HTTP 409 ve site bot variant matches are full döner.
| Parametreler | Tür | Zorunlu | Açıklama |
|---|---|---|---|
action | string "agent_challenge" | Zorunlu | Çağrılacak işlemin adı |
target_id | integer ≥ 1 | İsteğe bağlı | Meydan okunacak botun ID'si |
target_name | string | İsteğe bağlı | Meydan okunacak botun adı (target_id yerine) |
game_mode | string std | anti | octagon | grand | reversi | İsteğe bağlı | Bot eşleşmesi için oyun. Varsayılanı std. İki bot da desteklemelidir. Standart / Anti / Octagon / Grand (10x10) / Klasik Reversi |
İstek örneği
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"}'Yanıt örneği
{
"ok": true,
"match_id": 123,
"server_now_ms": 1800000000000
}POST agent_accept
Kabul et
| Parametreler | Tür | Zorunlu | Açıklama |
|---|---|---|---|
action | string "agent_accept" | Zorunlu | Çağrılacak işlemin adı |
match_id | integer ≥ 1 | Zorunlu | Maç ID'si (insana karşı oyunlarda negatif) |
İstek örneği
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}'Yanıt örneği
{
"ok": true,
"match": {
"id": 123,
"status": "running",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}POST agent_reject
Reddet
| Parametreler | Tür | Zorunlu | Açıklama |
|---|---|---|---|
action | string "agent_reject" | Zorunlu | Çağrılacak işlemin adı |
match_id | integer ≥ 1 | Zorunlu | Maç ID'si (insana karşı oyunlarda negatif) |
İstek örneği
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}'Yanıt örneği
{
"ok": true,
"match": {
"id": 123,
"status": "rejected",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}POST agent_move
Hamle gönder
| Parametreler | Tür | Zorunlu | Açıklama |
|---|---|---|---|
action | string "agent_move" | Zorunlu | Çağrılacak işlemin adı |
match_id | integer ≠ 0 | Zorunlu | Maç ID'si (insana karşı oyunlarda negatif) |
round_no | integer ≥ 0 | İsteğe bağlı | Yalnız insana karşı oyunlar: maç nesnesindeki round_no |
room_created_at | string | İsteğe bağlı | Yalnız insana karşı oyunlar: maç nesnesindeki room_created_at |
leg | integer 0 | 1 | Zorunlu | Oyun 0 veya 1 (insana karşı oyunlarda 0) |
revision | integer ≥ 0 | Zorunlu | Hamlenin hesaplandığı oyunun revision değeri; oyun değiştiyse 409 stale_revision |
move | integer -1..99 | string | Zorunlu | Hücre 0-(board_size²−1), pas için -1 / d3 / D3 / pass |
İstek örneği
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}'Yanıt örneği
{
"ok": true,
"match": {
"id": 123,
"status": "running",
"bot_a": 1,
"bot_b": 2
},
"server_now_ms": 1800000000000
}Hatalar
Hatalar {"ok": false, "error": "…"} biçimindedir. 401 durumunda durup belirteci kontrol edin. 409 durumunda güncel durumu sorgulayıp sırayı, revision değerini ve yasal hamleleri kontrol edin. 429, tek bot için çok fazla akış olduğu anlamına gelir. Bağlantı hatalarını ve 503'ü artan gecikmelerle yeniden deneyin; yasadışı bir hamleyi asla yeniden göndermeyin.
{"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 |