tsumego solver 5000 is go
This commit is contained in:
1 parent
da42fc4e0f
commit
0ade2524ce
27 files changed
+252
-83
No files matched your search
@@ -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:
|
||||
- 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
|
||||
|
||||
3. The True Type Font DIGITAL-7 version 1.02 by Sizenko Alexander, which is free for non-commercial use.
|
||||
|
||||
@@ -101,12 +101,13 @@ for lang in locales:
|
||||
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:
|
||||
for i, line in enumerate(f.readlines()):
|
||||
matches = [m.strip() for m in re.findall(r"i18n._\((.*?)\)", line)]
|
||||
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()}'")
|
||||
errors += 1
|
||||
|
||||
|
||||
+5
-1
@@ -324,6 +324,10 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
def _do_analyze_extra(self, 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):
|
||||
self.controls.timer.paused = True
|
||||
if not self.new_game_popup:
|
||||
@@ -489,7 +493,7 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
"s": ("analyze-extra", "equalize"),
|
||||
"d": ("analyze-extra", "sweep"),
|
||||
"f": ("analyze-extra", "alternative"),
|
||||
"g": ("analyze-extra", "local"),
|
||||
"g": ("select-box",),
|
||||
"i": ("insert-mode",),
|
||||
"p": ("play", None),
|
||||
"n": ("next-mistake",),
|
||||
|
||||
+9
-10
@@ -6,7 +6,7 @@ import subprocess
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
from typing import Callable, Dict, Optional
|
||||
from typing import Callable, Dict, Optional, List
|
||||
|
||||
from kivy.utils import platform
|
||||
|
||||
@@ -112,6 +112,7 @@ class KataGoEngine:
|
||||
self.terminate_query(query_id)
|
||||
self.queries = {}
|
||||
|
||||
|
||||
def restart(self):
|
||||
self.queries = {}
|
||||
self.shutdown(finish=False)
|
||||
@@ -249,7 +250,7 @@ class KataGoEngine:
|
||||
analyze_fast: bool = False,
|
||||
time_limit=True,
|
||||
find_alternatives: bool = False,
|
||||
find_local: bool = False,
|
||||
region_of_interest: Optional[List] = None,
|
||||
priority: int = 0,
|
||||
ownership: Optional[bool] = None,
|
||||
next_move: Optional[GameNode] = None,
|
||||
@@ -278,22 +279,20 @@ class KataGoEngine:
|
||||
"untilDepth": 1,
|
||||
}
|
||||
]
|
||||
elif find_local:
|
||||
distance = 5
|
||||
last_move = analysis_node.move
|
||||
if last_move is None or last_move.is_pass:
|
||||
return
|
||||
elif region_of_interest:
|
||||
xmin, xmax, ymin, ymax = region_of_interest
|
||||
avoid = [
|
||||
{
|
||||
"moves": [
|
||||
Move((x, y)).gtp()
|
||||
for x in range(0, size_x)
|
||||
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,
|
||||
"untilDepth": 1,
|
||||
"player": player,
|
||||
"untilDepth": 10000,
|
||||
}
|
||||
for player in "BW"
|
||||
]
|
||||
else:
|
||||
avoid = []
|
||||
|
||||
+19
-6
@@ -62,6 +62,8 @@ class Game:
|
||||
self.insert_mode = False
|
||||
self.insert_after = None
|
||||
|
||||
self.region_of_interest = None
|
||||
|
||||
if move_tree:
|
||||
self.root = move_tree
|
||||
self.komi = self.root.komi
|
||||
@@ -233,7 +235,11 @@ class Game:
|
||||
played_node = self.current_node.play(move)
|
||||
self.current_node = played_node
|
||||
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
|
||||
|
||||
def set_current_node(self, node):
|
||||
@@ -410,6 +416,17 @@ class Game:
|
||||
f.write(sgf)
|
||||
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):
|
||||
stones = {s.coords for s in self.stones}
|
||||
cn = self.current_node
|
||||
@@ -426,7 +443,7 @@ class Game:
|
||||
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)
|
||||
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
|
||||
if mode == "game":
|
||||
nodes = self.root.nodes_in_tree
|
||||
@@ -467,10 +484,6 @@ class Game:
|
||||
visits = engine.config["fast_visits"]
|
||||
self.katrain.controls.set_status(i18n._("sweep analysis").format(visits=visits), STATUS_ANALYSIS)
|
||||
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"]:
|
||||
if not cn.analysis_complete and mode != "local":
|
||||
self.katrain.controls.set_status(i18n._("wait-before-equalize"), STATUS_INFO, self.current_node)
|
||||
|
||||
@@ -145,13 +145,14 @@ class GameNode(SGFNode):
|
||||
refine_move=None,
|
||||
analyze_fast=False,
|
||||
find_alternatives=False,
|
||||
find_local=False,
|
||||
region_of_interest = None,
|
||||
report_every=0.25,
|
||||
):
|
||||
additional_moves = bool(find_alternatives or region_of_interest)
|
||||
engine.request_analysis(
|
||||
self,
|
||||
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,
|
||||
visits=visits,
|
||||
@@ -159,7 +160,7 @@ class GameNode(SGFNode):
|
||||
time_limit=time_limit,
|
||||
next_move=refine_move,
|
||||
find_alternatives=find_alternatives,
|
||||
find_local=find_local,
|
||||
region_of_interest=region_of_interest,
|
||||
report_every=report_every,
|
||||
)
|
||||
|
||||
|
||||
+3
-3
@@ -751,13 +751,13 @@
|
||||
shortcut: 'f'
|
||||
on_action: root.katrain("analyze-extra", "alternative")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:local")
|
||||
text: i18n._("analysis:region")
|
||||
icon: 'img/local.png'
|
||||
shortcut: 'g'
|
||||
on_action: root.katrain("analyze-extra", "local")
|
||||
on_action: root.katrain("select-box",)
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:insert")
|
||||
icon: 'img/local.png'
|
||||
icon: 'img/insert.png'
|
||||
shortcut: 'i'
|
||||
on_action: root.katrain("insert-mode")
|
||||
AnalysisMenuItem:
|
||||
|
||||
+70
-19
@@ -48,6 +48,9 @@ class BadukPanWidget(Widget):
|
||||
self.gridpos_y = []
|
||||
self.grid_size = 0
|
||||
self.stone_size = 0
|
||||
self.selecting_region_of_interest = False
|
||||
self.region_of_interest = []
|
||||
|
||||
self.active_pv_moves = []
|
||||
self.animating_pv = None
|
||||
self.last_mouse_pos = (0, 0)
|
||||
@@ -57,6 +60,12 @@ class BadukPanWidget(Widget):
|
||||
self.bind(size=self.redraw_trigger, pos=self.redraw_trigger)
|
||||
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
|
||||
def _find_closest(self, pos, gridpos):
|
||||
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:
|
||||
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):
|
||||
self.set_animating_pv(None, None) # any click kills PV from label/move
|
||||
if "button" in touch.profile and touch.button != "left":
|
||||
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):
|
||||
if "button" in touch.profile and touch.button != "left":
|
||||
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
|
||||
if self.get_root_window(): # don't proceed if I'm not displayed <=> If have no parent
|
||||
pos = args[1]
|
||||
rel_pos = self.to_widget(*pos) # compensate for relative layout
|
||||
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 = [
|
||||
(pv, node)
|
||||
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.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):
|
||||
if ("button" in touch.profile and touch.button != "left") or not self.gridpos_x:
|
||||
return
|
||||
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
|
||||
current_node = game and self.katrain.game.current_node
|
||||
if (
|
||||
@@ -429,6 +457,20 @@ class BadukPanWidget(Widget):
|
||||
|
||||
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):
|
||||
ghost_alpha = POLICY_ALPHA
|
||||
katrain = self.katrain
|
||||
@@ -442,6 +484,7 @@ class BadukPanWidget(Widget):
|
||||
|
||||
with self.canvas.after:
|
||||
self.canvas.after.clear()
|
||||
|
||||
self.active_pv_moves = []
|
||||
# hints or PV
|
||||
hint_moves = []
|
||||
@@ -582,16 +625,24 @@ class BadukPanWidget(Widget):
|
||||
width=dp(1.2),
|
||||
)
|
||||
|
||||
# hover next move ghost stone
|
||||
if self.ghost_stone:
|
||||
self.draw_stone(*self.ghost_stone, next_player, alpha=ghost_alpha)
|
||||
if self.selecting_region_of_interest and len(self.region_of_interest) == 4:
|
||||
x1, x2, y1, y2 = self.region_of_interest
|
||||
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):
|
||||
if self.animating_pv:
|
||||
|
||||
Binary file not shown.
@@ -657,9 +657,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "简明风格"
|
||||
|
||||
msgid "analysis:local"
|
||||
msgstr "寻找局部走法"
|
||||
|
||||
msgid "local analysis"
|
||||
msgstr "正在寻找局部走法"
|
||||
|
||||
@@ -739,3 +736,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -707,9 +707,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "Einfacher Stil"
|
||||
|
||||
msgid "analysis:local"
|
||||
msgstr "Finde lokale Antworten"
|
||||
|
||||
msgid "local analysis"
|
||||
msgstr "Suche nach lokalen Antworten"
|
||||
|
||||
@@ -791,3 +788,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -109,9 +109,14 @@ msgstr "Deeper full game analysis"
|
||||
msgid "analysis:alternatives"
|
||||
msgstr "Find alternative moves"
|
||||
|
||||
#. Analyze again but allow only nearby moves
|
||||
msgid "analysis:local"
|
||||
msgstr "Find local responses"
|
||||
#. Restrict analysis to a specific region
|
||||
msgid "analysis:region"
|
||||
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
|
||||
msgid "analysis:continuous"
|
||||
@@ -120,6 +125,10 @@ msgstr "Toggle continuous analysis"
|
||||
msgid "analysis:aimove"
|
||||
msgstr "Force AI Move"
|
||||
|
||||
#. Option in dropdown to insert some moves between the current and next
|
||||
msgid "analysis:insert"
|
||||
msgstr "Insert moves"
|
||||
|
||||
#. status message
|
||||
msgid "extra analysis"
|
||||
msgstr "Performing additional analysis to {visits} visits"
|
||||
@@ -343,6 +352,10 @@ msgstr "Update Timer"
|
||||
msgid "New Game title"
|
||||
msgstr "Setup New Game"
|
||||
|
||||
#. in new game options
|
||||
msgid "player names"
|
||||
msgstr "Player Names"
|
||||
|
||||
msgid "board size"
|
||||
msgstr "Board size"
|
||||
|
||||
|
||||
Binary file not shown.
@@ -713,10 +713,6 @@ msgstr "Plays moves that lead to simplifying the board state."
|
||||
msgid "ai:simple"
|
||||
msgstr "Simple Style"
|
||||
|
||||
#. TODO - Analyze again but allow only nearby moves
|
||||
msgid "analysis:local"
|
||||
msgstr "Find local responses"
|
||||
|
||||
#. TODO - status message
|
||||
msgid "local analysis"
|
||||
msgstr "Searching for local responses"
|
||||
@@ -799,3 +795,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -743,9 +743,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "Modéré"
|
||||
|
||||
msgid "analysis:local"
|
||||
msgstr "Proposer des coups locaux"
|
||||
|
||||
msgid "local analysis"
|
||||
msgstr "Recherche de coups locaux."
|
||||
|
||||
@@ -825,3 +822,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -698,10 +698,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "簡明派"
|
||||
|
||||
#. Analyze again but allow only nearby moves
|
||||
msgid "analysis:local"
|
||||
msgstr "近辺の応手に絞って分析"
|
||||
|
||||
#. status message
|
||||
msgid "local analysis"
|
||||
msgstr "近辺の応手を分析中"
|
||||
@@ -783,3 +779,20 @@ msgstr "Inserting exchange done and copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -671,9 +671,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "간명한 기풍"
|
||||
|
||||
msgid "analysis:local"
|
||||
msgstr "국지적인 응수 찾기"
|
||||
|
||||
msgid "local analysis"
|
||||
msgstr "국지적인 응수를 찾고 있습니다"
|
||||
|
||||
@@ -753,3 +750,19 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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.
@@ -706,9 +706,6 @@ msgstr ""
|
||||
msgid "ai:simple"
|
||||
msgstr "Простой стиль"
|
||||
|
||||
msgid "analysis:local"
|
||||
msgstr "Найти локальные ответы"
|
||||
|
||||
msgid "local analysis"
|
||||
msgstr "Поиск локальных ответов"
|
||||
|
||||
@@ -788,3 +785,20 @@ msgstr "Inserting exchange(s) done, copied {num_copied} following moves."
|
||||
msgid "finish inserting before navigating"
|
||||
msgstr ""
|
||||
"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
@@ -310,17 +310,9 @@
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("show stats if")
|
||||
BoxLayout:
|
||||
Label:
|
||||
text: '>'
|
||||
size_hint: 0.1, 1
|
||||
AnchorLayout:
|
||||
LabelledIntInput:
|
||||
input_property: "trainer/low_visits"
|
||||
Label:
|
||||
size_hint: 0.1, 1
|
||||
text: i18n._('visits')
|
||||
Label:
|
||||
AnchorLayout:
|
||||
LabelledIntInput:
|
||||
input_property: "trainer/low_visits"
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("show ai dots")
|
||||
@@ -396,7 +388,7 @@
|
||||
spacing: CP_SPACING
|
||||
padding: CP_PADDING
|
||||
DescriptionLabel:
|
||||
text: i18n._("names")
|
||||
text: i18n._("player names")
|
||||
AnchorLayout:
|
||||
LabelledTextInput:
|
||||
text: ''
|
||||
|
||||
Reference in new issue
Block a user