diff --git a/katrain/__main__.py b/katrain/__main__.py index 1d43aee..3fff02e 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -123,6 +123,8 @@ class KaTrainGui(Screen, KaTrainBase): def toggle_continuous_analysis(self): self.idle_analysis = not self.idle_analysis + if not self.idle_analysis: + self.controls.set_status("", STATUS_INFO) self.update_state() def start(self): diff --git a/katrain/core/base_katrain.py b/katrain/core/base_katrain.py index a729758..a1cbf1f 100644 --- a/katrain/core/base_katrain.py +++ b/katrain/core/base_katrain.py @@ -5,6 +5,7 @@ import sys from kivy import Config from kivy.storage.jsonstore import JsonStore +from katrain.core.ai import ai_rank_estimation from katrain.core.constants import * from katrain.core.utils import find_package_resource @@ -135,6 +136,13 @@ class KaTrainBase: def update_player(self, bw, **kwargs): self.players_info[bw].update(**kwargs) + self.update_calculated_ranks() + + def update_calculated_ranks(self): + 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) def reset_players(self): self.update_player("B") diff --git a/katrain/core/constants.py b/katrain/core/constants.py index b331ba7..ec156e3 100644 --- a/katrain/core/constants.py +++ b/katrain/core/constants.py @@ -86,3 +86,4 @@ AI_OPTION_VALUES = { "automatic": "bool", "pda": [(x / 10, f"{'W' if x<0 else 'B'}+{abs(x/10):.1f}") for x in range(-30, 31)], } +AI_KEY_PROPERTIES = {"kyu_rank", "strength", "weaken_fac", "pick_frac", "pick_n", "automatic"} diff --git a/katrain/core/lang.py b/katrain/core/lang.py index 0e286ce..af3299c 100644 --- a/katrain/core/lang.py +++ b/katrain/core/lang.py @@ -77,3 +77,12 @@ class Lang(Observable): DEFAULT_LANGUAGE = "en" i18n = Lang(DEFAULT_LANGUAGE) + + +def rank_label(rank): + if rank is None: + return "??k" + if rank > 0: + return f"{rank:.0f}{i18n._('strength:dan')}" + else: + return f"{1-rank:.0f}{i18n._('strength:kyu')}" \ No newline at end of file diff --git a/katrain/gui.kv b/katrain/gui.kv index 7fd131b..2c03d82 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -297,8 +297,8 @@ text_size: self.size halign: 'center' valign: 'middle' - shorten: True - shorten_from: 'right' + shorten: root.player_type==PLAYER_HUMAN # overflow/cut rank off AI names + max_lines: 1 : height: self.width diff --git a/katrain/gui/controlspanel.py b/katrain/gui/controlspanel.py index f0d337f..ff8a53f 100644 --- a/katrain/gui/controlspanel.py +++ b/katrain/gui/controlspanel.py @@ -7,6 +7,7 @@ from kivy.uix.boxlayout import BoxLayout from kivymd.uix.floatlayout import MDFloatLayout from katrain.core.constants import MODE_PLAY, MODE_ANALYZE, STATUS_ERROR, STATUS_ANALYSIS, PLAYER_HUMAN +from katrain.core.lang import rank_label from katrain.gui.kivyutils import AnalysisToggle, CollapsablePanel @@ -80,7 +81,11 @@ class ControlsPanel(BoxLayout): self.players[bw].player_type = player_info.player_type self.players[bw].player_subtype = player_info.player_subtype self.players[bw].name = player_info.name - self.players[bw].rank = player_info.sgf_rank if player_info.player_type == PLAYER_HUMAN else player_info.calculated_rank + self.players[bw].rank = ( + player_info.sgf_rank + if player_info.player_type == PLAYER_HUMAN + else rank_label(player_info.calculated_rank) + ) def set_status(self, msg, status_type, at_node=None): at_node = at_node or self.katrain and self.katrain.game and self.katrain.game.current_node diff --git a/katrain/gui/popups.py b/katrain/gui/popups.py index e0368b8..8f730ac 100644 --- a/katrain/gui/popups.py +++ b/katrain/gui/popups.py @@ -25,9 +25,10 @@ from katrain.core.constants import ( OUTPUT_ERROR, OUTPUT_INFO, STATUS_INFO, + AI_KEY_PROPERTIES, ) from katrain.core.engine import KataGoEngine -from katrain.core.lang import i18n +from katrain.core.lang import i18n, rank_label from katrain.core.utils import PATHS, find_package_resource from katrain.gui.kivyutils import BackgroundMixin, I18NSpinner from katrain.gui.style import DEFAULT_FONT, EVAL_COLORS @@ -138,6 +139,7 @@ class LabelledIntInput(LabelledTextInput): class LabelledSelectionSlider(BoxLayout): input_property = StringProperty("") values = ListProperty([(0, "")]) # (value:numeric,label:string) pairs + key_option = BooleanProperty(False) def set_value(self, v): self.slider.set_value(v) @@ -319,19 +321,17 @@ class ConfigAIPopup(QuickConfigGui): def estimate_rank_from_options(self, *_args): strategy = self.ai_select.selected[1] options = self.collect_properties(self) # [strategy] - print(strategy, options) prefix = f"ai/{strategy}/" options = {k[len(prefix) :]: v for k, v in options.items() if k.startswith(prefix)} - print(options) dan_rank, model_based = ai_rank_estimation(strategy, options) - self.estimated_rank_label.text = ("" if model_based else "~") + RankGraph.rank_label(dan_rank) + self.estimated_rank_label.text = ("" if model_based else "~") + rank_label(dan_rank) def build_ai_options(self, *_args): strategy = self.ai_select.selected[1] mode_settings = self.katrain.config(f"ai/{strategy}") self.options_grid.clear_widgets() self.help_label.text = i18n._(strategy.replace("ai:", "aihelp:")) - for k, v in sorted(mode_settings.items(), key=lambda kv: kv[0]): + for k, v in sorted(mode_settings.items(), key=lambda kv: (kv[0] not in AI_KEY_PROPERTIES, kv[0])): self.options_grid.add_widget(DescriptionLabel(text=k, size_hint_x=0.25)) if k in AI_OPTION_VALUES: values = AI_OPTION_VALUES[k] @@ -344,7 +344,9 @@ class ConfigAIPopup(QuickConfigGui): fixed_values = [(v, re.sub(r"\[(.*?)\]", lambda m: i18n._(m[1]), l)) for v, l in values] else: # just numbers fixed_values = [(v, str(v)) for v in values] - widget = LabelledSelectionSlider(values=fixed_values, input_property=f"ai/{strategy}/{k}") + widget = LabelledSelectionSlider( + values=fixed_values, input_property=f"ai/{strategy}/{k}", key_option=(k in AI_KEY_PROPERTIES) + ) widget.set_value(v) widget.textbox.bind(text=self.estimate_rank_from_options) self.options_grid.add_widget(wrap_anchor(widget)) @@ -356,6 +358,10 @@ class ConfigAIPopup(QuickConfigGui): self.options_grid.add_widget(Label(size_hint_x=None)) Clock.schedule_once(self.estimate_rank_from_options) + def update_config(self, save_to_file=True): + super().update_config(save_to_file=save_to_file) + self.katrain.update_calculated_ranks() + class ConfigPopup(QuickConfigGui): def __init__(self, katrain): diff --git a/katrain/gui/widgets/graph.py b/katrain/gui/widgets/graph.py index 14ea4db..dc7ee6f 100644 --- a/katrain/gui/widgets/graph.py +++ b/katrain/gui/widgets/graph.py @@ -7,7 +7,7 @@ from kivy.properties import BooleanProperty, Clock, ListProperty, NumericPropert from kivymd.app import MDApp from katrain.core.constants import OUTPUT_ERROR -from katrain.core.lang import i18n +from katrain.core.lang import rank_label from katrain.gui.kivyutils import BackgroundMixin @@ -179,13 +179,6 @@ class RankGraph(Graph): self.calculate_trigger = Clock.create_trigger(lambda *args: self.rank_game(), 0.25) self.rank_by_player = {} - @staticmethod - def rank_label(rank): - if rank > 0: - return f"{rank:.0f}{i18n._('strength:dan')}" - else: - return f"{1-rank:.0f}{i18n._('strength:kyu')}" - @staticmethod def calculate_rank_for_player(segment_stats, num_intersec, player): non_obvious_moves = [ @@ -284,9 +277,9 @@ class RankGraph(Graph): min_rank -= 1 rank_range = max_rank - min_rank - self.ids.mid_marker.text = self.rank_label((max_rank + min_rank) / 2) - self.ids.top_marker.text = self.rank_label(max_rank) - self.ids.bottom_marker.text = self.rank_label(min_rank) + self.ids.mid_marker.text = rank_label((max_rank + min_rank) / 2) + self.ids.top_marker.text = rank_label(max_rank) + self.ids.bottom_marker.text = rank_label(min_rank) graph_points = {} for pl, rank_points in self.rank_by_player.items(): diff --git a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo index f47d12d..6ad6cb1 100644 Binary files a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po index 6af9d59..701e8d8 100644 --- a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po @@ -588,7 +588,7 @@ msgstr "Continuously analyze" #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" diff --git a/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo index 0f8649a..6f262ec 100644 Binary files a/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/de/LC_MESSAGES/katrain.po b/katrain/i18n/locales/de/LC_MESSAGES/katrain.po index f4d0c02..82867b1 100644 --- a/katrain/i18n/locales/de/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/de/LC_MESSAGES/katrain.po @@ -631,7 +631,7 @@ msgstr "Continuous analysis" #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo index a81cc38..9519f28 100644 Binary files a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po index 2843e4f..3854a0b 100644 --- a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po @@ -520,7 +520,7 @@ msgstr "" #. ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" msgid "aihelp:handicap" msgstr "" diff --git a/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo index 3d5b857..54f70c2 100644 Binary files a/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/es/LC_MESSAGES/katrain.po b/katrain/i18n/locales/es/LC_MESSAGES/katrain.po index d7b03b5..14c7895 100644 --- a/katrain/i18n/locales/es/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/es/LC_MESSAGES/katrain.po @@ -618,7 +618,7 @@ msgstr "Analizar continuamente " #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" @@ -635,3 +635,4 @@ msgstr "Estimated Strength" #. TODO - label in little popup for analyzing entire game msgid "reanalyze max visits" msgstr "Number of visits per move" + diff --git a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo index b595a3c..79cb69b 100644 Binary files a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po index 99fde04..bd22511 100644 --- a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po @@ -665,7 +665,7 @@ msgstr "Continuous analysis" #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo index 97a171b..218461a 100644 Binary files a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po index c1fbe13..4639f1d 100644 --- a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po @@ -603,7 +603,7 @@ msgstr "Continuous analysis" #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" diff --git a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo index c0efa77..0bb0e33 100644 Binary files a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po index 22a574d..87db126 100644 --- a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po @@ -628,7 +628,7 @@ msgstr "Continuous analysis" #. TODO - ai which handles handicap games better msgid "ai:handicap" -msgstr "KataGo Handicap" +msgstr "KataHandicap" #. TODO msgid "aihelp:handicap" diff --git a/katrain/popups.kv b/katrain/popups.kv index 589c672..9f16abd 100644 --- a/katrain/popups.kv +++ b/katrain/popups.kv @@ -403,7 +403,7 @@ values: root.values on_select: textbox.text = str(slider.value) track_color: LIGHTGREY - thumb_color: 0.5, 0.6, 0.8, 1 + thumb_color: (0.6, 0.7, 0.9, 1) if root.key_option else (0.3, 0.4, 0.6, 1) LabelledFloatInput: id: textbox