scroll, double click

This commit is contained in:
Sander Land committed 2020-04-29 19:07:52 +02:00
1 parent e7b9f4be5b
commit 0de3335cd1
5 files changed
+34 -44

No files matched your search

+3 -22
View File
@@ -97,30 +97,11 @@ In addition to these, there are:
### Configuration
Configuration is stored in `config.json`. Most settings are available to edit in the program, but some are not.
Configuration is stored in `config.json`. Most settings are now available to edit in the program, but
some cosmetic options are now.
You can use `python katrain.py your_config_file.json` to use another config file instead.
#### The settings panel
The `trainer` block has the following options to tweak for engine assisted play and reviewing:
* `eval_off_show_last`: when the `eval` checkbox is off for a player, show coloured dots on the last this many moves regardless.
* `undo_eval_threshold`, `undo_point_threshold`: prompt player to undo if move is worse than this in terms of points AND evaluation.
The following options are relevant for the `balance score` AI play mode.
* `balance_play_target_score`: indicates how many points the AI aims to win by when using 'balance score'.
* `balance_play_randomize_eval`: when not needing to balance score, the AI will pick a random move which is at least this good as long as it stays ahead.
* `balance_play_min_eval`: when needing to balance score, the AI will pick a move which is at least this good.
* `balance_play_min_visits`: never pick a move with fewer playouts than this.
The cfg file has additional configuration for KataGo, which are documented there.
#### Configuring feedback
* `num_undo_prompts`: automatically undo bad moves when `undo` is on at most this many times. Can be a fraction like 0.5 for 50% chance of being granted an undo on a bad move.
If you ever need to reset to the original settings, simply re-download the `config.json` file in this repository.
## FAQ
+3 -2
View File
@@ -33,12 +33,13 @@ Low priority
[] more teaching / groups in danger? hard
[] When creating a new game, the 9 buttons on the right side aren't all that useful. Maybe the 9, 13 and 19 ones make sense since these three board sizes are the traditionally used ones, but why 2, 4 and 9 stones buttons? Why 0.5, 6.5 and -40pts komi buttons?
[] Score instead of game end
[] Plus, explanatory bubbles would help to clarify labels like "Debug" (are there bugs in the matrix? :p), "enable_ownership" (which didn't seem to prevent or allow visualizing territory ownership on the board, as that was already covered by the "owner" checkbox anyway... so I guess I missed something), etc.
-- possible right-click?
Wont do for now
[] dual engine support -- easily possible but has weird effects on win rate etc
[/] The UI would be directly understood if there were bubbles with a short explanation popping up when hovering above buttons and labels, e.g "Performing additional analysis to 1502 visits" which appears currently in the comments window after pushing the Extra button would also make a perfect explanatory bubble when hovering over said button too.
--- partially solved by config with help for some
bug/suggestion reports
-- Plus, explanatory bubbles would help to clarify labels like "Debug" (are there bugs in the matrix? :p), "enable_ownership" (which didn't seem to prevent or allow visualizing territory ownership on the board, as that was already covered by the "owner" checkbox anyway... so I guess I missed something), etc.
+10 -10
View File
@@ -43,8 +43,7 @@ class Game:
self.komi = self.config.get("init_komi", {}).get(str(board_size), 6.5)
self.root = GameNode(properties={**Game.DEFAULT_PROPERTIES, **{"SZ": board_size, "KM": self.komi, "DT": self.game_id}})
self.current_node = self.root
self._init_chains()
self.set_current_node(self.root)
threading.Thread(target=lambda: self.analyze_all_nodes(-1_000_000, analyze_fast=analyze_fast), daemon=True).start() # return faster, but bypass Kivy Clock
def analyze_all_nodes(self, priority=0, analyze_fast=False):
@@ -52,7 +51,7 @@ class Game:
node.analyze(self.engines[node.next_player], priority=priority, analyze_fast=analyze_fast)
# -- move tree functions --
def _init_chains(self):
def _calculate_groups(self):
board_size_x, board_size_y = self.board_size
self.board = [[-1 for _x in range(board_size_x)] for _y in range(board_size_y)] # type: List[List[int]] # board pos -> chain id
self.chains = [] # type: List[List[Move]] # chain id -> chain
@@ -121,7 +120,7 @@ class Game:
try:
self._validate_move_and_update_chains(move, ignore_ko)
except IllegalMoveException:
self._init_chains()
self._calculate_groups()
raise
played_node = self.current_node.play(move)
self.current_node = played_node
@@ -129,28 +128,29 @@ class Game:
played_node.analyze(self.engines[played_node.next_player])
return played_node
def set_current_node(self, node):
self.current_node = node
self._calculate_groups()
def undo(self, n_times=1):
cn = self.current_node # avoid race conditions
for _ in range(n_times):
if not cn.is_root:
cn = cn.parent
self.current_node = cn
self._init_chains()
self.set_current_node(cn)
def redo(self, n_times=1):
cn = self.current_node # avoid race conditions
for _ in range(n_times):
if cn.children:
cn = cn.children[-1]
self.current_node = cn
self._init_chains()
self.set_current_node(cn)
def switch_branch(self, direction):
cn = self.current_node # avoid race conditions
if cn.parent and len(cn.parent.children) > 1:
ix = cn.parent.children.index(cn)
self.current_node = cn.parent.children[(ix + direction) % len(cn.parent.children)]
self._init_chains()
self.set_current_node(cn.parent.children[(ix + direction) % len(cn.parent.children)])
def place_handicap_stones(self, n_handicaps):
board_size_x, board_size_y = self.board_size
+11 -10
View File
@@ -71,23 +71,25 @@ class BadukPanWidget(Widget):
self.draw_hover_contents()
def on_touch_up(self, touch):
if touch.button != "left":
return
if not self.gridpos_x:
if touch.button != "left" or not self.gridpos_x:
return
katrain = self.katrain
if self.ghost_stone:
if self.ghost_stone and touch.button == "left":
katrain("play", self.ghost_stone)
else:
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)
nodes_here = [node for node in katrain.game.current_node.nodes_from_root if node.single_move and node.single_move.coords == (xp, yp)]
if nodes_here and max(yd, xd) < self.grid_size / 2: # load old comment
katrain.log(f"\nAnalysis:\n{nodes_here[-1].analysis}", OUTPUT_DEBUG)
katrain.log(f"\nParent Analysis:\n{nodes_here[-1].parent.analysis}", OUTPUT_DEBUG)
katrain.controls.info.text = nodes_here[-1].comment(sgf=True)
if touch.is_double_tap: # navigate to move
katrain.game.set_current_node(nodes_here[-1])
self.draw_board_contents()
else: # load comments
katrain.log(f"\nAnalysis:\n{nodes_here[-1].analysis}", OUTPUT_DEBUG)
katrain.log(f"\nParent Analysis:\n{nodes_here[-1].parent.analysis}", OUTPUT_DEBUG)
katrain.controls.info.text = nodes_here[-1].comment(sgf=True)
katrain.controls.info.text = nodes_here[-1].comment(sgf=True)
self.ghost_stone = None
self.draw_hover_contents() # remove ghost
@@ -191,7 +193,6 @@ class BadukPanWidget(Widget):
realized_points_lost = None
for i, node in enumerate(nodes[::-1]): # reverse order!
points_lost = node.points_lost
print("node", node.single_move, "pl", points_lost, "rpl", realized_points_lost)
evalsize = 1
if points_lost and realized_points_lost:
if points_lost <= 0.5 and realized_points_lost <= 1.5:
+7
View File
@@ -228,6 +228,13 @@ class KaTrainGui(BoxLayout):
self.log(msg, OUTPUT_INFO)
self.controls.set_status(msg)
def on_touch_up(self, touch):
if touch.button == "scrollup":
self("redo")
elif touch.button == "scrolldown":
self("undo")
return super().on_touch_up(touch)
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
if isinstance(App.get_running_app().root_window.children[0], Popup):
return # if in new game or load, don't allow keyboard shortcuts