diff --git a/katrain/__main__.py b/katrain/__main__.py index 502859e..b8ecd36 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -207,7 +207,7 @@ class KaTrainGui(Screen, KaTrainBase): and not (teaching_undo and cn.auto_undo is None) ): # cn mismatch stops this if undo fired. avoid message loop here or fires repeatedly. self._do_ai_move(cn) - Clock.schedule_once(self.board_gui.play_stone_sound, 0) + Clock.schedule_once(self.board_gui.play_stone_sound, 0.25) if len(self.engine.queries) == 0 and self.idle_analysis: self("analyze-extra", "extra", continuous=True) Clock.schedule_once(lambda _dt: self.update_gui(cn, redraw_board=redraw_board), -1) # trigger? @@ -324,7 +324,7 @@ class KaTrainGui(Screen, KaTrainBase): self.controls.timer.paused = True if not self.timer_settings_popup: self.timer_settings_popup = I18NPopup( - title_key="timer settings", size=[dp(350), dp(400)], content=ConfigTimerPopup(self) + title_key="timer settings", size=[dp(600), dp(500)], content=ConfigTimerPopup(self) ).__self__ self.timer_settings_popup.content.popup = self.timer_settings_popup self.timer_settings_popup.open() diff --git a/katrain/config.json b/katrain/config.json index a8e5203..d3980d4 100644 --- a/katrain/config.json +++ b/katrain/config.json @@ -22,6 +22,8 @@ "timer": { "byo_length": 30, "byo_periods": 5, + "minimal_use": 0, + "main_time": 0, "sound": true }, "game": { diff --git a/katrain/core/engine.py b/katrain/core/engine.py index a975924..8fb0319 100644 --- a/katrain/core/engine.py +++ b/katrain/core/engine.py @@ -85,7 +85,7 @@ class KataGoEngine: def start(self): try: self.katrain.log(f"Starting KataGo with {self.command}", OUTPUT_DEBUG) - startupinfo = None # stop command box popups on windows/pyinstaller + startupinfo = None # stop command box popups on windows/pyinstaller if hasattr(subprocess, "STARTUPINFO"): startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW diff --git a/katrain/core/game.py b/katrain/core/game.py index ee4077d..3a3261f 100644 --- a/katrain/core/game.py +++ b/katrain/core/game.py @@ -79,6 +79,7 @@ class Game: self.root.set_property("RU", katrain.config("game/rules")) self.set_current_node(self.root) + self.main_time_used = 0 threading.Thread( target=lambda: self.analyze_all_nodes(-1_000_000, analyze_fast=analyze_fast), daemon=True ).start() # return faster, but bypass Kivy Clock diff --git a/katrain/gui.kv b/katrain/gui.kv index 07219f9..7d8825e 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -357,14 +357,14 @@ spacing: CP_SPACING padding: CP_PADDING * 4, CP_PADDING * 2 paused: True - timeout: self.state[1] <= 0 + timeout: root.state[1] is not None and root.state[1] <= 0 MDBoxLayout: size_hint: 0.7,1 MDFloatLayout: size_hint: 0.4,1 TimerLabel: color: BACKGROUND_COLOR - text: '8:88' + text: '{}:88'.format('188' if root.state[0] >= 6000 else ('88' if root.state[0] >= 600 else '8')) font_size: 0.85*self.height pos_hint: {'right':1,'center_y':0.5} halign: 'right' @@ -379,20 +379,20 @@ valign: 'middle' TimerLabel: size_hint: 0.05,1 - text: "x" + text: "x" if root.state[1] is not None else "" font_size: self.height * 0.3 text_size: self.width, self.height * 0.95 halign: 'right' valign: 'top' timeout: root.timeout TimerLabel: - size_hint: 0.1,1 + size_hint: 0.075,1 font_size: self.height * 0.35 text_size: self.size halign: 'left' valign: 'top' id: periods - text: str(root.state[1]) + text: str(root.state[1]) if root.state[1] is not None else "" max_lines: 1 timeout: root.timeout MDBoxLayout: diff --git a/katrain/gui/badukpan.py b/katrain/gui/badukpan.py index 611e706..18ba0e0 100644 --- a/katrain/gui/badukpan.py +++ b/katrain/gui/badukpan.py @@ -106,8 +106,21 @@ class BadukPanWidget(Widget): return katrain = self.katrain if self.ghost_stone and ("button" not in touch.profile or touch.button == "left"): - katrain("play", self.ghost_stone) - self.play_stone_sound() + current_node = self.katrain and self.katrain.game and self.katrain.game.current_node + if ( + current_node + and not current_node.children + and not self.katrain.next_player_info.ai + and not self.katrain.controls.timer.paused + and self.katrain.play_analyze_mode == MODE_PLAY + and current_node.time_used < self.katrain.config("timer/minimal_use", 0) + ): + self.katrain.controls.set_status( + i18n._("move too fast").format(num=self.katrain.config("timer/minimal_use", 0)), STATUS_TEACHING + ) + else: + katrain("play", self.ghost_stone) + self.play_stone_sound() elif not self.ghost_stone: xd, xp = self._find_closest(touch.x, self.gridpos_x) yd, yp = self._find_closest(touch.y, self.gridpos_y) diff --git a/katrain/gui/controlspanel.py b/katrain/gui/controlspanel.py index 245c0bd..fb5f351 100644 --- a/katrain/gui/controlspanel.py +++ b/katrain/gui/controlspanel.py @@ -71,6 +71,8 @@ class ControlsPanel(BoxLayout): self.active_comment_node = None self.last_timer_update = (None, 0, False) self.beep = SoundLoader.load("sounds/countdownbeep.wav") + self.boing = SoundLoader.load("sounds/boing.wav") + self.boing.volume = 0.1 self.beep_start = 5.2 self.timer_interval = 0.07 @@ -149,11 +151,13 @@ class ControlsPanel(BoxLayout): self.info.text = info def update_timer(self, _dt): - current_node = self.katrain and self.katrain.game and self.katrain.game.current_node + game = self.katrain and self.katrain.game + current_node = game and self.katrain.game.current_node if current_node: last_update_node, last_update_time, beeping = self.last_timer_update new_beeping = beeping now = time.time() + main_time = self.katrain.config("timer/main_time",0) * 60 byo_len = max(1, self.katrain.config("timer/byo_length")) byo_num = max(1, self.katrain.config("timer/byo_periods")) sounds_on = self.katrain.config("timer/sound") @@ -161,9 +165,16 @@ class ControlsPanel(BoxLayout): ai = player.ai used_period = False + min_use = self.katrain.config("timer/minimal_use", 0) + boing_at_remaining = byo_len - min_use + main_time_remaining = main_time - game.main_time_used + if not self.timer.paused and not ai and self.katrain.play_analyze_mode == MODE_PLAY: if last_update_node == current_node and not current_node.children: - current_node.time_used += now - last_update_time + if main_time_remaining > 0: + game.main_time_used += now - last_update_time + else: + current_node.time_used += now - last_update_time else: current_node.time_used = 0 new_beeping = False @@ -173,6 +184,7 @@ class ControlsPanel(BoxLayout): time_remaining += byo_len player.periods_used += 1 used_period = True + if ( self.beep_start - 2 * self.timer_interval < time_remaining < self.beep_start and player.periods_used < byo_num @@ -180,6 +192,18 @@ class ControlsPanel(BoxLayout): new_beeping = True elif time_remaining > self.beep_start: new_beeping = False + + if ( + min_use + and not new_beeping + and self.boing + and boing_at_remaining - self.timer_interval + < time_remaining + < boing_at_remaining + self.timer_interval + and player.periods_used < byo_num + ): + self.boing.play() + else: new_beeping = False @@ -198,4 +222,7 @@ class ControlsPanel(BoxLayout): self.last_timer_update = (current_node, now, new_beeping) - self.timer.state = (max(0, time_remaining), max(0, periods_rem), ai) + if main_time_remaining > 0: + self.timer.state = (main_time_remaining, None, ai) + else: + self.timer.state = (max(0, time_remaining), max(0, periods_rem), ai) diff --git a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo index 7254b38..36b6916 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 2622d3a..91de790 100644 --- a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po @@ -640,3 +640,15 @@ msgstr "寻找其他走法" #. status message msgid "alternative analysis" msgstr "正在搜索其他走法" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo index 5c942fc..34b36de 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 722e7ce..93dc91b 100644 --- a/katrain/i18n/locales/de/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/de/LC_MESSAGES/katrain.po @@ -689,3 +689,15 @@ msgstr "Finde alternative Züge" #. - status message msgid "alternative analysis" msgstr "Suche nach alternativen Zügen" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least %d seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo index 9c7f8dc..8ad3bbd 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 c5b79e3..92f8f8f 100644 --- a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po @@ -293,14 +293,25 @@ msgid "timer settings" msgstr "Adjust Timer Settings" msgid "byoyomi length" -msgstr "Time per Byo-yomi Period" +msgstr "Time per byo-yomi period (s)" msgid "byoyomi periods" -msgstr "Number of Periods" +msgstr "Number of periods" msgid "count down sound" msgstr "Sound on" +#. in minutes +msgid "main time" +msgstr "Main time (min.)" + +#. ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + #. submit button msgid "update timer" msgstr "Update Timer" diff --git a/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/es/LC_MESSAGES/katrain.mo index 75031f1..eebeda8 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 1124967..d7f32a2 100644 --- a/katrain/i18n/locales/es/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/es/LC_MESSAGES/katrain.po @@ -697,3 +697,15 @@ msgstr "Find alternative moves" #. TODO - status message msgid "alternative analysis" msgstr "Searching for alternative moves" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.mo index 83b7aa1..09a9c96 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 bb070f0..28f1c6c 100644 --- a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po @@ -721,3 +721,15 @@ msgstr "Proposer des coups différents" msgid "alternative analysis" msgstr "Recherche de coups différents." + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo index 9c28dd2..206ae2d 100644 Binary files a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po index 705244c..b4b9b4f 100644 --- a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po @@ -679,3 +679,15 @@ msgstr "" #. status message msgid "alternative analysis" msgstr "他の候補手を分析中" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo index c14eca3..6739fb1 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 eaf984b..0e89d0b 100644 --- a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po @@ -654,3 +654,15 @@ msgstr "다른 수 찾기" msgid "alternative analysis" msgstr "다른 수를 찾는 중입니다" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Ignore moves faster than seconds" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo index 5459d12..b62d3c0 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 bfed209..cc87c03 100644 --- a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po @@ -684,3 +684,15 @@ msgstr "Поискать альтернативные ходы" msgid "alternative analysis" msgstr "Поиск альтернативных ходов" + +#. TODO - ignore moves if timer is on and less than this is used +msgid "minimal time use" +msgstr "Minimal time use in byo-yomi (s)" + +#. TODO +msgid "move too fast" +msgstr "Think for at least {num} seconds before playing." + +#. TODO - in minutes +msgid "main time" +msgstr "Main time (min.)" diff --git a/katrain/popups.kv b/katrain/popups.kv index c9c5265..83c44b4 100644 --- a/katrain/popups.kv +++ b/katrain/popups.kv @@ -319,9 +319,15 @@ : MDGridLayout: cols: 2 - rows: 3 + rows: 5 spacing: 1.5 * CP_SPACING size_hint: 1,2.5 + DescriptionLabel: + text: i18n._('main time') + AnchorLayout: + LabelledIntInput: + text: "10" + input_property: "timer/main_time" DescriptionLabel: text: i18n._('byoyomi length') AnchorLayout: @@ -334,6 +340,12 @@ LabelledIntInput: text: "5" input_property: "timer/byo_periods" + DescriptionLabel: + text: i18n._('minimal time use') + AnchorLayout: + LabelledIntInput: + text: "0" + input_property: "timer/minimal_use" DescriptionLabel: text: i18n._('count down sound') AnchorLayout: diff --git a/katrain/sounds/boing.wav b/katrain/sounds/boing.wav new file mode 100644 index 0000000..2cee3df Binary files /dev/null and b/katrain/sounds/boing.wav differ