diff --git a/katrain/__main__.py b/katrain/__main__.py index 605b697..8e5f7fc 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -112,9 +112,10 @@ class KaTrainGui(Screen, KaTrainBase): return if "ready" in message.lower(): self.controls.set_status(f"KataGo engine ready.", STATUS_INFO) - if (level == OUTPUT_ERROR or (level == OUTPUT_KATAGO_STDERR and "error" in message.lower())) and getattr( - self, "controls", None - ): + if ( + level == OUTPUT_ERROR + or (level == OUTPUT_KATAGO_STDERR and "error" in message.lower() and "tuning" not in message.lower()) + ) and getattr(self, "controls", None): self.controls.set_status(f"ERROR: {message}", STATUS_ERROR) @property diff --git a/katrain/config.json b/katrain/config.json index c201cb2..9b9fedf 100644 --- a/katrain/config.json +++ b/katrain/config.json @@ -77,7 +77,7 @@ "target_score": 0.5 }, "ai:scoreloss": { - "strength": 0.25 + "strength": 0.2 }, "ai:policy": { "opening_moves": 22.0 @@ -103,13 +103,13 @@ "pick_override": 0.85, "stddev": 7.5, "pick_n": 5, - "pick_frac": 0.5, + "pick_frac": 0.4, "endgame": 0.45 }, "ai:p:influence": { "pick_override": 0.95, "pick_n": 5, - "pick_frac": 0.4, + "pick_frac": 0.3, "threshold": 3.5, "line_weight": 10, "endgame": 0.4 @@ -117,7 +117,7 @@ "ai:p:territory": { "pick_override": 0.95, "pick_n": 5, - "pick_frac": 0.4, + "pick_frac": 0.3, "threshold": 3.5, "line_weight": 2, "endgame": 0.4 diff --git a/katrain/core/ai.py b/katrain/core/ai.py index df968cd..674799e 100644 --- a/katrain/core/ai.py +++ b/katrain/core/ai.py @@ -30,6 +30,7 @@ from katrain.core.constants import ( AI_TENUKI_ELO_GRID, AI_TERRITORY_ELO_GRID, AI_INFLUENCE_ELO_GRID, + AI_PICK_ELO_GRID, ) from katrain.core.game import Game, GameNode, Move from katrain.core.utils import var_to_grid @@ -61,16 +62,18 @@ def interp2d(gridspec, x, y): ) -def ai_rank_estimation(strategy, settings) -> Tuple[int, bool]: +def ai_rank_estimation(strategy, settings) -> int: if strategy in [AI_DEFAULT, AI_HANDICAP, AI_JIGO]: - return 9, True + return 9 if strategy == AI_RANK: return 1 - settings["kyu_rank"], True - if strategy in [AI_WEIGHTED, AI_SCORELOSS, AI_LOCAL, AI_TENUKI, AI_TERRITORY, AI_INFLUENCE]: + if strategy in [AI_WEIGHTED, AI_SCORELOSS, AI_LOCAL, AI_TENUKI, AI_TERRITORY, AI_INFLUENCE, AI_PICK]: if strategy == AI_WEIGHTED: elo = interp1d(AI_WEIGHTED_ELO, settings["weaken_fac"]) if strategy == AI_SCORELOSS: elo = interp1d(AI_SCORELOSS_ELO, settings["strength"]) + if strategy == AI_PICK: + elo = interp2d(AI_PICK_ELO_GRID, settings["pick_frac"], settings["pick_n"]) if strategy == AI_LOCAL: elo = interp2d(AI_LOCAL_ELO_GRID, settings["pick_frac"], settings["pick_n"]) if strategy == AI_TENUKI: @@ -81,9 +84,9 @@ def ai_rank_estimation(strategy, settings) -> Tuple[int, bool]: elo = interp2d(AI_INFLUENCE_ELO_GRID, settings["pick_frac"], settings["pick_n"]) kyu = interp1d(CALIBRATED_RANK_ELO, elo) - return 1 - kyu, True + return 1 - kyu else: - return AI_STRENGTH[strategy], False + return AI_STRENGTH[strategy] def weighted_selection_without_replacement(items: List[Tuple], pick_n: int) -> List[Tuple]: diff --git a/katrain/core/base_katrain.py b/katrain/core/base_katrain.py index a1cbf1f..627a3de 100644 --- a/katrain/core/base_katrain.py +++ b/katrain/core/base_katrain.py @@ -142,7 +142,7 @@ class KaTrainBase: for bw, player_info in self.players_info.items(): if player_info.player_type == PLAYER_AI: settings = self.config(f"ai/{player_info.strategy}") - player_info.calculated_rank, _ = ai_rank_estimation(player_info.player_subtype, settings) + player_info.calculated_rank = ai_rank_estimation(player_info.player_subtype, settings) def reset_players(self): self.update_player("B") diff --git a/katrain/core/constants.py b/katrain/core/constants.py index 6c72303..768ad43 100644 --- a/katrain/core/constants.py +++ b/katrain/core/constants.py @@ -55,7 +55,7 @@ AI_STRATEGIES_RECOMMENDED_ORDER = [ AI_JIGO, ] -AI_STRENGTH = { # dan ranks +AI_STRENGTH = { # dan ranks, backup if model is missing. TODO: remove some? AI_DEFAULT: 9, AI_POLICY: 5, AI_JIGO: float("nan"), @@ -143,59 +143,59 @@ AI_LOCAL_ELO_GRID = [ [0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0], [0, 5, 10, 15, 25, 50], [ - [450.0, 704.0, 1190.0, 1282.0, 1520.0, 1464.0, 1617.0, 1700.0], - [153.0, 1079.0, 1144.0, 1335.0, 1440.0, 1525.0, 1700.0, 1700.0], - [606.0, 1185.0, 1268.0, 1484.0, 1404.0, 1544.0, 1700.0, 1700.0], - [911.0, 1230.0, 1312.0, 1352.0, 1432.0, 1564.0, 1700.0, 1700.0], - [1212.0, 1326.0, 1393.0, 1441.0, 1446.0, 1601.0, 1700.0, 1700.0], - [1321.0, 1395.0, 1399.0, 1473.0, 1582.0, 1700.0, 1700.0, 1700.0], + [-204.0, 791.0, 1154.0, 1372.0, 1402.0, 1473.0, 1700.0, 1700.0], + [174.0, 1094.0, 1191.0, 1384.0, 1435.0, 1522.0, 1700.0, 1700.0], + [619.0, 1155.0, 1323.0, 1390.0, 1450.0, 1558.0, 1700.0, 1700.0], + [975.0, 1289.0, 1332.0, 1401.0, 1461.0, 1575.0, 1700.0, 1700.0], + [1344.0, 1348.0, 1358.0, 1467.0, 1477.0, 1616.0, 1700.0, 1700.0], + [1425.0, 1474.0, 1489.0, 1524.0, 1571.0, 1700.0, 1700.0, 1700.0], ], ] AI_TENUKI_ELO_GRID = [ [0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0], [0, 5, 10, 15, 25, 50], [ - [491.0, 394.0, 527.0, 676.0, 732.0, 959.0, 1415.0, 1700.0], - [21.0, 456.0, 620.0, 719.0, 812.0, 1027.0, 1308.0, 1700.0], - [306.0, 480.0, 689.0, 705.0, 925.0, 1154.0, 1397.0, 1700.0], - [286.0, 534.0, 636.0, 796.0, 968.0, 1077.0, 1443.0, 1700.0], - [534.0, 645.0, 665.0, 846.0, 999.0, 1134.0, 1422.0, 1700.0], - [746.0, 719.0, 806.0, 975.0, 1048.0, 1370.0, 1505.0, 1700.0], + [47.0, 335.0, 530.0, 678.0, 830.0, 1070.0, 1376.0, 1700.0], + [99.0, 469.0, 546.0, 707.0, 855.0, 1090.0, 1413.0, 1700.0], + [327.0, 513.0, 605.0, 745.0, 875.0, 1110.0, 1424.0, 1700.0], + [429.0, 519.0, 620.0, 754.0, 900.0, 1130.0, 1435.0, 1700.0], + [492.0, 607.0, 682.0, 797.0, 1000.0, 1208.0, 1454.0, 1700.0], + [778.0, 830.0, 909.0, 949.0, 1169.0, 1461.0, 1483.0, 1700.0], ], ] AI_TERRITORY_ELO_GRID = [ [0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0], [0, 5, 10, 15, 25, 50], [ - [512.0, 451.0, 640.0, 686.0, 929.0, 1112.0, 1533.0, 1700.0], - [155.0, 419.0, 614.0, 761.0, 879.0, 1118.0, 1507.0, 1700.0], - [338.0, 449.0, 716.0, 945.0, 949.0, 1282.0, 1520.0, 1700.0], - [400.0, 495.0, 702.0, 875.0, 950.0, 1309.0, 1520.0, 1700.0], - [570.0, 635.0, 707.0, 981.0, 922.0, 1346.0, 1519.0, 1700.0], - [713.0, 772.0, 839.0, 1095.0, 1217.0, 1468.0, 1700.0, 1700.0], + [34.0, 383.0, 566.0, 748.0, 980.0, 1264.0, 1527.0, 1700.0], + [131.0, 450.0, 586.0, 826.0, 995.0, 1280.0, 1537.0, 1700.0], + [291.0, 517.0, 627.0, 850.0, 1010.0, 1310.0, 1547.0, 1700.0], + [454.0, 526.0, 696.0, 870.0, 1038.0, 1340.0, 1590.0, 1700.0], + [491.0, 603.0, 747.0, 890.0, 1050.0, 1390.0, 1635.0, 1700.0], + [718.0, 841.0, 1039.0, 1076.0, 1332.0, 1523.0, 1700.0, 1700.0], ], ] AI_INFLUENCE_ELO_GRID = [ [0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0], [0, 5, 10, 15, 25, 50], [ - [570.0, 293.0, 536.0, 774.0, 919.0, 1236.0, 1491.0, 1518.0], - [238.0, 461.0, 628.0, 833.0, 859.0, 1211.0, 1459.0, 1592.0], - [323.0, 513.0, 667.0, 837.0, 941.0, 1224.0, 1504.0, 1576.0], - [407.0, 545.0, 659.0, 899.0, 988.0, 1215.0, 1483.0, 1602.0], - [457.0, 713.0, 785.0, 856.0, 1142.0, 1309.0, 1508.0, 1506.0], - [774.0, 903.0, 942.0, 1098.0, 1339.0, 1449.0, 1469.0, 1495.0], + [217.0, 439.0, 572.0, 768.0, 960.0, 1227.0, 1449.0, 1521.0], + [302.0, 551.0, 580.0, 800.0, 1028.0, 1257.0, 1470.0, 1529.0], + [388.0, 572.0, 619.0, 839.0, 1077.0, 1305.0, 1490.0, 1561.0], + [467.0, 591.0, 764.0, 878.0, 1097.0, 1390.0, 1530.0, 1591.0], + [539.0, 622.0, 815.0, 953.0, 1120.0, 1420.0, 1560.0, 1601.0], + [772.0, 912.0, 958.0, 1145.0, 1318.0, 1511.0, 1577.0, 1623.0], ], ] AI_PICK_ELO_GRID = [ [0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0], [0, 5, 10, 15, 25, 50], [ - [106.0, 148.0, 94.0, 218.0, 606.0, 1063.0, 1426.0, 1458.0], - [114.0, 69.0, 278.0, 385.0, 683.0, 1099.0, 1425.0, 1517.0], - [144.0, 174.0, 186.0, 452.0, 730.0, 1153.0, 1430.0, 1447.0], - [145.0, 105.0, 380.0, 548.0, 863.0, 1233.0, 1423.0, 1448.0], - [202.0, 251.0, 460.0, 651.0, 919.0, 1321.0, 1554.0, 1482.0], - [472.0, 538.0, 816.0, 971.0, 1169.0, 1422.0, 1522.0, 1491.0], + [-533.0, -515.0, -355.0, 234.0, 650.0, 1147.0, 1546.0, 1700.0], + [-531.0, -450.0, -69.0, 347.0, 670.0, 1182.0, 1550.0, 1700.0], + [-450.0, -311.0, 140.0, 459.0, 693.0, 1252.0, 1555.0, 1700.0], + [-365.0, -82.0, 265.0, 508.0, 864.0, 1301.0, 1619.0, 1700.0], + [-113.0, 273.0, 363.0, 641.0, 983.0, 1486.0, 1700.0, 1700.0], + [514.0, 670.0, 870.0, 1128.0, 1305.0, 1550.0, 1700.0, 1700.0], ], ] diff --git a/katrain/gui/popups.py b/katrain/gui/popups.py index 3100d55..59616cd 100644 --- a/katrain/gui/popups.py +++ b/katrain/gui/popups.py @@ -331,8 +331,8 @@ class ConfigAIPopup(QuickConfigGui): return prefix = f"ai/{strategy}/" options = {k[len(prefix) :]: v for k, v in options.items() if k.startswith(prefix)} - dan_rank, model_based = ai_rank_estimation(strategy, options) - self.estimated_rank_label.text = ("" if model_based else "~") + rank_label(dan_rank) + dan_rank = ai_rank_estimation(strategy, options) + self.estimated_rank_label.text = rank_label(dan_rank) def build_ai_options(self, *_args): strategy = self.ai_select.selected[1] diff --git a/tests/test_ai.py b/tests/test_ai.py index cd97314..e49c366 100644 --- a/tests/test_ai.py +++ b/tests/test_ai.py @@ -40,6 +40,5 @@ class TestAI: katrain = KaTrainBase(force_package_config=True, debug_level=0) for strategy in AI_STRATEGIES: settings = katrain.config(f"ai/{strategy}") - rank, flag = ai_rank_estimation(strategy, settings) + rank = ai_rank_estimation(strategy, settings) assert -20 <= rank <= 9 - assert isinstance(flag, bool)