| | 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}") |