From be5a588d68eae8fa03178978219b2f363addf437 Mon Sep 17 00:00:00 2001 From: Sander Land Date: Tue, 1 Sep 2020 10:15:50 +0200 Subject: [PATCH] komi in info --- katrain/__main__.py | 8 ++++--- katrain/core/game.py | 18 +++++++++++---- katrain/core/game_node.py | 8 +++++++ katrain/gui.kv | 23 ++++++------------- katrain/gui/badukpan.py | 6 ++--- katrain/gui/controlspanel.py | 2 +- .../i18n/locales/en/LC_MESSAGES/katrain.po | 4 ++++ 7 files changed, 41 insertions(+), 28 deletions(-) diff --git a/katrain/__main__.py b/katrain/__main__.py index 3b864a8..40bb3e3 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -159,7 +159,6 @@ class KaTrainGui(Screen, KaTrainBase): self.board_controls.mid_circles_container.add_widget(top) self.board_controls.branch.disabled = not cn.parent or len(cn.parent.children) <= 1 self.controls.players["W"].captures = prisoners["W"] - self.controls.players["W"].komi = self.game.komi self.controls.players["B"].captures = prisoners["B"] # update engine status dot @@ -197,14 +196,14 @@ class KaTrainGui(Screen, KaTrainBase): and cn.analysis_ready and cn.parent.analysis_ready and not cn.children - and not self.game.ended + and not self.game.end_result ): self.game.analyze_undo(cn) # not via message loop if ( cn.analysis_ready and next_player.ai and not cn.children - and not self.game.ended + and not self.game.end_result 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) @@ -287,6 +286,9 @@ class KaTrainGui(Screen, KaTrainBase): self.board_gui.animating_pv = None self.game.undo(n_times) + def _do_resign(self): + self.game.current_node.end_state = f"{self.game.current_node.player}+R" + def _do_redo(self, n_times=1): self.board_gui.animating_pv = None self.game.redo(n_times) diff --git a/katrain/core/game.py b/katrain/core/game.py index daef7e8..359842e 100644 --- a/katrain/core/game.py +++ b/katrain/core/game.py @@ -207,8 +207,11 @@ class Game: return sum(self.chains, []) @property - def ended(self): - return self.current_node.parent and self.current_node.is_pass and self.current_node.parent.is_pass + def end_result(self): + if self.current_node.end_state: + return self.current_node.end_state + if self.current_node.parent and self.current_node.is_pass and self.current_node.parent.is_pass: + return self.manual_score or i18n._("board-game-end") @property def prisoner_count( @@ -283,13 +286,17 @@ class Game: def player_name(player_info): return f"{i18n._(player_info.player_type)} ({i18n._(player_info.player_subtype)})" + root_properties = self.root.properties + x_properties = {} if "KaTrain" in self.root.get_property("AP", ""): for bw in "BW": - self.root.set_property("P" + bw, player_name(self.katrain.players_info[bw])) + x_properties["P" + bw] = player_name(self.katrain.players_info[bw]) player_info = self.katrain.players_info[bw] if player_info.player_type == PLAYER_AI: - self.root.set_property(bw + "R", rank_label(player_info.calculated_rank)) - + x_properties[bw + "R"] = rank_label(player_info.calculated_rank) + if "+" in str(self.end_result): + x_properties["RE"] = self.end_result + self.root.properties = {**root_properties, **{k: [v] for k, v in x_properties.items()}} player_names = {bw: re.sub(r"['<>:\"/\\|?*]", "", self.root.get_property("P" + bw, bw)) for bw in "BW"} game_name = f"katrain_{player_names['B']} vs {player_names['W']} {self.game_id}" file_name = os.path.abspath(os.path.join(path, f"{game_name}.sgf")) @@ -303,6 +310,7 @@ class Game: ) with open(file_name, "w", encoding="utf-8") as f: f.write(sgf) + self.root.properties = root_properties return i18n._("sgf written").format(file_name=file_name) def analyze_extra(self, mode, **kwargs): diff --git a/katrain/core/game_node.py b/katrain/core/game_node.py index 6321f72..c4afc3b 100644 --- a/katrain/core/game_node.py +++ b/katrain/core/game_node.py @@ -23,6 +23,7 @@ class GameNode(SGFNode): self.time_used = 0 self.analysis_visits_requested = 0 self.undo_threshold = random.random() # for fractional undos + self.end_state = None def sgf_properties(self, save_comments_player=None, save_comments_class=None, eval_thresholds=None): properties = copy.copy(super().sgf_properties()) @@ -151,6 +152,8 @@ class GameNode(SGFNode): def comment(self, sgf=False, teach=False, details=False, interactive=True): single_move = self.move if not self.parent or not single_move: # root + if self.root: + return f"{i18n._('komi')}: {self.komi:.1f}\n{i18n._('ruleset')}: {i18n._(self.get_property('RU','Japanese').lower())}\n" return "" text = i18n._("move").format(number=self.depth) + f": {single_move.player} {single_move.gtp()}\n" @@ -193,8 +196,10 @@ class GameNode(SGFNode): text += "\n" + i18n._("Info:AI thoughts").format(thoughts=self.ai_thoughts) else: text = i18n._("No analysis available") if sgf else i18n._("Analyzing move...") + if "C" in self.properties: text += "\n[u]SGF Comments:[/u]\n" + "\n".join(self.properties["C"]) + return text @property @@ -258,3 +263,6 @@ class GameNode(SGFNode): moves = [(policy_grid[y][x], Move((x, y), player=self.next_player)) for x in range(szx) for y in range(szy)] moves.append((self.policy[-1], Move(None, player=self.next_player))) return sorted(moves, key=lambda mp: -mp[0]) + + + diff --git a/katrain/gui.kv b/katrain/gui.kv index 40ade7f..343bb09 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -277,25 +277,16 @@ : captures: 0 player: 'B' - komi: 0 player_type: 'player:human' player_subtype: 'game:normal' background_color: BOX_BACKGROUND_COLOR if self.active else BACKGROUND_COLOR outline_color: BOX_BACKGROUND_COLOR outline_width: 2 padding: [2*CP_PADDING,CP_PADDING,CP_PADDING,CP_PADDING] - BoxLayout: + CircleWithText: size_hint: 0.32, 1 - orientation: 'vertical' - CircleWithText: - player: root.player - text: str(root.captures) - Label: - size_hint: 1,0.25 - halign: 'center' - valign: 'middle' - font_size: self.height - text: "%s: %.1f" % (i18n._('komi'), root.komi) if root.player=='W' else '' + player: root.player + text: str(root.captures) BoxLayout: size_hint: 0.75, 1 pos_hint: {'x':0,'y':0} @@ -560,14 +551,14 @@ padding: 2*CP_PADDING,CP_PADDING spacing: CP_SPACING size_hint_x: 0.35 - SizedRoundedRectangleButton: - text: i18n._('pass-button-text') - size_hint: 1, 0.5 - on_left_release: root.katrain("play",None) SizedRoundedRectangleButton: text: i18n._('undo-button-text') size_hint: 1, 0.5 on_left_release: root.katrain("undo","smart") + SizedRoundedRectangleButton: + text: i18n._('resign') + size_hint: 1, 0.5 + on_left_release: root.katrain("resign") MoveTree: id: move_tree size_hint_x: EPSILON if self.parent.mode == MODE_PLAY else 1 diff --git a/katrain/gui/badukpan.py b/katrain/gui/badukpan.py index 01ddf54..5699a19 100644 --- a/katrain/gui/badukpan.py +++ b/katrain/gui/badukpan.py @@ -254,7 +254,7 @@ class BadukPanWidget(Widget): self.canvas.clear() # stones current_node = katrain.game.current_node - game_ended = katrain.game.ended + game_ended = katrain.game.end_result full_eval_on = katrain.analysis_controls.eval.active has_stone = {} drawn_stone = {} @@ -379,7 +379,7 @@ class BadukPanWidget(Widget): passed = len(nodes) > 1 and current_node.is_pass if passed: if game_ended: - text = katrain.game.manual_score or i18n._("board-game-end") + text = game_ended katrain.controls.timer.paused = True else: text = i18n._("board-pass") @@ -397,7 +397,7 @@ class BadukPanWidget(Widget): def draw_hover_contents(self, *_args): ghost_alpha = GHOST_ALPHA katrain = self.katrain - game_ended = katrain.game.ended + game_ended = katrain.game.end_result current_node = katrain.game.current_node player, next_player = current_node.player, current_node.next_player diff --git a/katrain/gui/controlspanel.py b/katrain/gui/controlspanel.py index 37f1cf5..9044bcc 100644 --- a/katrain/gui/controlspanel.py +++ b/katrain/gui/controlspanel.py @@ -127,7 +127,7 @@ class ControlsPanel(BoxLayout): lock_ai = katrain.config("trainer/lock_ai") and katrain.play_analyze_mode == MODE_PLAY details = self.info.detailed and not lock_ai info = "" - if current_node.move and not current_node.is_root: + if current_node.move or current_node.is_root: info = self.active_comment_node.comment( teach=katrain.players_info[self.active_comment_node.player].being_taught, details=details ) diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po index 2e84d25..31ea61c 100644 --- a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po @@ -129,6 +129,10 @@ msgstr "Re-analyzing entire game using {visits} visits" msgid "pass-button-text" msgstr "Pass" +#. resign the game +msgid "resign" +msgstr "Resign" + msgid "teaching undo message" msgstr "" "Undid move {move} as it lost {points_lost:.1f} points. Hover over the move "