tsumego solver 5000 is go

This commit is contained in:
Sander Land committed 2020-12-03 22:09:46 +01:00
1 parent da42fc4e0f
commit 0ade2524ce
27 files changed
+252 -83

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@ For on related licenses for these binaries and libraries see https://github.com/
2. Icons from www.flaticon.com, used with permission with the following attributions: 2. Icons from www.flaticon.com, used with permission with the following attributions:
- Equalize icon and Thrash Icon: derived from work by bqlqn from www.flaticon.com - Equalize icon and Thrash Icon: derived from work by bqlqn from www.flaticon.com
- Local search icon: derived from work by Pixel Perfect from www.flaticon.com - Local search icon, Insert icon: derived from work by Pixel Perfect from www.flaticon.com
- Other Menu icons and Flag icons: derived from work by Freepik from www.flaticon.com - Other Menu icons and Flag icons: derived from work by Freepik from www.flaticon.com
3. The True Type Font DIGITAL-7 version 1.02 by Sizenko Alexander, which is free for non-commercial use. 3. The True Type Font DIGITAL-7 version 1.02 by Sizenko Alexander, which is free for non-commercial use.
+3 -2
View File
@@ -101,12 +101,13 @@ for lang in locales:
print("Fixed", pofile[lang], "and converted ->", mofile) print("Fixed", pofile[lang], "and converted ->", mofile)
for file in glob.glob("katrain/**/*.py") + glob.glob("katrain/**/*.kv"): for file in glob.glob("**/*.py") + glob.glob("**/*.kv"):
with open(file, "r") as f: with open(file, "r") as f:
for i, line in enumerate(f.readlines()): for i, line in enumerate(f.readlines()):
matches = [m.strip() for m in re.findall(r"i18n._\((.*?)\)", line)] matches = [m.strip() for m in re.findall(r"i18n._\((.*?)\)", line)]
for msgid in matches: for msgid in matches:
if msgid[0] in ['"', "'"] and msgid.strip("\"'") not in strings_to_langs: # not code stripped_msgid = msgid.strip("\"'")
if stripped_msgid and msgid[0] in ['"', "'"] and stripped_msgid not in strings_to_langs: # not code
print(f"Missing {msgid} used in code at \t{file}:{i} \t'{line.strip()}'") print(f"Missing {msgid} used in code at \t{file}:{i} \t'{line.strip()}'")
errors += 1 errors += 1
+5 -1
View File
@@ -324,6 +324,10 @@ class KaTrainGui(Screen, KaTrainBase):
def _do_analyze_extra(self, mode, **kwargs): def _do_analyze_extra(self, mode, **kwargs):
self.game.analyze_extra(mode, **kwargs) self.game.analyze_extra(mode, **kwargs)
def _do_select_box(self):
self.controls.set_status(i18n._("analysis:region:start"), STATUS_INFO)
self.board_gui.selecting_region_of_interest = True
def _do_new_game_popup(self): def _do_new_game_popup(self):
self.controls.timer.paused = True self.controls.timer.paused = True
if not self.new_game_popup: if not self.new_game_popup:
@@ -489,7 +493,7 @@ class KaTrainGui(Screen, KaTrainBase):
"s": ("analyze-extra", "equalize"), "s": ("analyze-extra", "equalize"),
"d": ("analyze-extra", "sweep"), "d": ("analyze-extra", "sweep"),
"f": ("analyze-extra", "alternative"), "f": ("analyze-extra", "alternative"),
"g": ("analyze-extra", "local"), "g": ("select-box",),
"i": ("insert-mode",), "i": ("insert-mode",),
"p": ("play", None), "p": ("play", None),
"n": ("next-mistake",), "n": ("next-mistake",),
+9 -10
View File
@@ -6,7 +6,7 @@ import subprocess
import threading import threading
import time import time
import traceback import traceback
from typing import Callable, Dict, Optional from typing import Callable, Dict, Optional, List
from kivy.utils import platform from kivy.utils import platform
@@ -112,6 +112,7 @@ class KataGoEngine:
self.terminate_query(query_id) self.terminate_query(query_id)
self.queries = {} self.queries = {}
def restart(self): def restart(self):
self.queries = {} self.queries = {}
self.shutdown(finish=False) self.shutdown(finish=False)
@@ -249,7 +250,7 @@ class KataGoEngine:
analyze_fast: bool = False, analyze_fast: bool = False,
time_limit=True, time_limit=True,
find_alternatives: bool = False, find_alternatives: bool = False,
find_local: bool = False, region_of_interest: Optional[List] = None,
priority: int = 0, priority: int = 0,
ownership: Optional[bool] = None, ownership: Optional[bool] = None,
next_move: Optional[GameNode] = None, next_move: Optional[GameNode] = None,
@@ -278,22 +279,20 @@ class KataGoEngine:
"untilDepth": 1, "untilDepth": 1,
} }
] ]
elif find_local: elif region_of_interest:
distance = 5 xmin, xmax, ymin, ymax = region_of_interest
last_move = analysis_node.move
if last_move is None or last_move.is_pass:
return
avoid = [ avoid = [
{ {
"moves": [ "moves": [
Move((x, y)).gtp() Move((x, y)).gtp()
for x in range(0, size_x) for x in range(0, size_x)
for y in range(0, size_y) for y in range(0, size_y)
if max(abs(x - last_move.coords[0]), abs(y - last_move.coords[1])) > distance if x < xmin or x > xmax or y < ymin or y > ymax
], ],
"player": analysis_node.next_player, "player": player,
"untilDepth": 1, "untilDepth": 10000,
} }
for player in "BW"
] ]
else: else:
avoid = [] avoid = []
+19 -6
View File
@@ -62,6 +62,8 @@ class Game:
self.insert_mode = False self.insert_mode = False
self.insert_after = None self.insert_after = None
self.region_of_interest = None
if move_tree: if move_tree:
self.root = move_tree self.root = move_tree
self.komi = self.root.komi self.komi = self.root.komi
@@ -233,7 +235,11 @@ class Game:
played_node = self.current_node.play(move) played_node = self.current_node.play(move)
self.current_node = played_node self.current_node = played_node
if analyze: if analyze:
played_node.analyze(self.engines[played_node.next_player]) if self.region_of_interest:
played_node.analyze(self.engines[played_node.next_player],analyze_fast=True)
played_node.analyze(self.engines[played_node.next_player],region_of_interest=self.region_of_interest)
else:
played_node.analyze(self.engines[played_node.next_player])
return played_node return played_node
def set_current_node(self, node): def set_current_node(self, node):
@@ -410,6 +416,17 @@ class Game:
f.write(sgf) f.write(sgf)
return i18n._("sgf written").format(file_name=filename) return i18n._("sgf written").format(file_name=filename)
def set_region_of_interest(self,region_of_interest):
x1, x2, y1, y2 =region_of_interest
xmin, xmax = min(x1, x2), max(x1, x2)
ymin, ymax = min(y1, y2), max(y1, y2)
if not (xmin==xmax and ymin==ymax):
self.region_of_interest = [xmin,xmax,ymin,ymax]
else:
self.region_of_interest = None
self.katrain.controls.set_status("",OUTPUT_INFO)
def analyze_extra(self, mode, **kwargs): def analyze_extra(self, mode, **kwargs):
stones = {s.coords for s in self.stones} stones = {s.coords for s in self.stones}
cn = self.current_node cn = self.current_node
@@ -426,7 +443,7 @@ class Game:
visits = cn.analysis_visits_requested + engine.config["max_visits"] visits = cn.analysis_visits_requested + engine.config["max_visits"]
self.katrain.controls.set_status(i18n._("extra analysis").format(visits=visits), STATUS_ANALYSIS) self.katrain.controls.set_status(i18n._("extra analysis").format(visits=visits), STATUS_ANALYSIS)
self.katrain.controls.set_status(i18n._("extra analysis").format(visits=visits), STATUS_ANALYSIS) self.katrain.controls.set_status(i18n._("extra analysis").format(visits=visits), STATUS_ANALYSIS)
cn.analyze(engine, visits=visits, priority=-1_000, time_limit=False) cn.analyze(engine, visits=visits, priority=-1_000, region_of_interest=self.region_of_interest, time_limit=False)
return return
if mode == "game": if mode == "game":
nodes = self.root.nodes_in_tree nodes = self.root.nodes_in_tree
@@ -467,10 +484,6 @@ class Game:
visits = engine.config["fast_visits"] visits = engine.config["fast_visits"]
self.katrain.controls.set_status(i18n._("sweep analysis").format(visits=visits), STATUS_ANALYSIS) self.katrain.controls.set_status(i18n._("sweep analysis").format(visits=visits), STATUS_ANALYSIS)
priority = -1_000_000_000 priority = -1_000_000_000
elif mode == "local": # also do a quick update on current candidates so it doesn't look too weird
self.katrain.controls.set_status(i18n._("local analysis"), STATUS_ANALYSIS)
cn.analyze(engine, priority=-500, time_limit=False, find_local="local")
return
elif mode in ["equalize", "alternative", "local"]: elif mode in ["equalize", "alternative", "local"]:
if not cn.analysis_complete and mode != "local": if not cn.analysis_complete and mode != "local":
self.katrain.controls.set_status(i18n._("wait-before-equalize"), STATUS_INFO, self.current_node) self.katrain.controls.set_status(i18n._("wait-before-equalize"), STATUS_INFO, self.current_node)
+4 -3
View File
@@ -145,13 +145,14 @@ class GameNode(SGFNode):
refine_move=None, refine_move=None,
analyze_fast=False, analyze_fast=False,
find_alternatives=False, find_alternatives=False,
find_local=False, region_of_interest = None,
report_every=0.25, report_every=0.25,
): ):
additional_moves = bool(find_alternatives or region_of_interest)
engine.request_analysis( engine.request_analysis(
self, self,
callback=lambda result, partial_result: self.set_analysis( callback=lambda result, partial_result: self.set_analysis(
result, refine_move, find_alternatives or find_local, partial_result result, refine_move, additional_moves, partial_result
), ),
priority=priority, priority=priority,
visits=visits, visits=visits,
@@ -159,7 +160,7 @@ class GameNode(SGFNode):
time_limit=time_limit, time_limit=time_limit,
next_move=refine_move, next_move=refine_move,
find_alternatives=find_alternatives, find_alternatives=find_alternatives,
find_local=find_local, region_of_interest=region_of_interest,
report_every=report_every, report_every=report_every,
) )
+3 -3
View File
@@ -751,13 +751,13 @@
shortcut: 'f' shortcut: 'f'
on_action: root.katrain("analyze-extra", "alternative") on_action: root.katrain("analyze-extra", "alternative")
AnalysisMenuItem: AnalysisMenuItem:
text: i18n._("analysis:local") text: i18n._("analysis:region")
icon: 'img/local.png' icon: 'img/local.png'
shortcut: 'g' shortcut: 'g'
on_action: root.katrain("analyze-extra", "local") on_action: root.katrain("select-box",)
AnalysisMenuItem: AnalysisMenuItem:
text: i18n._("analysis:insert") text: i18n._("analysis:insert")
icon: 'img/local.png' icon: 'img/insert.png'
shortcut: 'i' shortcut: 'i'
on_action: root.katrain("insert-mode") on_action: root.katrain("insert-mode")
AnalysisMenuItem: AnalysisMenuItem:
+70 -19
View File
@@ -48,6 +48,9 @@ class BadukPanWidget(Widget):
self.gridpos_y = [] self.gridpos_y = []
self.grid_size = 0 self.grid_size = 0
self.stone_size = 0 self.stone_size = 0
self.selecting_region_of_interest = False
self.region_of_interest = []
self.active_pv_moves = [] self.active_pv_moves = []
self.animating_pv = None self.animating_pv = None
self.last_mouse_pos = (0, 0) self.last_mouse_pos = (0, 0)
@@ -57,6 +60,12 @@ class BadukPanWidget(Widget):
self.bind(size=self.redraw_trigger, pos=self.redraw_trigger) self.bind(size=self.redraw_trigger, pos=self.redraw_trigger)
Clock.schedule_interval(self.animate_pv, 0.1) Clock.schedule_interval(self.animate_pv, 0.1)
def play_stone_sound(self, *_args):
if self.katrain.config("timer/sound"):
sound = random.choice(self.stones_sounds)
if sound:
sound.play()
# stone placement functions # stone placement functions
def _find_closest(self, pos, gridpos): def _find_closest(self, pos, gridpos):
return sorted([(abs(p - pos), i) for i, p in enumerate(gridpos)])[0] return sorted([(abs(p - pos), i) for i, p in enumerate(gridpos)])[0]
@@ -74,23 +83,42 @@ class BadukPanWidget(Widget):
if prev_ghost != self.ghost_stone: if prev_ghost != self.ghost_stone:
self.draw_hover_contents() self.draw_hover_contents()
def update_box_selection(self, touch, second_point=True):
if not self.gridpos_x:
return
_, xp = self._find_closest(touch.x, self.gridpos_x)
_, yp = self._find_closest(touch.y, self.gridpos_y)
if second_point and len(self.region_of_interest) == 4:
self.region_of_interest[1] = xp
self.region_of_interest[3] = yp
else:
self.region_of_interest = [xp, xp, yp, yp]
self.draw_hover_contents()
def on_touch_down(self, touch): def on_touch_down(self, touch):
self.set_animating_pv(None, None) # any click kills PV from label/move self.set_animating_pv(None, None) # any click kills PV from label/move
if "button" in touch.profile and touch.button != "left": if "button" in touch.profile and touch.button != "left":
return return
self.check_next_move_ghost(touch) if self.selecting_region_of_interest:
self.update_box_selection(touch, second_point=False)
else:
self.check_next_move_ghost(touch)
def on_touch_move(self, touch): def on_touch_move(self, touch):
if "button" in touch.profile and touch.button != "left": if "button" in touch.profile and touch.button != "left":
return return
return self.check_next_move_ghost(touch) if self.selecting_region_of_interest:
return self.update_box_selection(touch)
else:
return self.check_next_move_ghost(touch)
def on_mouse_pos(self, *args): # https://gist.github.com/opqopq/15c707dc4cffc2b6455f def on_mouse_pos(self, *args): # https://gist.github.com/opqopq/15c707dc4cffc2b6455f
if self.get_root_window(): # don't proceed if I'm not displayed <=> If have no parent if self.get_root_window(): # don't proceed if I'm not displayed <=> If have no parent
pos = args[1] pos = args[1]
rel_pos = self.to_widget(*pos) # compensate for relative layout rel_pos = self.to_widget(*pos) # compensate for relative layout
inside = self.collide_point(*rel_pos) inside = self.collide_point(*rel_pos)
if inside and self.active_pv_moves:
if inside and self.active_pv_moves and not self.selecting_region_of_interest:
near_move = [ near_move = [
(pv, node) (pv, node)
for move, pv, node in self.active_pv_moves for move, pv, node in self.active_pv_moves
@@ -109,17 +137,17 @@ class BadukPanWidget(Widget):
self.set_animating_pv(None, None) # any click kills PV from label/move self.set_animating_pv(None, None) # any click kills PV from label/move
self.last_mouse_pos = pos self.last_mouse_pos = pos
def play_stone_sound(self, *_args):
if self.katrain.config("timer/sound"):
sound = random.choice(self.stones_sounds)
if sound:
sound.play()
def on_touch_up(self, touch): def on_touch_up(self, touch):
if ("button" in touch.profile and touch.button != "left") or not self.gridpos_x: if ("button" in touch.profile and touch.button != "left") or not self.gridpos_x:
return return
katrain = self.katrain katrain = self.katrain
if self.ghost_stone and ("button" not in touch.profile or touch.button == "left"): if self.selecting_region_of_interest:
if len(self.region_of_interest) == 4:
self.katrain.game.set_region_of_interest(self.region_of_interest)
self.region_of_interest = []
self.selecting_region_of_interest = False
elif self.ghost_stone and ("button" not in touch.profile or touch.button == "left"):
game = self.katrain and self.katrain.game game = self.katrain and self.katrain.game
current_node = game and self.katrain.game.current_node current_node = game and self.katrain.game.current_node
if ( if (
@@ -429,6 +457,20 @@ class BadukPanWidget(Widget):
self.draw_hover_contents() self.draw_hover_contents()
def draw_roi_box(self,region_of_interest,width=2):
xmin, xmax, ymin, ymax = region_of_interest
Color(*LIGHTER_BACKGROUND_COLOR)
Line(
rectangle=(
self.gridpos_x[xmin] - self.grid_size/6,
self.gridpos_y[ymin] - self.grid_size/6,
(xmax - xmin + 1/3) * self.grid_size,
(ymax - ymin + 1/3) * self.grid_size,
),
dash_length=10,dash_offset=10,
width=width,
)
def draw_hover_contents(self, *_args): def draw_hover_contents(self, *_args):
ghost_alpha = POLICY_ALPHA ghost_alpha = POLICY_ALPHA
katrain = self.katrain katrain = self.katrain
@@ -442,6 +484,7 @@ class BadukPanWidget(Widget):
with self.canvas.after: with self.canvas.after:
self.canvas.after.clear() self.canvas.after.clear()
self.active_pv_moves = [] self.active_pv_moves = []
# hints or PV # hints or PV
hint_moves = [] hint_moves = []
@@ -582,16 +625,24 @@ class BadukPanWidget(Widget):
width=dp(1.2), width=dp(1.2),
) )
# hover next move ghost stone if self.selecting_region_of_interest and len(self.region_of_interest) == 4:
if self.ghost_stone: x1, x2, y1, y2 = self.region_of_interest
self.draw_stone(*self.ghost_stone, next_player, alpha=ghost_alpha) self.draw_roi_box([min(x1, x2), max(x1, x2), min(y1, y2), max(y1, y2)],width=2)
else:
# hover next move ghost stone
if self.ghost_stone:
self.draw_stone(*self.ghost_stone, next_player, alpha=ghost_alpha)
animating_pv = self.animating_pv
if animating_pv:
pv, node, start_time, _ = animating_pv
delay = self.katrain.config("general/anim_pv_time", 0.5)
up_to_move = (time.time() - start_time) / delay
self.draw_pv(pv, node, up_to_move)
if self.katrain.game.region_of_interest:
self.draw_roi_box(self.katrain.game.region_of_interest, width=1) # dashed
animating_pv = self.animating_pv
if animating_pv:
pv, node, start_time, _ = animating_pv
delay = self.katrain.config("general/anim_pv_time", 0.5)
up_to_move = (time.time() - start_time) / delay
self.draw_pv(pv, node, up_to_move)
def animate_pv(self, _dt): def animate_pv(self, _dt):
if self.animating_pv: if self.animating_pv:
Binary file not shown.
+17 -3
View File
@@ -657,9 +657,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "简明风格" msgstr "简明风格"
msgid "analysis:local"
msgstr "寻找局部走法"
msgid "local analysis" msgid "local analysis"
msgstr "正在寻找局部走法" msgstr "正在寻找局部走法"
@@ -739,3 +736,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+17 -3
View File
@@ -707,9 +707,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "Einfacher Stil" msgstr "Einfacher Stil"
msgid "analysis:local"
msgstr "Finde lokale Antworten"
msgid "local analysis" msgid "local analysis"
msgstr "Suche nach lokalen Antworten" msgstr "Suche nach lokalen Antworten"
@@ -791,3 +788,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+16 -3
View File
@@ -109,9 +109,14 @@ msgstr "Deeper full game analysis"
msgid "analysis:alternatives" msgid "analysis:alternatives"
msgstr "Find alternative moves" msgstr "Find alternative moves"
#. Analyze again but allow only nearby moves #. Restrict analysis to a specific region
msgid "analysis:local" msgid "analysis:region"
msgstr "Find local responses" msgstr "Set region of interest"
#. Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. Keep improving current position analysis when there is nothing else to do #. Keep improving current position analysis when there is nothing else to do
msgid "analysis:continuous" msgid "analysis:continuous"
@@ -120,6 +125,10 @@ msgstr "Toggle continuous analysis"
msgid "analysis:aimove" msgid "analysis:aimove"
msgstr "Force AI Move" msgstr "Force AI Move"
#. Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. status message #. status message
msgid "extra analysis" msgid "extra analysis"
msgstr "Performing additional analysis to {visits} visits" msgstr "Performing additional analysis to {visits} visits"
@@ -343,6 +352,10 @@ msgstr "Update Timer"
msgid "New Game title" msgid "New Game title"
msgstr "Setup New Game" msgstr "Setup New Game"
#. in new game options
msgid "player names"
msgstr "Player Names"
msgid "board size" msgid "board size"
msgstr "Board size" msgstr "Board size"
Binary file not shown.
+17 -4
View File
@@ -713,10 +713,6 @@ msgstr "Plays moves that lead to simplifying the board state."
msgid "ai:simple" msgid "ai:simple"
msgstr "Simple Style" msgstr "Simple Style"
#. TODO - Analyze again but allow only nearby moves
msgid "analysis:local"
msgstr "Find local responses"
#. TODO - status message #. TODO - status message
msgid "local analysis" msgid "local analysis"
msgstr "Searching for local responses" msgstr "Searching for local responses"
@@ -799,3 +795,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+17 -3
View File
@@ -743,9 +743,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "Modéré" msgstr "Modéré"
msgid "analysis:local"
msgstr "Proposer des coups locaux"
msgid "local analysis" msgid "local analysis"
msgstr "Recherche de coups locaux." msgstr "Recherche de coups locaux."
@@ -825,3 +822,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+17 -4
View File
@@ -698,10 +698,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "簡明派" msgstr "簡明派"
#. Analyze again but allow only nearby moves
msgid "analysis:local"
msgstr "近辺の応手に絞って分析"
#. status message #. status message
msgid "local analysis" msgid "local analysis"
msgstr "近辺の応手を分析中" msgstr "近辺の応手を分析中"
@@ -783,3 +779,20 @@ msgstr "Inserting exchange done and copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+16 -3
View File
@@ -671,9 +671,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "간명한 기풍" msgstr "간명한 기풍"
msgid "analysis:local"
msgstr "국지적인 응수 찾기"
msgid "local analysis" msgid "local analysis"
msgstr "국지적인 응수를 찾고 있습니다" msgstr "국지적인 응수를 찾고 있습니다"
@@ -753,3 +750,19 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr "Drag to select the region of interest."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.
+17 -3
View File
@@ -706,9 +706,6 @@ msgstr ""
msgid "ai:simple" msgid "ai:simple"
msgstr "Простой стиль" msgstr "Простой стиль"
msgid "analysis:local"
msgstr "Найти локальные ответы"
msgid "local analysis" msgid "local analysis"
msgstr "Поиск локальных ответов" msgstr "Поиск локальных ответов"
@@ -788,3 +785,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
msgid "finish inserting before navigating" msgid "finish inserting before navigating"
msgstr "" msgstr ""
"Navigation is disabled in insert mode, finish insert mode by pressing 'i'. " "Navigation is disabled in insert mode, finish insert mode by pressing 'i'. "
#. TODO - in new game options
msgid "player names"
msgstr "Player Names"
#. TODO - Option in dropdown to insert some moves between the current and next
msgid "analysis:insert"
msgstr "Insert moves"
#. TODO - Status message
msgid "analysis:region:start"
msgstr ""
"Drag to select the region of interest. Selecting a single point removes it."
#. TODO - Restrict analysis to a specific region
msgid "analysis:region"
msgstr "Set region of interest"
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

+4 -12
View File
@@ -310,17 +310,9 @@
DescriptionLabel: DescriptionLabel:
font_size: DESC_FONT_SIZE * 0.8 font_size: DESC_FONT_SIZE * 0.8
text: i18n._("show stats if") text: i18n._("show stats if")
BoxLayout: AnchorLayout:
Label: LabelledIntInput:
text: '>' input_property: "trainer/low_visits"
size_hint: 0.1, 1
AnchorLayout:
LabelledIntInput:
input_property: "trainer/low_visits"
Label:
size_hint: 0.1, 1
text: i18n._('visits')
Label:
DescriptionLabel: DescriptionLabel:
font_size: DESC_FONT_SIZE * 0.8 font_size: DESC_FONT_SIZE * 0.8
text: i18n._("show ai dots") text: i18n._("show ai dots")
@@ -396,7 +388,7 @@
spacing: CP_SPACING spacing: CP_SPACING
padding: CP_PADDING padding: CP_PADDING
DescriptionLabel: DescriptionLabel:
text: i18n._("names") text: i18n._("player names")
AnchorLayout: AnchorLayout:
LabelledTextInput: LabelledTextInput:
text: '' text: ''