|
|
import os |
|
|
import subprocess |
|
|
import requests |
|
|
import zipfile |
|
|
import gzip |
|
|
import shutil |
|
|
import json |
|
|
|
|
|
|
|
|
print("Downloading libzip5 and libssl1.1...") |
|
|
libzip_url = "http://archive.ubuntu.com/ubuntu/pool/universe/libz/libzip/libzip5_1.5.1-0ubuntu1_amd64.deb" |
|
|
libssl_url = "http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb" |
|
|
libzip_deb = "libzip5_1.5.1-0ubuntu1_amd64.deb" |
|
|
libssl_deb = "libssl1.1_1.1.1f-1ubuntu2_amd64.deb" |
|
|
lib_dir = "libs" |
|
|
|
|
|
os.makedirs(lib_dir, exist_ok=True) |
|
|
|
|
|
for url, deb in [(libzip_url, libzip_deb), (libssl_url, libssl_deb)]: |
|
|
try: |
|
|
print(f"Downloading {deb}...") |
|
|
response = requests.get(url) |
|
|
with open(deb, "wb") as f: |
|
|
f.write(response.content) |
|
|
print(f"Extracting {deb}...") |
|
|
subprocess.run(["dpkg-deb", "-x", deb, lib_dir]) |
|
|
if os.path.exists(deb): |
|
|
os.remove(deb) |
|
|
print(f"Deleted {deb}.") |
|
|
except Exception as e: |
|
|
print(f"Error processing {deb}: {e}") |
|
|
|
|
|
libzip_lib_path = os.path.join(lib_dir, "usr", "lib", "x86_64-linux-gnu") |
|
|
libssl_lib_path = os.path.join(lib_dir, "lib", "x86_64-linux-gnu") |
|
|
os.environ["LD_LIBRARY_PATH"] = f"{libzip_lib_path}:{libssl_lib_path}" |
|
|
|
|
|
|
|
|
print("Downloading KataGo (Eigen version)...") |
|
|
katago_url = "https://github.com/lightvector/KataGo/releases/download/v1.15.3/katago-v1.15.3-eigen-linux-x64.zip" |
|
|
katago_zip = "katago-v1.15.3-eigen-linux-x64.zip" |
|
|
katago_dir = "katago" |
|
|
|
|
|
try: |
|
|
print(f"Downloading {katago_zip}...") |
|
|
response = requests.get(katago_url) |
|
|
with open(katago_zip, "wb") as f: |
|
|
f.write(response.content) |
|
|
print(f"Extracting {katago_zip}...") |
|
|
with zipfile.ZipFile(katago_zip, "r") as zip_ref: |
|
|
zip_ref.extractall(katago_dir) |
|
|
if os.path.exists(katago_zip): |
|
|
os.remove(katago_zip) |
|
|
print(f"Deleted {katago_zip}.") |
|
|
os.chmod(os.path.join(katago_dir, "katago"), 0o755) |
|
|
print("KataGo setup complete.") |
|
|
except Exception as e: |
|
|
print(f"Error setting up KataGo: {e}") |
|
|
|
|
|
|
|
|
print("Downloading KataGo model...") |
|
|
model_url = "https://media.katagotraining.org/uploaded/networks/models/kata1/kata1-b18c384nbt-s9937771520-d4300882049.bin.gz" |
|
|
model_gz = "kata1-b18c384nbt-s9937771520-d4300882049.bin.gz" |
|
|
model_bin = "kata1-b18c384nbt-s9937771520-d4300882049.bin" |
|
|
|
|
|
try: |
|
|
print(f"Downloading {model_gz}...") |
|
|
response = requests.get(model_url) |
|
|
with open(model_gz, "wb") as f: |
|
|
f.write(response.content) |
|
|
print(f"Extracting {model_gz}...") |
|
|
with gzip.open(model_gz, "rb") as gz_file: |
|
|
with open(os.path.join(katago_dir, model_bin), "wb") as bin_file: |
|
|
shutil.copyfileobj(gz_file, bin_file) |
|
|
if os.path.exists(model_gz): |
|
|
os.remove(model_gz) |
|
|
print(f"Deleted {model_gz}.") |
|
|
print("KataGo model setup complete.") |
|
|
except Exception as e: |
|
|
print(f"Error setting up KataGo model: {e}") |
|
|
|
|
|
|
|
|
print("Downloading gtp2ogs...") |
|
|
gtp2ogs_url = "https://github.com/online-go/gtp2ogs/releases/download/9.0/gtp2ogs-9.0.0-linux" |
|
|
gtp2ogs_binary = "gtp2ogs" |
|
|
|
|
|
try: |
|
|
print(f"Downloading {gtp2ogs_binary}...") |
|
|
response = requests.get(gtp2ogs_url) |
|
|
with open(gtp2ogs_binary, "wb") as f: |
|
|
f.write(response.content) |
|
|
os.chmod(gtp2ogs_binary, 0o755) |
|
|
print("gtp2ogs setup complete.") |
|
|
except Exception as e: |
|
|
print(f"Error setting up gtp2ogs: {e}") |
|
|
|
|
|
|
|
|
print("Updating default_gtp.cfg...") |
|
|
default_gtp_cfg_path = os.path.join(katago_dir, "default_gtp.cfg") |
|
|
|
|
|
try: |
|
|
with open(default_gtp_cfg_path, "r") as f: |
|
|
lines = f.readlines() |
|
|
|
|
|
|
|
|
lines[54] = "logSearchInfo = true\n" |
|
|
lines[63] = "ogsChatToStderr = True\n" |
|
|
lines[300] = "# maxVisits = 500\n" |
|
|
lines[302] = "maxTime = 1.0\n" |
|
|
lines[305] = "ponderingEnabled = true\n" |
|
|
|
|
|
|
|
|
lines[113:150] = [ |
|
|
"# rules = tromp-taylor\n", |
|
|
"\n", |
|
|
"# By default, the \"rules\" parameter is used, but if you comment it out and\n", |
|
|
"# uncomment one option in each of the sections below, you can specify an\n", |
|
|
"# arbitrary combination of individual rules.\n", |
|
|
"\n", |
|
|
"# koRule = SIMPLE # Simple ko rules (triple ko = no result)\n", |
|
|
"koRule = POSITIONAL # Positional superko\n", |
|
|
"# koRule = SITUATIONAL # Situational superko\n", |
|
|
"\n", |
|
|
"scoringRule = AREA # Area scoring\n", |
|
|
"# scoringRule = TERRITORY # Territory scoring (special computer-friendly territory rules)\n", |
|
|
"\n", |
|
|
"taxRule = NONE # All surrounded empty points are scored\n", |
|
|
"# taxRule = SEKI # Eyes in seki do NOT count as points\n", |
|
|
"# taxRule = ALL # All groups are taxed up to 2 points for the two eyes needed to live\n", |
|
|
"\n", |
|
|
"# Is multiple-stone suicide legal? (Single-stone suicide is always illegal).\n", |
|
|
"# multiStoneSuicideLegal = false\n", |
|
|
"multiStoneSuicideLegal = true # Allow multi-stone suicide\n", |
|
|
"\n", |
|
|
"# \"Button go\" - the first pass when area scoring awards 0.5 points and does\n", |
|
|
"# not count for ending the game.\n", |
|
|
"# Allows area scoring rulesets that have far simpler rules to achieve the same\n", |
|
|
"# final scoring precision and reward for precise play as territory scoring.\n", |
|
|
"# hasButton = false\n", |
|
|
"# hasButton = true\n", |
|
|
"\n", |
|
|
"# Is this a human ruleset where it's okay to pass before having physically\n", |
|
|
"# captured and removed all dead stones?\n", |
|
|
"# friendlyPassOk = false\n", |
|
|
"friendlyPassOk = true # Allow friendly pass\n", |
|
|
"\n", |
|
|
"# How handicap stones in handicap games are compensated\n", |
|
|
"# whiteHandicapBonus = 0 # White gets no compensation for black's handicap stones (Tromp-taylor, NZ, JP)\n", |
|
|
"# whiteHandicapBonus = N-1 # White gets N-1 points for black's N handicap stones (AGA)\n", |
|
|
"# whiteHandicapBonus = N # White gets N points for black's N handicap stones (Chinese)\n", |
|
|
] |
|
|
|
|
|
|
|
|
with open(default_gtp_cfg_path, "w") as f: |
|
|
f.writelines(lines) |
|
|
print("default_gtp.cfg has been updated successfully!") |
|
|
except Exception as e: |
|
|
print(f"Error updating default_gtp.cfg: {e}") |
|
|
|
|
|
|
|
|
print("Generating kata_speed.json5...") |
|
|
kata_speed_config = { |
|
|
"blacklist": [""], |
|
|
"whitelist": [""], |
|
|
"allow_ranked": True, |
|
|
"decline_new_challenges": True, |
|
|
"max_games_per_player": 1, |
|
|
"hidden": False, |
|
|
"allowed_board_sizes": [19], |
|
|
"engine": "KataGo v1.15.3", |
|
|
"allow_unranked": True, |
|
|
"farewellscore": True, |
|
|
"bot": { |
|
|
"send_pv_data": True, |
|
|
"send_chats": True |
|
|
}, |
|
|
|
|
|
"allowed_correspondence_settings": None |
|
|
} |
|
|
|
|
|
try: |
|
|
with open("kata_speed.json5", "w", encoding="utf-8") as f: |
|
|
json.dump(kata_speed_config, f, indent=4, ensure_ascii=False) |
|
|
print("kata_speed.json5 has been generated successfully!") |
|
|
except Exception as e: |
|
|
print(f"Error generating kata_speed.json5: {e}") |
|
|
|
|
|
|
|
|
print("Running gtp2ogs with KataGo...") |
|
|
api_key ="3a6eabc09f8669c66cb975b9de77e49aa70d169a" |
|
|
|
|
|
|
|
|
command = [ |
|
|
"./gtp2ogs", |
|
|
"--apikey", api_key, |
|
|
"--config", "kata_speed.json5", |
|
|
"--", |
|
|
os.path.join(katago_dir, "katago"), |
|
|
"gtp", |
|
|
"-config", os.path.join(katago_dir, "default_gtp.cfg"), |
|
|
"-model", os.path.join(katago_dir, model_bin) |
|
|
] |
|
|
|
|
|
try: |
|
|
subprocess.run(command) |
|
|
except Exception as e: |
|
|
print(f"Error running gtp2ogs: {e}") |