diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 2c4ce50..fb43441 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -6,7 +6,7 @@ Matthew Allred ("Kameone") for design of the v1.1 UI and providing MacOS install "isty2e" for the Korean translation. "Dontbtme" for detailed feedback and early testing of v1.0, and the French translation. "bale-go" for implementing and calibrating the 'calibrated rank' AI. -"isty2e" for the German translation. +"nimets123" for the German translation and sound effects. Additional thanks to: "Seventeen" for explanatory youtube videos. diff --git a/i18n.py b/i18n.py index 44ec93c..14520e7 100644 --- a/i18n.py +++ b/i18n.py @@ -59,11 +59,8 @@ for lang in locales: errors = True elif DEFAULT_LANG in strings_to_langs[msgid]: copied_msg = strings_to_langs[msgid][DEFAULT_LANG] - if lang == "haha": - entry = polib.POEntry(msgid=msgid, msgstr="ㅋㅋ" + copied_msg) - else: - print("Message id", msgid, "missing in ", lang, "-> Adding it from", DEFAULT_LANG) - entry = polib.POEntry(msgid=msgid, msgstr=copied_msg, comment="TODO") + print("Message id", msgid, "missing in ", lang, "-> Adding it from", DEFAULT_LANG) + entry = polib.POEntry(msgid=msgid, msgstr=copied_msg, comment="TODO") po[lang].append(entry) errors = True else: diff --git a/katrain/__main__.py b/katrain/__main__.py index 3b8b70d..8356483 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -20,7 +20,7 @@ try: WINDOW_SCALE_FAC = max(0.4,scale) except Exception as e: print(f"Exception {e} while getting screen resolution (if on MacOS, 'pip3 install screeninfo' manually or ignore this)") - WINDOW_SCALE_FAC = 0.85 + WINDOW_SCALE_FAC = 0.85 Config.set("graphics", "width", int(WINDOW_SCALE_FAC*WINDOW_X)) Config.set("graphics", "height", int(WINDOW_SCALE_FAC*WINDOW_Y)) @@ -160,12 +160,12 @@ class KaTrainGui(Screen, KaTrainBase): return cn = self.game.current_node last_player, next_player = self.players_info[cn.player], self.players_info[cn.next_player] - if self.play_analyze_mode == MODE_PLAY: - teaching_undo = cn.player and last_player.being_taught + print('update state',self.play_analyze_mode == MODE_PLAY , self.nav_drawer.state != "open" , self.popup_open is None) + if self.play_analyze_mode == MODE_PLAY and self.nav_drawer.state != "open" and self.popup_open is None: + teaching_undo = cn.player and last_player.being_taught and cn.parent if ( teaching_undo and cn.analysis_ready - and cn.parent and cn.parent.analysis_ready and not cn.children and not self.game.ended @@ -177,11 +177,9 @@ class KaTrainGui(Screen, KaTrainBase): and not cn.children and not self.game.ended and not (teaching_undo and cn.auto_undo is None) - ): - self._do_ai_move( - cn - ) # cn mismatch stops this if undo fired. avoid message loop here or fires repeatedly. - Clock.schedule_once(lambda _dt: self.update_gui(cn,redraw_board=redraw_board),-1) + ): # cn mismatch stops this if undo fired. avoid message loop here or fires repeatedly. + self._do_ai_move(cn) + Clock.schedule_once(lambda _dt: self.update_gui(cn, redraw_board=redraw_board), -1) def update_player(self, bw, **kwargs): @@ -317,7 +315,7 @@ class KaTrainGui(Screen, KaTrainBase): title_key="load sgf title", size=[dp(1200), dp(800)], content=popup_contents ).__self__ - def readfile(*args): + def readfile(*_args): files = popup_contents.filesel.selection self.fileselect_popup.dismiss() try: @@ -345,8 +343,8 @@ class KaTrainGui(Screen, KaTrainBase): return try: move_tree = KaTrainSGF.parse(clipboard) - except Exception as e: - self.controls.set_status(i18n._("Failed to import from clipboard").format(error=e, contents=clipboard[:50])) + except Exception as exc: + self.controls.set_status(i18n._("Failed to import from clipboard").format(error=exc, contents=clipboard[:50])) return move_tree.nodes_in_tree[-1].analyze( self.engine, analyze_fast=False @@ -385,15 +383,23 @@ class KaTrainGui(Screen, KaTrainBase): "f8": ("config-popup",), } + + @property + def popup_open(self) -> Popup: + app = App.get_running_app() + first_child = app.root_window.children[0] + return first_child if isinstance(first_child, Popup) else None + def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers): if self.controls.note.focus: return # when making notes, don't allow keyboard shortcuts - app = App.get_running_app() - first_child = app.root_window.children[0] - if isinstance(first_child, Popup): - if keycode[1] not in ["f5", "f6", "f7", "f8"]: + + popup = self.popup_open + if popup: + if keycode[1] in ["f5", "f6", "f7", "f8"]: # switch between popups + popup.dismiss() + else: return - first_child.dismiss() shortcuts = self.shortcuts if keycode[1] == "tab": @@ -412,8 +418,6 @@ class KaTrainGui(Screen, KaTrainBase): self("new-game-popup") elif keycode[1] == "l" and "ctrl" in modifiers: self("analyze-sgf-popup") - elif keycode[1] == "f12" and "ctrl" in modifiers: - app.language = "haha" elif keycode[1] == "s" and "ctrl" in modifiers: self("output-sgf") elif keycode[1] == "c" and "ctrl" in modifiers: @@ -436,8 +440,6 @@ class KaTrainApp(MDApp): def __init__(self): super().__init__() -# self.theme_cls.selected_color = WHITE -# self.theme_cls.secondary_text_color = LIGHTGREY def build(self): self.icon = ICON # how you're supposed to set an icon @@ -460,9 +462,8 @@ class KaTrainApp(MDApp): def on_language(self, _instance, language): self.gui.log(f"Switching language to {language}", OUTPUT_INFO) i18n.switch_lang(language) - if language != "haha": - self.gui._config["general"]["lang"] = language - self.gui.save_config() + self.gui._config["general"]["lang"] = language + self.gui.save_config() if self.gui.game: self.gui.update_state() self.gui.controls.set_status("") diff --git a/katrain/gui.kv b/katrain/gui.kv index bc921e5..97ba841 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -1084,6 +1084,7 @@ width: self.height * 0.5 height: root.height - analysis_controls.height swipe_edge_width: 0 + on_state: if self.state=='close': root.update_state() # ai move etc on nav drawer close HamburgerMenuContents: id: nav_drawer_contents diff --git a/katrain/i18n/locales/haha/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/haha/LC_MESSAGES/katrain.mo deleted file mode 100644 index 6dc15a2..0000000 Binary files a/katrain/i18n/locales/haha/LC_MESSAGES/katrain.mo and /dev/null differ diff --git a/katrain/i18n/locales/haha/LC_MESSAGES/katrain.po b/katrain/i18n/locales/haha/LC_MESSAGES/katrain.po deleted file mode 100644 index 55f8578..0000000 --- a/katrain/i18n/locales/haha/LC_MESSAGES/katrain.po +++ /dev/null @@ -1,543 +0,0 @@ -# KaTrain i18n file -msgid "" -msgstr "" -"Language: ㅋㅋㅋ\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "analysis:equalize" -msgstr "ㅋㅋEqualize visits of potential moves" - -msgid "Engine died unexpectedly" -msgstr "" -"ㅋㅋEngine died unexpectedly without sending output, possibly due to out of " -"memory: {error}" - -msgid "general settings" -msgstr "ㅋㅋGeneral Settings" - -msgid "ai:p:local" -msgstr "ㅋㅋLocal Style" - -msgid "point loss threshold" -msgstr "ㅋㅋPoint loss greater than" - -msgid "chinese" -msgstr "ㅋㅋChinese" - -msgid "load sgf rewind" -msgstr "ㅋㅋRewind to start" - -msgid "save dots" -msgstr "ㅋㅋSave in SGF" - -msgid "ai-ponder" -msgstr "" -"ㅋㅋThis simply indicates the Engine status, going from green (idle) to orange" -" (processing queries). It turns red when the engine has crashed or fails to " -"start." - -msgid "ruleset" -msgstr "ㅋㅋRules" - -msgid "non square board hint" -msgstr "ㅋㅋUse x:y (e.g. 19:9) for non-square size" - -msgid "menu:save" -msgstr "ㅋㅋSave Game" - -msgid "new game" -msgstr "ㅋㅋStart New Game" - -msgid "menu:load" -msgstr "ㅋㅋLoad Game" - -msgid "byoyomi length" -msgstr "ㅋㅋTime per Byo-yomi Period" - -msgid "player:ai" -msgstr "ㅋㅋAI" - -msgid "menu:aisettings" -msgstr "ㅋㅋAI Settings" - -msgid "sgf written" -msgstr "ㅋㅋSGF with analysis written to {file_name}" - -msgid "load sgf fast analysis" -msgstr "ㅋㅋUse fast analysis" - -msgid "btn:Analyze" -msgstr "ㅋㅋAnalysis Options" - -msgid "load sgf title" -msgstr "ㅋㅋLoad SGF File to Analyze" - -msgid "ai:policy" -msgstr "ㅋㅋPolicy" - -msgid "show last n dots" -msgstr "" -"ㅋㅋShow dots for the last\n" -" moves" - -msgid "engine:fast_visits" -msgstr "ㅋㅋMaximum number of visits in fast analysis" - -msgid "engine:max_visits" -msgstr "ㅋㅋMaximum number of visits in analysis" - -msgid "teacher settings" -msgstr "ㅋㅋEdit Teacher Settings" - -msgid "count down sound" -msgstr "ㅋㅋSound on" - -msgid "stats:pointslost" -msgstr "ㅋㅋPoints Lost" - -msgid "Copied SGF to clipboard." -msgstr "ㅋㅋCopied SGF to clipboard." - -msgid "Info:point loss" -msgstr "ㅋㅋEstimated point loss: {points_lost:.1f}" - -msgid "analysis:topmoves" -msgstr "" -"ㅋㅋTop\n" -"Moves" - -msgid "engine:wide_root_noise:hint" -msgstr "" -"ㅋㅋUse 0.02-0.1 to show\n" -"more possible moves" - -msgid "Info:best move" -msgstr "ㅋㅋMove was predicted best move" - -msgid "analysis:policy" -msgstr "" -"ㅋㅋPolicy\n" -"Moves" - -msgid "ai:p:tenuki" -msgstr "ㅋㅋTenuki Style" - -msgid "Info:undo predicted PV" -msgstr "ㅋㅋPredicted follow-up: {pv}" - -msgid "ai settings" -msgstr "ㅋㅋAdvanced AI Settings" - -msgid "stats:winrate" -msgstr "ㅋㅋWin Rate" - -msgid "ai:p:territory" -msgstr "ㅋㅋTerritorial Style" - -msgid "engine:wide_root_noise" -msgstr "ㅋㅋWide root noise (increases variety of moves considered)" - -msgid "analysis:territory" -msgstr "" -"ㅋㅋExpected\n" -"Territory" - -msgid "engine:katago" -msgstr "ㅋㅋPath to KataGo executable" - -msgid "wait-before-equalize" -msgstr "" -"ㅋㅋWait for initial analysis to complete before requesting a refinement." - -msgid "closedlabel:movestats" -msgstr "ㅋㅋMove Stats" - -msgid "menu:support" -msgstr "ㅋㅋSupport" - -msgid "Failed to import from clipboard" -msgstr "" -"ㅋㅋFailed to import game from clipboard: {error}\n" -"Clipboard contents: {contents}..." - -msgid "btn:Analysis" -msgstr "ㅋㅋAnalysis" - -msgid "aga" -msgstr "ㅋㅋAGA" - -msgid "teaching undo message" -msgstr "" -"ㅋㅋUndid move {move} as it lost {points_lost:.1f} points. Hover over the move" -" to see expected refutation. Please try again." - -msgid "menu:newgame" -msgstr "ㅋㅋNew Game" - -msgid "move" -msgstr "ㅋㅋMove {number}" - -msgid "board-game-end" -msgstr "" -"ㅋㅋgame\n" -"end" - -msgid "No analysis available" -msgstr "ㅋㅋNo analysis available" - -msgid "aihelp:p:influence" -msgstr "" -"ㅋㅋPicks moves biased above the `threshold` line and plays the best one. " -"Increase `line_weight` to penalize moves near the edge more. Stops strategy " -"after the 'endgame' fraction of the board is filled." - -msgid "tab:info" -msgstr "ㅋㅋInfo" - -msgid "engine:config" -msgstr "ㅋㅋPath to KataGo config file" - -msgid "ai:default" -msgstr "ㅋㅋKataGo" - -msgid "lock ai when playing" -msgstr "" -"ㅋㅋDisable top moves\n" -" while in play mode" - -msgid "player:type" -msgstr "ㅋㅋPlayer" - -msgid "show dots" -msgstr "ㅋㅋShow dots" - -msgid "closedlabel:info¬es" -msgstr "ㅋㅋMove Info & Notes" - -msgid "Info:top move" -msgstr "ㅋㅋPredicted top move was {top_move} ({score})." - -msgid "aihelp:scoreloss" -msgstr "" -"ㅋㅋPlays moves that lead to more points lost with lower probability. Likely " -"to play more varied/weaker with higher visits settings." - -msgid "num undos" -msgstr "ㅋㅋNumber of undos" - -msgid "ai:p:weighted" -msgstr "ㅋㅋPolicy Weighted" - -msgid "analysis:sweep" -msgstr "ㅋㅋFast analysis of all moves" - -msgid "update teacher" -msgstr "ㅋㅋUpdate Feedback Settings" - -msgid "japanese" -msgstr "ㅋㅋJapanese" - -msgid "btn:Play" -msgstr "ㅋㅋPlay" - -msgid "ai:p:pick" -msgstr "ㅋㅋBlinded Policy" - -msgid "aihelp:p:territory" -msgstr "" -"ㅋㅋPicks moves biased below the `threshold` line and plays the best one. " -"Increase `line_weight` to penalize moves near the center more. Stops " -"strategy after the 'endgame' fraction of the board is filled." - -msgid "timer settings" -msgstr "ㅋㅋAdjust Timer Settings" - -msgid "file not found" -msgstr "ㅋㅋPath does not exist" - -msgid "config file path" -msgstr "ㅋㅋAll options are saved in {file}" - -msgid "game:teach" -msgstr "ㅋㅋTeaching Game" - -msgid "Failed to load SGF" -msgstr "ㅋㅋFailed to load SGF. Parse Error: {error}" - -msgid "gametype" -msgstr "ㅋㅋGame Type" - -msgid "update ai settings" -msgstr "ㅋㅋUpdate AI Settings" - -msgid "aihelp:default" -msgstr "" -"ㅋㅋFull strength KataGo AI. Strength is affected by `max visits` and `model`" -" in the general settings `engine` section and engine configuration file. No " -"options are available here." - -msgid "Starting default Kata failed" -msgstr "" -"ㅋㅋStarting KataGo with command '{command}' failed with error {error}. If on " -"MacOS, see the manual on how to use brew to install katago first, and add it" -" to your path or 'engine/katago' setting." - -msgid "aihelp:p:pick" -msgstr "" -"ㅋㅋPicks `pick_n + pick_frac * ` at random and plays " -"the best one. For `pick_frac=1` plays like the `Policy` AI. Plays top move " -"if policy value is above `pick_override` to avoid obvious mistakes." - -msgid "show ai dots" -msgstr "" -"ㅋㅋShow dots/SGF comments\n" -" for AI players" - -msgid "menu:lang" -msgstr "ㅋㅋLanguage" - -msgid "Info:PV" -msgstr "ㅋㅋPV: {pv}" - -msgid "tab:points" -msgstr "ㅋㅋPoint Loss" - -msgid "analysis:extra" -msgstr "ㅋㅋDeeper analysis" - -msgid "SGF start message" -msgstr "" -"ㅋㅋMoves marked 'X' indicate the top move according to KataGo, those with a " -"square are moves that lose less than 0.5 points" - -msgid "general:sgf_load" -msgstr "ㅋㅋPath for loading SGF files" - -msgid "ai:jigo" -msgstr "ㅋㅋKataJigo" - -msgid "engine settings" -msgstr "ㅋㅋKataGo Engine Settings" - -msgid "komi" -msgstr "ㅋㅋKomi" - -msgid "general settings title" -msgstr "ㅋㅋGeneral and Engine Settings" - -msgid "byoyomi periods" -msgstr "ㅋㅋNumber of Periods" - -msgid "aihelp:p:weighted" -msgstr "" -"ㅋㅋPlays moves according to policy probability, with `weaken_fac` influencing" -" how much more likely weaker moves are played. A high negative value plays " -"like the `Policy` AI.`pick_override` determines when top move is chosen " -"without randomness, and `lower_bound` determines the lower bound policy " -"value that is allowed." - -msgid "engine:katago:hint" -msgstr "ㅋㅋLeave blank to use included executable" - -msgid "Analyzing move..." -msgstr "ㅋㅋAnalyzing move..." - -msgid "update timer" -msgstr "ㅋㅋUpdate Timer" - -msgid "engine:model" -msgstr "ㅋㅋPath to KataGo model file" - -msgid "dot color" -msgstr "ㅋㅋColour (fixed)" - -msgid "aihelp:jigo" -msgstr "" -"ㅋㅋWill try to win by a set amount of points (default 0.5), without further " -"restrictions." - -msgid "strength:dan" -msgstr "ㅋㅋd" - -msgid "stats:pointsgained" -msgstr "ㅋㅋPoints Gained" - -msgid "handicap" -msgstr "ㅋㅋHandicap" - -msgid "aihelp:p:tenuki" -msgstr "" -"ㅋㅋPicks `pick_n + pick_frac * ` weighted away from " -"the last move and plays the best one. Plays top move if policy value is " -"above `pick_override` to avoid obvious mistakes. A higher `stddev` makes it " -"play further away." - -msgid "engine:max_time" -msgstr "ㅋㅋMaximum time for analysis" - -msgid "Info:policy best" -msgstr "ㅋㅋTop policy move was {move} ({probability:.1%})." - -msgid "game:normal" -msgstr "ㅋㅋNormal Game" - -msgid "aihelp:p:local" -msgstr "" -"ㅋㅋPicks `pick_n + pick_frac * ` weighted towards the " -"last move and plays the best one. Plays top move if policy value is above " -"`pick_override` to avoid obvious mistakes." - -msgid "tab:score" -msgstr "ㅋㅋScore" - -msgid "strength:kyu" -msgstr "ㅋㅋk" - -msgid "clear cache" -msgstr "ㅋㅋClear Cache" - -msgid "ai:scoreloss" -msgstr "ㅋㅋScore Loss" - -msgid "Starting Kata failed" -msgstr "" -"ㅋㅋStarting KataGo with command '{command}' failed with error {error}. Please" -" make sure the 'katago' value under 'engine' in settings points to the " -"correct KataGo executable." - -msgid "pass-button-text" -msgstr "ㅋㅋPass" - -msgid "avoids replaying" -msgstr "" -"ㅋㅋAvoids replaying\n" -"identical games" - -msgid "general:debug_level:hint" -msgstr "ㅋㅋSet to 1 when reporting errors" - -msgid "ai:p:influence" -msgstr "ㅋㅋInfluential Style" - -msgid "analysis:dots" -msgstr "" -"ㅋㅋShow\n" -"Dots" - -msgid "menu:manual" -msgstr "ㅋㅋManual" - -msgid "general:sgf_save" -msgstr "ㅋㅋPath for saving SGF files" - -msgid "Jigo" -msgstr "ㅋㅋJigo" - -msgid "update settings" -msgstr "ㅋㅋUpdate Settings" - -msgid "Info:AI thoughts" -msgstr "ㅋㅋAI thought process: {thoughts}" - -msgid "Info:policy rank" -msgstr "ㅋㅋMove was #{rank} according to policy ({probability:.2%})." - -msgid "aihelp:policy" -msgstr "" -"ㅋㅋPlays the top move from the policy network, without any reading. Strength " -"is mainly affected by `model` in engine settings. The opening moves setting " -"affects how many moves in the opening are more random." - -msgid "menu:teachsettings" -msgstr "ㅋㅋTeaching Game Settings" - -msgid "stats:score" -msgstr "ㅋㅋEstimated Score" - -msgid "menu:clocksettings" -msgstr "ㅋㅋTimer Settings" - -msgid "Info:score" -msgstr "ㅋㅋScore: {score}" - -msgid "closedlabel:scoregraph" -msgstr "ㅋㅋScore Graph" - -msgid "Info:winrate" -msgstr "ㅋㅋWin rate: {winrate}" - -msgid "SGF Notes Hint" -msgstr "ㅋㅋYour SGF notes for this position here." - -msgid "menu:settings" -msgstr "ㅋㅋGeneral & Engine Settings" - -msgid "tab:notes" -msgstr "ㅋㅋNotes" - -msgid "general:anim_pv_time" -msgstr "ㅋㅋTime between moves when animating a sequence" - -msgid "analysis:aimove" -msgstr "ㅋㅋForce AI Move" - -msgid "board-pass" -msgstr "ㅋㅋpass" - -msgid "player:human" -msgstr "ㅋㅋHuman" - -msgid "aistrategy" -msgstr "ㅋㅋAI Strategy" - -msgid "korean" -msgstr "ㅋㅋKorean" - -msgid "menu:playersetup" -msgstr "ㅋㅋPlayer Setup" - -msgid "New Game title" -msgstr "ㅋㅋSetup New Game" - -msgid "tab:winrate" -msgstr "ㅋㅋWin Rate" - -msgid "engine:time:hint" -msgstr "ㅋㅋTime in seconds" - -msgid "undo-button-text" -msgstr "ㅋㅋUndo" - -msgid "board size" -msgstr "ㅋㅋBoard size" - -msgid "Select AI" -msgstr "ㅋㅋSelect AI strategy to configure" - -msgid "general:debug_level" -msgstr "ㅋㅋDebug level in the console" - -msgid "Info:teaching undo" -msgstr "ㅋㅋMove was automatically undone in teaching mode." - -msgid "restarting engine" -msgstr "ㅋㅋRestarting Engine after Settings Change." - -msgid "analysis:nextmoves" -msgstr "" -"ㅋㅋNext\n" -"Moves" - -msgid "aihelp:p:rank" -msgstr "" -"ㅋㅋPicks moves at random from a limited selection of moves and plays the best" -" one. Stronger settings select the best move from a larger selection. Since " -"there is no 0 kyu/dan, 3 dan = -2 kyu." - -msgid "ai:p:rank" -msgstr "ㅋㅋCalibrated Rank Bot" - -msgid "tab:info-details" -msgstr "ㅋㅋ+Analysis"