From 4e2ee03db7c04838473294a998aaffc77dc9f674 Mon Sep 17 00:00:00 2001 From: Sander Land Date: Tue, 8 Sep 2020 22:26:14 +0200 Subject: [PATCH] fewer hints, alternatives search --- README.md | 20 +++++---------- katrain/__main__.py | 1 + katrain/core/engine.py | 17 ++++++++++++- katrain/core/game.py | 18 ++++++++----- katrain/core/game_node.py | 22 +++++++++++++--- katrain/gui.kv | 5 ++++ katrain/gui/badukpan.py | 24 +++++++++++++----- katrain/gui/kivyutils.py | 1 + katrain/gui/style.py | 11 +++++--- .../i18n/locales/cn/LC_MESSAGES/katrain.mo | Bin 11866 -> 11927 bytes .../i18n/locales/cn/LC_MESSAGES/katrain.po | 5 ++++ .../i18n/locales/de/LC_MESSAGES/katrain.mo | Bin 14005 -> 14064 bytes .../i18n/locales/de/LC_MESSAGES/katrain.po | 17 ++++++++----- .../i18n/locales/en/LC_MESSAGES/katrain.mo | Bin 12991 -> 13156 bytes .../i18n/locales/en/LC_MESSAGES/katrain.po | 10 ++++++-- .../i18n/locales/es/LC_MESSAGES/katrain.mo | Bin 13802 -> 13863 bytes .../i18n/locales/es/LC_MESSAGES/katrain.po | 5 ++++ .../i18n/locales/fr/LC_MESSAGES/katrain.mo | Bin 14803 -> 14864 bytes .../i18n/locales/fr/LC_MESSAGES/katrain.po | 5 ++++ .../i18n/locales/jp/LC_MESSAGES/katrain.mo | Bin 15090 -> 15151 bytes .../i18n/locales/jp/LC_MESSAGES/katrain.po | 13 +++++++--- .../i18n/locales/ko/LC_MESSAGES/katrain.mo | Bin 14945 -> 15009 bytes .../i18n/locales/ko/LC_MESSAGES/katrain.po | 5 ++++ .../i18n/locales/ru/LC_MESSAGES/katrain.mo | Bin 18890 -> 18951 bytes .../i18n/locales/ru/LC_MESSAGES/katrain.po | 5 ++++ katrain/img/Alternative.png | Bin 0 -> 4384 bytes 26 files changed, 137 insertions(+), 47 deletions(-) create mode 100644 katrain/img/Alternative.png diff --git a/README.md b/README.md index 508fb96..d45689b 100644 --- a/README.md +++ b/README.md @@ -154,23 +154,21 @@ Keyboard shortcuts are shown with **[key]**. wanting to guess the next move. * **[w]**: Show all dots: Show all evaluation dots instead of the last few. * You can configure how many are shown with this setting off, and whether they are shown for AIs under 'Configure Teacher'. - * **[e]**: Top moves: Show the next moves KataGo considered, colored by their expected point loss. Small dots indicate high uncertainty. Hover over any of them to see the principal variation. - * **[r]**: Policy moves: Show KataGo's policy network evaluation, i.e. where it thinks the best next move is purely from the position, and in the absence of any 'reading'. + * **[e]**: Top moves: Show the next moves KataGo considered, colored by their expected point loss. + Small/faint dots indicate high uncertainty and never show text (lower than your 'fast visits' setting). + Hover over any of them to see the principal variation. + * **[r]**: Policy moves: Show KataGo's policy network evaluation, i.e. where it thinks the best next move is purely from the position, + and in the absence of any 'reading'. This turns off the 'top moves' setting as the overlap is often not useful. * **[t]**: Expected territory: Show expected ownership of each intersection. * The analysis options available under the 'Analysis' button are used for deeper evaluation of the position: * **[a]**: Deeper analysis: Re-evaluate the position using more visits, usually resulting in a more accurate evaluation. * **[s]**: Equalize visits: Re-evaluate all currently shown next moves with the same visits as the current top move. Useful to increase confidence in the suggestions with high uncertainty. * **[d]**: Analyze all moves: Evaluate all possible next moves. This can take a bit of time even though 'fast_visits' is used, but can be useful to see how many reasonable next moves are available. + * **[f]**: Find alternatives: Increases analysis of current candidate moves to at least the 'fast visits' level, and request a new query that excludes all current candidate moves. * **[spacebar]**: Turn continuous analysis on/off. This will continuously improve analysis of the current position, similar to Lizzie's 'pondering', but only when there are no other queries going on. * **[enter]** AI move. Makes the AI move for the current player regardless of current player selection. -### Rank Estimation - -A new feature in v1.3 is the rank estimation panel. This adds an extra graph which uses a statistical model to estimate the playing strength -of both players for every 80 move segment. It can be used for determining which part of your game needs extra attention, -but keep in mind the estimation is based purely on how well moves correspond to the 'shape sense' of KataGo and can be very inaccurate at times. - ## Keyboard and mouse shortcuts In addition to shortcuts mentioned above and those shown in the main menu: @@ -197,15 +195,11 @@ In addition to shortcuts mentioned above and those shown in the main menu: * Try using a lower number for `nnMaxBatchSize` in `KataGo/analysis_config.cfg`, and avoid using versions compiled with large board sizes. * If still encountering problems, please start KataGo by itself to check for any errors it gives. * Note that if you don't have a GPU, or your GPU does not support OpenCL, you should use the 'eigen' binaries which run on CPU only. -* How can I play on larger boards? - * For windows, change the `katago` setting to `katrain\KataGo\katago-bs52.exe`. For other operating systems, you need to compile your own KataGo version with higher limits. - ## Support / Contribute [![GitHub issues](https://img.shields.io/github/issues/sanderland/katrain)](https://github.com/sanderland/katrain/issues) [![Contributors](https://img.shields.io/static/v1?label=contributors&message=19&color=dcb424)](CONTRIBUTIONS.md) -[![Liberapay patrons](https://img.shields.io/liberapay/patrons/sanderbaduk)](https://liberapay.com/sanderbaduk/) [![Github sponsors](https://img.shields.io/static/v1?label=sponsor&message=7&logo=GitHub&color=dcb424&link=https://github.com/sponsors/sanderland/)](https://github.com/sponsors/sanderland) * Ideas, feedback, and contributions to code or translations are all very welcome. @@ -213,7 +207,7 @@ In addition to shortcuts mentioned above and those shown in the main menu: * I am looking for contributors of more translations of both this manual and the program itself. The best way to help with this is to contact me on discord. * You can contact me on [discord](https://discord.gg/AjTPFpN) (Sander#3278), [KakaoTalk](https://open.kakao.com/o/gTsMJCac) or [Reddit](http://reddit.com/u/sanderbaduk) to get help, discuss improvements, or simply show your appreciation. -* You can also donate to the project through [Liberapay](https://liberapay.com/KaTrain/) or [Github Sponsors](https://github.com/sponsors/sanderland). +* You can also donate to the project through [Github Sponsors](https://github.com/sponsors/sanderland). diff --git a/katrain/__main__.py b/katrain/__main__.py index a667637..687e659 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -440,6 +440,7 @@ class KaTrainGui(Screen, KaTrainBase): "a": ("analyze-extra", "extra"), "s": ("analyze-extra", "equalize"), "d": ("analyze-extra", "sweep"), + "f": ("analyze-extra", "alternative"), "p": ("play", None), "down": ("switch-branch", 1), "up": ("switch-branch", -1), diff --git a/katrain/core/engine.py b/katrain/core/engine.py index c2a3f9e..542753d 100644 --- a/katrain/core/engine.py +++ b/katrain/core/engine.py @@ -77,7 +77,9 @@ class KataGoEngine: elif not os.path.isfile(cfg): self.katrain.log(i18n._("Kata config not found").format(config=cfg), OUTPUT_ERROR) return # don't start - self.command = shlex.split(f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}') + self.command = shlex.split( + f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}' + ) self.start() def start(self): @@ -224,6 +226,7 @@ class KataGoEngine: visits: int = None, analyze_fast: bool = False, time_limit=True, + find_alternatives: bool = False, priority: int = 0, ownership: Optional[bool] = None, next_move: Optional[GameNode] = None, @@ -241,6 +244,17 @@ class KataGoEngine: if analyze_fast and self.config.get("fast_visits"): visits = self.config["fast_visits"] + if find_alternatives: + avoid = [ + { + "moves": list(analysis_node.analysis["moves"].keys()), + "player": analysis_node.next_player, + "untilDepth": 1, + } + ] + else: + avoid = [] + size_x, size_y = analysis_node.board_size settings = copy.copy(self.override_settings) if time_limit: @@ -254,6 +268,7 @@ class KataGoEngine: "analyzeTurns": [len(moves)], "maxVisits": visits, "komi": analysis_node.komi, + "avoidMoves": avoid, "boardXSize": size_x, "boardYSize": size_y, "includeOwnership": ownership and not next_move, diff --git a/katrain/core/game.py b/katrain/core/game.py index 359842e..7af8ad3 100644 --- a/katrain/core/game.py +++ b/katrain/core/game.py @@ -369,21 +369,27 @@ 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 == "equalize": + elif mode in ["equalize", "alternative"]: if not cn.analysis_ready: self.katrain.controls.set_status(i18n._("wait-before-equalize"), STATUS_INFO, self.current_node) return analyze_moves = [Move.from_gtp(gtp, player=cn.next_player) for gtp, _ in cn.analysis["moves"].items()] - visits = max(d["visits"] for d in cn.analysis["moves"].values()) - self.katrain.controls.set_status(i18n._("equalizing analysis").format(visits=visits), STATUS_ANALYSIS) priority = -1_000 + if mode == "alternative": # also do a quick update on current candidates so it doesn't look too weird + self.katrain.controls.set_status("Searching for alternatives", STATUS_ANALYSIS) + cn.analyze(engine, priority=-500, time_limit=False, find_alternatives=True) + visits = engine.config["fast_visits"] + else: + visits = max(d["visits"] for d in cn.analysis["moves"].values()) + self.katrain.controls.set_status(i18n._("equalizing analysis").format(visits=visits), STATUS_ANALYSIS) else: raise ValueError("Invalid analysis mode") for move in analyze_moves: - cn.analyze( - engine, priority, visits=visits, refine_move=move, time_limit=False - ) # explicitly requested so take as long as you need + if cn.analysis["moves"].get(move.gtp(), {"visits": 0})["visits"] < visits: + cn.analyze( + engine, priority, visits=visits, refine_move=move, time_limit=False + ) # explicitly requested so take as long as you need def analyze_undo(self, node): train_config = self.katrain.config("trainer") diff --git a/katrain/core/game_node.py b/katrain/core/game_node.py index 502c8bb..a9920c6 100644 --- a/katrain/core/game_node.py +++ b/katrain/core/game_node.py @@ -68,15 +68,25 @@ class GameNode(SGFNode): ) # analyzed/not undone main, non-teach second, undone last # various analysis functions - def analyze(self, engine, priority=0, visits=None, time_limit=True, refine_move=None, analyze_fast=False): + def analyze( + self, + engine, + priority=0, + visits=None, + time_limit=True, + refine_move=None, + analyze_fast=False, + find_alternatives=False, + ): engine.request_analysis( self, - lambda result: self.set_analysis(result, refine_move), + lambda result: self.set_analysis(result, refine_move, find_alternatives), priority=priority, visits=visits, analyze_fast=analyze_fast, time_limit=time_limit, next_move=refine_move, + find_alternatives=find_alternatives, ) def update_move_analysis(self, move_analysis, move_gtp): @@ -90,18 +100,22 @@ class GameNode(SGFNode): elif cur["visits"] < move_analysis["visits"]: cur.update(move_analysis) - def set_analysis(self, analysis_json, refine_move): + def set_analysis(self, analysis_json, refine_move, alternatives_mode): if refine_move: pvtail = analysis_json["moveInfos"][0]["pv"] if analysis_json["moveInfos"] else [] self.update_move_analysis( {"pv": [refine_move.gtp()] + pvtail, **analysis_json["rootInfo"]}, refine_move.gtp() ) else: + if alternatives_mode: + for m in analysis_json["moveInfos"]: + m["order"] += 10 # offset for not making this top for move_analysis in analysis_json["moveInfos"]: self.update_move_analysis(move_analysis, move_analysis["move"]) self.ownership = analysis_json.get("ownership") self.policy = analysis_json.get("policy") - self.analysis["root"] = analysis_json["rootInfo"] + if not alternatives_mode: + self.analysis["root"] = analysis_json["rootInfo"] if self.parent and self.move: analysis_json["rootInfo"]["pv"] = [self.move.gtp()] + ( analysis_json["moveInfos"][0]["pv"] if analysis_json["moveInfos"] else [] diff --git a/katrain/gui.kv b/katrain/gui.kv index fef7bf0..07219f9 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -744,6 +744,11 @@ icon: 'img/Sweep.png' shortcut: 'd' on_action: root.katrain("analyze-extra", "sweep") + AnalysisMenuItem: + text: i18n._("analysis:alternatives") + icon: 'img/Alternative.png' + shortcut: 'f' + on_action: root.katrain("analyze-extra", "alternative") AnalysisMenuItem: text: i18n._("analysis:game") icon: 'img/analysis.png' diff --git a/katrain/gui/badukpan.py b/katrain/gui/badukpan.py index 488d354..90f849e 100644 --- a/katrain/gui/badukpan.py +++ b/katrain/gui/badukpan.py @@ -361,7 +361,7 @@ class BadukPanWidget(Widget): polsize = 1.1 * math.sqrt(policy_grid[y][x]) policy_circle_color = ( *POLICY_COLOR, - POLICY_ALPHA + TOP_MOVE_ALPHA * (policy_grid[y][x] == best_move_policy), + POLICY_ALPHA + TOP_POLICY_ALPHA * (policy_grid[y][x] == best_move_policy), ) draw_circle( (self.gridpos_x[x], self.gridpos_y[y]), polsize * self.stone_size, policy_circle_color @@ -409,27 +409,37 @@ class BadukPanWidget(Widget): self.active_pv_moves = [] # hints or PV - if katrain.analysis_controls.hints.active and not katrain.analysis_controls.policy.active and not game_ended: + if ( + katrain.analysis_controls.hints.active + and not katrain.analysis_controls.policy.active + and not game_ended + ): hint_moves = current_node.candidate_moves for i, move_dict in enumerate(hint_moves): move = Move.from_gtp(move_dict["move"]) if move.coords is not None: - scale = 0.95 - if move_dict["visits"] < VISITS_FRAC_SMALL * hint_moves[0]["visits"]: - scale = 0.75 + scale = HINT_SCALE + text_on = True + alpha = HINTS_ALPHA + if move_dict["visits"] < katrain.config("engine/fast_visits"): + scale = UNCERTAIN_HINT_SCALE + text_on = False + alpha = HINTS_MIN_ALPHA + (HINTS_ALPHA - HINTS_MIN_ALPHA) * ( + move_dict["visits"] / katrain.config("engine/fast_visits") + ) if "pv" in move_dict: self.active_pv_moves.append((move.coords, move_dict["pv"], current_node)) else: katrain.log(f"PV missing for move_dict {move_dict}", OUTPUT_DEBUG) evalsize = self.stone_size * scale evalcol = self.eval_color(move_dict["pointsLost"]) - Color(*evalcol[:3], HINTS_ALPHA) + Color(*evalcol[:3], alpha) Rectangle( pos=(self.gridpos_x[move.coords[0]] - evalsize, self.gridpos_y[move.coords[1]] - evalsize), size=(2 * evalsize, 2 * evalsize), source="katrain/img/topmove.png", ) - if self.trainer_config["text_point_loss"]: + if self.trainer_config["text_point_loss"] and text_on: if move_dict["pointsLost"] < 0.05: ptloss_text = "0.0" else: diff --git a/katrain/gui/kivyutils.py b/katrain/gui/kivyutils.py index 40a3e43..a2b953b 100644 --- a/katrain/gui/kivyutils.py +++ b/katrain/gui/kivyutils.py @@ -373,6 +373,7 @@ class AnalysisToggle(MDBoxLayout): default_active = BooleanProperty(False) font_name = StringProperty(DEFAULT_FONT) disabled = BooleanProperty(False) + def trigger_action(self, *args, **kwargs): return self.checkbox.trigger_action(*args, **kwargs) diff --git a/katrain/gui/style.py b/katrain/gui/style.py index de037f4..6125534 100644 --- a/katrain/gui/style.py +++ b/katrain/gui/style.py @@ -59,13 +59,16 @@ POLICY_COLOR = [0.9, 0.2, 0.8] STARPOINT_SIZE = 0.1 BOARD_COLOR = [0.85, 0.68, 0.40, 1] STONE_SIZE = 0.505 # texture edge is transparent -VISITS_FRAC_SMALL = 0.1 -POLICY_ALPHA = 0.5 -HINTS_ALPHA = 0.75 -TOP_MOVE_ALPHA = 0.4 +HINTS_ALPHA = 0.8 +HINTS_MIN_ALPHA = 0.1 # single visit +POLICY_ALPHA = 0.6 +TOP_POLICY_ALPHA = 0.3 TOP_MOVE_BORDER_COLOR = [10 / 255, 200 / 255, 250 / 255, 1.0] CHILD_SCALE = 0.95 +HINT_SCALE = 0.975 +UNCERTAIN_HINT_SCALE = 0.7 + # ponder light ENGINE_DOWN_COL = EVAL_COLORS["theme:normal"][1] diff --git a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.mo index 71c09be37c4ee6d2d14e2aed03833284f3fe0a06..db2b7ee9427b52756373fe4a66045ca6a1b451b8 100644 GIT binary patch delta 3096 zcmYk-drVe!9LMqB0D*^_KygtK@E#WhET&~sW{b6aSh31milL$45JM4Np~qH>MGgrI zYqMH9#hEk*Su-cqY~m$dZBnU2mw9V8X({*zO1(ck->uy7yw30b`+k4tJe*&&eX(~j zKIDDJzr*}b;s2dsDmnK<Zz+{Y$a!y?*qRLY-9_L^hmRNZc#!`M4 z!*D0YIOn;2JPfDekaaj=p2rC4Z=xpb$7u9%OT;9k%1yx#oPpY40jmF89Elb9Aijw# z=sraC+dEYDoa^L45uHXKUP2A{1A}o86=4vg)gFV|STd@994ew5 zs^1f+BPd2~a4CBHcdNK5B^&Vp+=d#^ikjdcYQZk6{~5Kw736Yvxv4#j*;Sv28kd1u za0WLm=tuRNXXWLwoWCNjra}>J!f_nxw9o6q^)H`qtwecP+-$pJM!Rm4p zsy!Q(;n}EhesftI`PTxkQo-dKtYHT#10AS{zO(XKD_=&9>q9O#j7|z93AONe)I#|< z3jL_emLr#|5qVuTnH_Sd% z=7LD40*OP-Hxd;{7Dnj%&*xz%Rn}01ns^>+z%pbmSA+U>Zb0>KLcLrcp%yxX>VF)y z(Q~LX{?pp;p~giLjWUyr-g+J;^DqW?V=8u`I$lF9eA~)C-mu3hC*o>+4h!)pPQ(b_ zENv(c6>$-2{9H`KO3cG8I2}7jkbmv)E)|n7j34ZWFb6eoKI+V>P-nOqXJS3h!eh7t zLs@ki?n2FX0hNK9s8kQ)vlz}_IAv-9)?s-H`B#Ul*3gUVC=a3*tQj3R+t*N^AVR_@0}%E2D_-p)faDxysC)PyVX01n_O+@J2;JGg;!`V~XQ z2Kx2j9?DhY_|u9BFnm+ApBy>9hKviGj?LW?RP{gQ>rlF2%I;y?U+KbGEIP~{_1rOTcdgSjL z^DER5bfOme$?C78j_wv}p4jYwqmeziOytXUFIfGWZ1T_XIFAaYdapHfnP*W8|7PAW zd(D1iEqC9_8IuG3bIoZOMf*&1j@8dMm%PM-QnMU4U@dAuuXzs@sc%Z4J_WU*4Al3X zYxT2Gnee0fFGXcyUB{uwBf(Lnl{IB+s!D4rYRlGkR1R-SNGzuG delta 3044 zcmYM#3rtpJ9LMn|0fD%@h+v8!O7fC`4x$n(3mIdki_is&iZ+e8RbJT2v@%b0AuCNS z9n7pD+08alv4IVg*la^Ha*QNP1*FT83MDqOa(#ci|1EbopXdHR&;L2+wWj>+!`}JW z;GK?tpYxZ<-(ZMp&b37R?+p}NsmEhCPQXhz8UIBtHz_huPr+E~cVIFWS$#FeP_M#J zd<&zU^V}{9J{mr;0Y}Uecs=dkqZa%Lqwp`BgrQU@x@j1U8K?)$LX9uP1T4cidWrQuO$9<=iIXD%8L#)WogGT5gZEA3!a96uI1KZtCx|_94`~AfhNxJU0dM zqsC=hJrA|f#W9?}cJ=@bVOU`USD^xIK&5swYTORg+1H`Yu*vGDkjo92BdGrIJdHA& zh??g&=cCrYe**cZ>?*9|X;cQbpmzF>)%RPy1vRk~x!eVA+R0_q16)G|@-cZT`caw9 zN3B=NO__MiT<=lP#8*)}tVN}4FDfGq*58a;xC8Za_M#RZL4AhdRJ2ZtnS+{NVBU*U zsF$KPP>K3#ycZ~pr|=3Yz-AlpKI%yuQ32bn{R|S*{ftWORWq1D+CVfaBMGPnN<)py zMP)YM`iqfuJXcOZ11nKaRE2u-YSbBSMJ@0FYFvZW+fac{paP#kE_cx!MQtpKMRZhg zsCUVaT5k?U5Z~oe&_V^)u>=+9A=EG5O4N>Dw)PrSz>iToI*gj%Zg!$F_XBDpmr(2d zi3%J-nsvlJjMVp^KtUa8sD-mp6XqjxToLM5xdIjFan#GT4i)Ha)cAVTgEpeh_)F{m z7B%ljREDnLIt*oZ-V6#Jg=x44HLwj8_>|Qz;+@ooa1GApjVr`=(T@YD2a4bg(~i?n z^RqA+3o#p4U@q389`N)O@}EYbkA|BtoF8mWycu<73sGnIAl`+`@NTTb-PntB@p+}-E`Uk9j+3KTah<|Lp=VAi|myA05OsnUk7Q7F6VO<&OK`SvGU$Xjs ziDUe~g)gda!i!cJw$7w}?U*R-z_6g9=b>^)2Qu45$4g zs~d0>@z`YN031XHiE}g$lI8 z+V`Q3?jUNNF0&Vj>3&1LXg4`C(0?m(8ZIA|=_fMDzb3wJ18Pu#_nM!Yhs-0$ny$_2 zgXXY#6(i}tZg#+E)Ou6R6jTOg;d-1`OhFS4na5B&{mSYWPzwyAeyE16ecYTtCVZ&z Ysi;ikHg-g`1~u;XRmV5ZOMN8#KN&wCbpQYW diff --git a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po index 959abdf..8a41685 100644 --- a/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/cn/LC_MESSAGES/katrain.po @@ -521,6 +521,7 @@ msgstr "读秒声音开启" msgid "tab:info-details" msgstr "详细" +#. TODO: updated msgid "teaching undo message" msgstr "撤销第 {move} 手棋因为损失超过 {points_lost:.1f} 目. 悬停在该手棋 上方查看信息. 请再次尝试." @@ -631,3 +632,7 @@ msgstr "启动katago失败因缺失dll文件. 请检查运行要求, 或尝试 #. TODO - resign the game msgid "resign" msgstr "Resign" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" diff --git a/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/de/LC_MESSAGES/katrain.mo index 86b01ac29e9127c9b56346ad2036e890d68234d3..d8769577f13506b2b23aab69315a78fbd5e4a876 100644 GIT binary patch delta 3106 zcmYk;drX&A9LMo5$o1c?Ql@#C8)<@Z5tzxeIpwkCAB5f1 zskvEOl-lgJM7FFnTTR6a(-JpGZBuKQHBqy+5Z3#{?`+i`pVv9hb8g@7InR$;YkF$D z%l@$K#(!V&?>_$h8LpbyY2SaQP&`9@DE@*;*o&zc7i*@bS*Use`f)anz*1Llz(nd> zFcOa895Zr`J zXuDADJ{+ifW=AL}qB9tcKchNa$3fVSiZGPkdLNHkSSsrIC{#q_k;{s>>HTz6`?<~~ zsP^T^WvjTwF~4o3poVXtB6=ISY!5eO<{+x$_o&FuB9~p|#@g(*Q;pR=o}1cbpaRQB zwR;@31#?jgd>%diSq(R(WCISyZKw|WPy@80COqz*UqDT84Y}-ZZh9Zd=z5-v>Nf^8 z;S_F~uo%^Dp{uV*Wd9ZMDjq1p28_Zc*KiwZf@V~T51`t8i8=$vPz%50>UWUKVwhc~ zqu!50W%w~vzhdX|B=WBb*71PLn%s-ss0_5ABKp?V&%62+RKL5(W#KeZAStMcN24Yx z#B?l1WwrvjY&|z+;!V#L-bHo%1Qp>CRLV}GGScDRUq%gl6Lm-<7*zwObJOQH9yQLB z&c&$yRnFBojQV<10NxG?`h50c1b&2?;DBq;hFWPSYQk>!yboD}#qm(7&2;9V0+@ix z$W+vV=D7EzsLWOb-+Q)(f(Cj8)o=%DLHkfE{}{E0t*D7kq1tu0`md;odQcPhA(utd zNoJq|3!t`YGU_Z9V>IW_=2K9|Qq(|I124?hq9%G7^$WNawb1?U`C(MQc2q=NsQ%r~ zyQs{Cl1>GZgc>gm706hO(f40SVIWoR#T?YY3sD`GBV$=T>esmm)&4Ei;d%!((IHg( z6R3rDqW1WA_x>KLpO0vinN;+uDdbX^jJq%&&m(Ouf)k~~G8`3Q5mw+6_!)kRPhlyI z3ROq7zs5}w_v1*6VM*g)YU%LnGIG%baVGYLuROC;i&cq6wht)U> zzrouW!(Xo1*oRv9Oga;TEyWys37hbJ9D{ioW=C;R2Km=-{IC(hR1U}2sXvT5G{;dX zYez-&ldE5I-a=)j9~DS!W^n5=oH?j1nTQ&125P(#JcUa<3YREklczEazn}fXD!hn+ zQQSfpWVG3L6q6oc@2GcR8};9^*aGSYv(5gX9!7YZ@iuCr2Ex|@Hls4L8(FKhU<`Uc zQh1QUWlX@xvB5u^DX2qLfEs8T>i-W)P?1)n4>url+pDN{pS$NrP!XR*eQxJa<9E9H zb>w(>cFVo+jSH?Q9W_uEYQ+Imif6g!i;(14IciH9aRP2ZeI3V;?X}aWvvUJ=+Cy@K z0VLyM>Vbi}$9_}Lq1%t@(1pr+4|2e5NS+zlwp`@A**sKA>u?5cM4jprI2Hdv^_#+= zMK~X|fY-19-@|x3j{|@IuTqHS!7WtBUep4HJY>dYleqC=Sf#6PLTyDWX5tU16yHIO z(~Bc9oKb@Pd#Ek) zPYh0!hdSi})bnRhXQmd_Z!6Bky)B1)hX=(jTUlTJV(qf}$~EPyTUI9Qi3%&JD=TkF aNnPeoo?cm7mifO1nKgB4wKnI`*na_#Q88iw delta 3056 zcmYM$drZ}39LMpm0Y~L_gd>WiAYP!53_YZ#v6PX{7mP2EnSpLObFKR2$}Zlh z45et5w`Fdj?TA{_I^o9hg4kM}p{AH=ZCWGB1Q)FLr}J#F!|(Mxzu$BFexK)eprfj> z%Db2vTWkD$!S7IhZ^Wr)b~NFC2U9#oJq^Fd6uge<*n@m*P-3(`0#m6^!7MCy^=ceI zeI542w=vnwv-c?Yx$%i>@VWCO#&iEXYQSrlgxxp@`%Pzx+TwV#d|xBv&@ zYGgut1J$nXzq)7EKtT~5!~WQc>d=NU_&X}XPWQYQwXlASruzX@L|Lc_a=GaF1k`xb zoTaGtk0Kvi$|Z^UZ50JId=VAV>&VAyxhONcQ5_GWA`2rQ`;H51v7ekBsP?_6cF9x} zST?F%5VZx2DPO8~1-4cDPM)*xfq4tM_mYTz%CkA2HU&o8_C9jJaW%%X|X zxM-prRJ(DmJ{1*c=>Ya$kk4o((RJ(Ujd;bw?4-dO~3-Ym_oi|a> zeXK^A9g6Cg<19jrKQD#+Q?^R?U=1n*n^BS0yLyAGA4PR+MLu?kiz4|0wSZpKM1DHo zi8-ju7Nf?i;G#?{cdqp)sN-v>2`z7GjBo}~ z{Y#u>ID~oyDu7j}x5j&kf{(&_)C8McgI%bVhENkWx%&}hPWuIw+S|@p8YzHeR7NsT z3(7^cn}o`2v3oun8OO6F6x47PYDMc%D}NQWhc&1H_MqDBcl9u8qLZkJBgn_DIJ;1R zB{7J$Y9Q(?<)FqJiwVqclPGAQ68B&ZYNAD`Z@#Bd5x?T@Z%0kI7ZuS#RR1PtD=Kpr zP=Q=WjrSL7;yBW*E%sxg-v0~=dXS46cpR!j5z@!XQQyjysEM9J9j<3l6KzGc--%ji z2(`z}?)eX>epgW$>ckb;m*~976rQ0l4jYhX){Z(Xw@?G6aKfI%Y}}6Apg3tj~n;mMI467gr~^!QD>qUAHf;;FxF!y zUc*vs<1d#MKAO&~*&e_=oQE6G!@Ds)lSN`7>Z|=`Ci!O!>*mI0Ov{QMnq8=r?L$R$ z*ww?%7S!IKLq+l{YU^%0eZ!+$l8QQnBT?h!;VGPmKVpnWo+>F^#&2-?2o4VVM{?=I zpJO~u@wZXz9re#f^Bq9FIfpHv{$?)EsJGu`wh_+|rY2fQ_&O8IkTuy_jK?~psqI2- zt#_INS+@(Q!*mNZfNxCn|A7E1!U9adVq{J$N3~ny?!SzRvZ9`4)fvY#5&d4Em z|18Gq{coqBfv%(WunU!1e}44-FeE9KhuVrVEW`@bTd@(@J$nmvW)7fEc{A!Cn)A2- zyIg(lJ<+qa64Uhle@H>uZbW^Rwjo)zPSn{*9~(_&APiv zz#JTpPhc{>i%GZ_^|~Lzbmq4(1udWr3$O>ZC1a_mK9h?gc@Br;c2tUwpau$KHl9RH zd;|5?^kJ2x*nFt*Qc&Ly`KZ7iM33`gizp1h^{5WpFn~KS5gSpdZ^8sTg^DDC>UR~D zfxl6a`UzVTW}>$4e$+UNQR6O0W$K0T@1c_0`) z3mK^XvrywzAiHPFkZreG)WVyP-Lf;t3uHY(^6#fGiW4OZQIVFQGEs)SWj5cr5DC&2 zqf)#DwZN^Y3F=XievHb*LDYE1QRAIP-eim59{gvvd$5!5(Ev9-MV;cWQF|0YP4p+~ wly|xNgC|7KOc2%YF`S7jLMIZA#f0AX*Z1?4R`qI=;D6c5-UsTO5YybcN diff --git a/katrain/i18n/locales/de/LC_MESSAGES/katrain.po b/katrain/i18n/locales/de/LC_MESSAGES/katrain.po index fb18d0b..694e89b 100644 --- a/katrain/i18n/locales/de/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/de/LC_MESSAGES/katrain.po @@ -105,12 +105,6 @@ msgstr "AI Zug erzwingen" msgid "pass-button-text" msgstr "Passen" -msgid "teaching undo message" -msgstr "" -"Zug {move} zurückgenommen, da er {points_lost:.1f} Punkte verliert. Bewege " -"Mauszeiger über den Zug,um die erwartete Widerlegung zu sehen. Bitte " -"versuche es erneut." - msgid "ai-ponder" msgstr "" "Zeigt den Enginestatus an von grün (Leerlauf) bis orange(Zugberechnung). Ist" @@ -680,3 +674,14 @@ msgstr "Zeig den Punkteverlust auf Beste Züge" #. TODO - resign the game msgid "resign" msgstr "Resign" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" + +#. TODO - updated +msgid "teaching undo message" +msgstr "" +"Zug {move} zurückgenommen, da er {points_lost:.1f} Punkte verliert. Bewege " +"Mauszeiger über den Zug,um die erwartete Widerlegung zu sehen. Bitte " +"versuche es erneut." diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo index 1a8577021adcda04e61d156bbdf138f59b3e40bc..394e52092271ec57c51cc1124e4a80e0b3263075 100644 GIT binary patch delta 3230 zcmYk-drZ}39LMp;3v$0{31Z?;Q4&QFFS*oZ(?zW?vYgZ;>j*zNN0FoF951DEXxbmJ zWd@6xGcD63%dI3gZ^R`Pe^Pne1~FdY*Uj8W5URDKwC#YeC=PP6$cOd8<)C)WXtHbr zQ&H_*9Yh{;nip#`m#k{6_DQ_dE)%t} zd{ny$s3Vw!THtgH^KWMJQb?9yH>^i>*oYcnD{8{Mw){KP1ZR-PT;-+uXhv6gcT~R| z)P!SrX~IHOyJDN4k;3_F$8#yr4y!N*Yi+}N)CB8LA>M*&w*z$tK1VJ5gw6kjJSL9W zWlvOnE-J#~QT+<7rK!YU6Fg4=kEyj4t5FeXLha~doB!74Poert$5rIucH8Bo#GY25KXNFixNUktEtfWh*A41};W*C`HCHA=I~XEvo$r)a7~| zHPLod`+cZ|9z~t;d0T%I)i0jiC^G37t{^d(L=LXPyKxUHROeBb>NaXYX=I8q3s>MG zEW!kC)Br5OOnecwLq%jgYQpzXp>9UC{|eRaxGlec8t*phV;#jRKERYPi8d0S;1qn* z;ad%_;cjg1W6Tk(>dWr{PRTOn0><~_obfu2>%hYMa}mjRBF@!#2(`c`I2T>cXOQDJ zvytGLWvELSUQ2?p%{!91;5I>6yY|2p^ zsM$QSpf2$d9D?UC9y11WG|X?ZNyOp^REX|FeXfg;wq_P8^ed73W14LK5Ng4{qe33d z=rRSl4yFfcq2o|TQG|-nWK_hbV&wOqghI9i)v*D!!d;kz`%nWPK`rzoYM|e2`Jb3T z{<^J?&WkK872_x$gxbJ8s0~cQM4XdnKmSz}aAD0$n2cLdEB*{SVhcuLD{A6zP-l4z z6@g2(JYi_$D7vBAk40@{ye)qeb+ijm8(A}y`0MN%Dd4-oe2rS!1yskIn2a$Tq#}@x zeA-MOYZmgD{=Br{V$>xrK`o#R6@i(kap&3crKs_0JS6l@Rfi|B5f#dsVUZ3EsQUHR z9jJ*8VplwjTHsmK5ne;}PaST|1DH9yX-E97P6?ihkQ=D2{54JpV6L~?)L=BoCRJt;5u{s4Cz$( QgF(j^{CA-GQ~4+U0efv_WB>pF delta 3074 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 NOnt^@1G;QX`xjmMI1c~- delta 3044 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 delta 3044 zcmYM#3uu;A7{Kup^V)QC(|K9CIWL=e%VkbO7iwC9mn=<`Fj@|@i#hU^WPYyFGBu@~ z_e9h1LTIstCTe0KO$ldWVw&cq25M%OnL(rfzwbcu?fso|-t(Swp68tRb@_}F(-Y@1 z>s18)?d7j6f7j|;3t?aC|F)vIpL!Oa#0tQ!^fxXcFk6<=Vz!o?I znJ_Fu`>p=3o(N$l1tZ#zjqw=zz-dgu>u7{GF6 zqI|SpVXO~C10CLs{Wr4lG&I7}*l{X4!CW-8OVEBR(7oS??&0oO{|5Pm%h6lt{RXVY z%(g|J%a0bL%yfF*Sz*02Qb+NuP*7u=o$gX&Q4?1u)dN_YX2fl^AhK;E>PKRi3^!Xvt zk=Ta%I5dDV^sPzEr_g}H0(62UvBPF`rIqM}hhqCFWX@2FruOe>Jvtdc8k&)8bU_7Z zzkXXq9f?Ur;uN`6#WYgtSN)I zRV~o7l#hyu`;I31h#{%2G0Mgcl-A^Jcu@=O?oew9nniJnIf*KBm6_tE|zq6@7=_xNzU z{~h|=PiTg2;tSZ2=n`EhOs7zc>yhmY-(x;rM+eN}gguL0a3e0pN!Xne)eo0rN32E< z*)Or)kneAM>fP``9D$>8A-cd*+2nr=g<2ZAV}HW(KcOjTtmw)DaD6vEAh2d&4~B7=;he1?@o& zdN_<__ydxhFsd*)-m94B`@fZf6IP>{IEiFG+>ExmKY4!u=F>h5J@wP@A>4*8tQMW% zPt3!Py_0X%P&6}dps)Em=%HR=JM)J%6kO>>WLv{-?12}M?GNb>Bv;%AO??R(`Eqm% z)}VX31)b-boiQ1kKd=BJ$sY!U7tca4j0qrdac82SDMA1M diff --git a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po index b2aaf45..4ede1f0 100644 --- a/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/fr/LC_MESSAGES/katrain.po @@ -522,6 +522,7 @@ msgstr "" "possiblement pour cause de \n" "mémoire insuffisante : {error}" +#. TODO: updated msgid "teaching undo message" msgstr "" "Le coup {move} a été annulé car il perdait {points_lost:.1f} points. Vous " @@ -715,3 +716,7 @@ msgstr "Indiquer les points perdus" #. TODO - resign the game msgid "resign" msgstr "Resign" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" diff --git a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.mo index 3d441077cb5dc22bb2c22c0fab6387ae1135c8d6..1617864e752194e0225cb7ec19d8635103313e9e 100644 GIT binary patch delta 3096 zcmYk-drVh#7{~D^#0ytN1QF^dl%j+pDu#loGe>RU%5+KT5WF;T-bLFAJejmMT3*XC z)0vyuv@7TuHJMDOVZ!=DGi+H)ZMIxC)chm0-XG4hl{=i*_kMZ4-}AF;?WgO4i~XbD zGX8zV-~IgE?5UjDnYjNPNV1)L3SPk^{2S9SA>K?)vr+jm*dI%AFjjbeJ@zBN6?@}8 zOf(DZAc?*dG<$Gzc2w~c%|Y%q{#9x8jDd2oPuiq45ni>4#0Y3LfeUI z_hENFFl!;99kpW&{)FoA8}`6^s2xVpTlI;kg{7g&A42VD6!KUhFV&Zz+Rt$3pxQ4& z9$UpLf%)xa5^A^!wWD{C$M*A5WDcV`o-k?${ca(T^`wzDG7vTK5Y$BDFayg_ zkzI^DR?AC~*c^Cb531wGs2#STLUtMzk#k;u5jF62)Fti3s2Vtfmp;EysBxZfpGEaw z;;z9#MS>VMU}g^FAh z;nYTwP~)YeHj<06`u@j}=nj=vOh*ko8`WU}GM3e#ew`ao?YE#V*KX8A&8YTYqZZnU zI^%0ze+Shsj@>9SX&5XcF_Oe&+~xj&YM8-|8jHhGmuoIBwO@eEB`)@ z2A`w+_yb|2BCJCF3UDGmj>TAyitI5|`!f;ZuiyA#gTu>_izmrHikdJwGyDwW+*H(# zvQQJ`qK;+~D%7)3kz0srw+dDNlIORg+U>&Qcqkxojl_y9E*j2#&}nNy^H0;!*(}v%-YC5nac&F{~+Re25+Kv+L{+$-ge~p?Fw>gb_W&tAZ1i| ziLy~Eo$C2=Odwx_`XPD+S&O~l<&Ew!Bv{sgeen-efjoQ*oFQqNc5o8&iQmcIYA zF=4|ZB#Jf7Y;lDb=k^M3!9I+?bWCV?f3FVx7o{& zq5l7|b`qN4XXKt)AGW1mtUS~Jg{Xn2dA=02;BwC|_WWAUzlz$xHq`i^U<$V4Bs`Ca zm|95uRWY=X$*>sJVF_x&I*h`4&%cJ6coVAM9@Jeq?Dg%aAC|MIh(vKN+CV&xz(L5| zR)U(RZanelOS3H$=xm!%9lm$3xLv3P{e!w>y(WalB0;l6?2eFIiW=u>cOGitOTE6< z-B?LNJ88hra4%|QGm63v3sD2rpxSLf?d)w#!uL@FH+lVWw-YB*e!ZzV?r4wrs--oH kRxhursb05eP1Dl8GY6-ZR4-qc`M=`KWh+$Il2;J_FZ|*zPyhe` delta 3044 zcmYM#e@xX?7{~EP;fg3+`~hfSB9xE=5xs>ZDd-F{C!whe%QhE(XhowI=$z}uQ2T|c zrPHCcOiNpvSjaLbWw?H55xJH`I?Kw+NewYJGiAL$+-J*OzOQr6_xyUEbMCdVrl&f5 zZbbApnQcJ$Z7W(O!Jq85zBcGQ4QjKaTA5%&1|KGenrGn?8+q9RH|Es(`S@AFaf&2;CX z`Y%R4wwy;i>su8Cb$kXD(eud1w((GA_M!$JLPd5A`PjES*o*z_cBA_Dq51`>D6n)? zzYyvOW}-H@5X1c0G9Dwb64kL5HESmVVwW!qAqxx+{o&6iAGyK5oZOF%db$e0o2eBJv zb_{AiyBl0HliZk>GcC%KZ+XIj(qG#9*X2LY6E?!g%TK?ikYa) z&O*(%goiS*(p?>*0kSIslDb#(@6mYQ5i`=Z72)X zuK<FzkH9QB3|e1+ffVdM@4i9HNMqtM`i9TDv(R4 z`Tj;N93ag);slJ-_dkV#USy#ro{SnW9T{V#s9)s@)IyJZi<8fS%T{t(K&W)##pTUJAqQkfd6K^%E!?{15{3_C&xsl7e4>>LS7?twxktEth)CR+W zNs)$BjHh8LD)PILJy@BySG#pc5^M`5;CrZyed2!Mwxbp}?e#89pnk=T%IhB&wviOH z!xZFLEQA`k5H(;0rsHZ_eU5aex0gYQq#AHYIm)-*Wn1> zZ${0(2gBSi`;vlwsV<`?xQ2>2hHzC6qIR6>^=z*fc>Nw!0EuI z|3L1a_2rX)4VXAJvS2X|q&~;%_o5bFfSPbQ>aMKv_nT2aDBDpP`4qL`cFe)E$XXW5 zd1;+uv)5jlbXE?!qG4-)}lGv?Z!(SHj%1 Krt7((xc>lQ;vb&? diff --git a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po index 62bf609..8e9e46d 100644 --- a/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/jp/LC_MESSAGES/katrain.po @@ -129,10 +129,6 @@ msgstr "一局全体を再分析中(各{visits}手)" msgid "pass-button-text" msgstr "パス" -msgid "teaching undo message" -msgstr "" -"待った。{move}は{points_lost:.1f}目損です(マウスカーソルをこの手にかざせばとがめる手順が表示されます)。打ち直してください。" - msgid "ai-ponder" msgstr "この印はエンジンの状態をシンプルに表します(緑=空き、オレンジ=処理中)。エンジンが止まったり起動できなかったりすると赤くなります。" @@ -670,3 +666,12 @@ msgstr "損失目数を候補手上に表示" #. - resign the game msgid "resign" msgstr "投了" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" + +#. TODO - updated +msgid "teaching undo message" +msgstr "" +"待った。{move}は{points_lost:.1f}目損です(マウスカーソルをこの手にかざせばとがめる手順が表示されます)。打ち直してください。" diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo index b637b58912b41421e721f51c7ce3203a70648690..4bbfd006a57cde5a6e90d959f36e8f059d734fcb 100644 GIT binary patch delta 3111 zcmYk-3rv<(9LMqhtEjyoB1oW;T*S-^U|vxUlxY<+*cXDj#ke9k$~x&8m=d0sjy-&^Io z7#6VI`1djYAK?G30jimOAM~G*6i-vXAAiSC?8V_2JlITK$D-;}Fbto<7%Xu08XQV} z3l73vIK<3nO%y_CIOaN>a<*e2?blEf-oaq>a*M!7q{)&n05eb;5f8yk*lk4Hr`3At<WqY_OGe=MZzd}X!19I7K+}NA_=~QR+AHq%jqEUfO zM)i9Fbp*Mn4K79>|7{sJrQ~HChV`fc`%n|KpceebwVy{V(1~2u!%fczF}vC$P~*m< z7R=zL1#?jS@?HJ;p`5=WUP*%@tik)R&ULIuEwBrf;=`zZ$5HRV*QkyE?CRafWr3_N zqfpNiP#Kgc^4nxoiNP6i6g$;W4O% zQZWj1P?;@7F01CIOl$}hfoooK&9+kR7P6e^NXm7Z=zn(fy}Cjqqynwn}nKY zmh)NE_%de&j-XzR3c%MuL7&fF9Eb-{3mkSGPN8<%hFb8lYrlu=!GdX2YGa)fPywW% zGBO>tp}FpP0V=bl{^vehO+gc_Lv?IGZD=2A=Lb<|*n(QV#~TId+6 z|4GzF+fZkG-97&sH7bDr`azZ&C#w z#7vCk_jW8ULM>d2aoB*P@F-^Bd7O=5QRJVpEhLO&ting|0J2%@MAouiRLa8n3ssEK zScvN|$-^HdT%_mG{xhybMOcezxC1v}D{4cFV>mWkA4C528$UnR|HmR9zocG{dTCPW zt;iomo#9+m3iDih5%M8eB`RaDy7mTCzkR3xkDvlLi~6kF@I&nMQRt!2Fq%!^rg(nO z@e;;)*zp*%r?KZjv%9pdUergRK9@{Xg!3>Ci%}8Oq9WRY$+*L{pT%J6?as@n zOx|(zd#)ZdsV}oW3-cE&9@R0$)iY3MpM#pP1bGdt0`)a)M)lu=itr%nC|gk*ZbLWQ5)()4ZMYVX?js-KP=V% zE{wvV)W@Nory*aM<)XfVm8h?v1~ae`mBH3j@*hf}gNAw7jhZNnFtzXk)C5JS4Xi*d zT!mq{7Q=CyYkwbgbj_&#H{A1Em`>e0&Fpc^LakFfjr`B1@CFThf!2X~y93Cd3_)#h zBx*wms8psqGjSpH8K?z!I`=vcq2@V)8vmKApLX>Ng%p&UF5HS9wyy!(Py=?NGH?iW zB*#%1ID;B@0oAV?Bhf>c%E$;T$E5V;<3XSFA6&S!vZQ=@Vdaw5B^Av}Lp;$D*-Mre i$NsN5cG-(O+r2c=>%DsPgR38HxUqeIbNSSp{r?5*zdus| delta 3057 zcmYM#drX#P7{~ETIcbO}Aetw@3@pMR6i;blh*OJ{$ZC0Pq)=ikuv}|Bv8CBS-6$tB z+cNEd<)L1t*?`os8f?j2Lub0uO8Y}*=2Xlj_5Jl;Tki4s+~>n}-_Og=wdbpYpAsUs z8vnlL|49CKM=5949Q(gRNw$z5f?YTmFX1q}jXah-Ae)bMrGjy58XZRMrN>_&BLLhbAb^4Jf&Sd0DQUO~0*MYS79MjJ~*waY~v zK|X4M#TfA4mhei%3RJ@yRL3pIShmy451SSr{~melH}^WKKAP1ivLjLb z(%tE(@k<61f6`X!6)&SAunD!(_dLJP^UbJ^oycQ9^U_ZKL@l5fHBmgBM_@WCva?X* zE#jp}l)LK!66*LCYKIM|knKiAWWU#cg&MdWbve(W2ELB^4EvMOIAh#gRR03^QM{A< zBGd*dQD05)28n1A>roTbd4pZ3m4;9g9`o{3$ei{&DzvxUNE&Ga15ptfj#^L#s@-H% zWM_H(0%V-PmXJ`xO4N#KP%GbnI>Rlf0X{;t+wb`!sEImI6Q4pJ`_;XP+E^Te=%|uV zcPSk;-gt~-erU>=Do5{1}`+EElY>RwDl4Lk#D@iE+kXRr!4aHD46ElkHL{N8Hf z<(P(*I11}=8Xmy8*o{1vH-h-*l32)gCgXZ!an_2=VO^-mT*gwoi7Rjkf2qdzG5ZFW zsh(MM#zmvUJ6w)a$gjmZ+>ct&gDGamaVhGjJu8*?Yb80UoF6`dx-{{$*3OerXPAKs zVYZh~M=rhdZs<1-4=jRt96t9w$+D7w3Y_nAV3CkLC9n zPu$I4Jj%yr@P~u^=yBn8)%TdqCclbv>ZX2gCVww*`+ebsWoMbu)Cy2XP=TDT)nY2{ z@_f)ng1PK0DujK;hX+W+H1Zj!mCr@(qy%+jOTD}vQFkQS3n7odc)^eTS*og^KVE)Oho< z!y8_Sx_?$nLYL(e)aP*?6|x)1y|JX6@MoEe1j!!48CZdH@N?9J*Kj8GeIPu+!#JCK z8LECC>TWc9zFjiEog$%~UqFt}dQm&hB+hx5k6Oq&cN;1a2i+Fb*VBfY=r$@cu@n3< zqau@xe5sa&I@&oHaBr-fL?UiQ4bX_1;1KH4w4%=bB;Fc+C`+0c-r)q) z?a#+)xEN!x0SDu5T!05B5`PU8!!|YXFjR=rQ47dLO*|D7umF?rNv~gxI=U*)@Adj7 zoJx5+=40ff@PZ3*uKFV%p6#4O{I#Pt3S=j0g+HPe)Qt+|Ew>jJlkZEswZLWWO1Ah($ diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po index a127532..fa63bf0 100644 --- a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po @@ -546,6 +546,7 @@ msgstr "" "`threshold`선 밑의 수를 더 많이 뽑은 후 그 중 최선의 수를 둡니다. `line_weight`을 증가시키면 바둑판 중앙에 있는" " 수를 더욱 꺼리게 됩니다. 판이 `endgame` 비율만큼 차면 평범하게 둡니다." +#. TODO: updated msgid "teaching undo message" msgstr "" "{points_lost:.1f}집 손해이므로 {move}을/를 물렀습니다. 커서를 올려 상대의 대응책을 보십시오. 다시 두어 주세요." @@ -648,3 +649,7 @@ msgstr "돌 위에 집 손해 표시하기" #. TODO - resign the game msgid "resign" msgstr "기권함" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" diff --git a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.mo index 9133fed04b500a42e75bb5d660abd5a0c5002e5f..6c4daa3e7f0b9a85752879f61a4a769def029364 100644 GIT binary patch delta 3098 zcmYk;3rv+|9LMp$AQ}h=CZLi>Kp}5PBB*)EBPeR1WuwqiCn<`kIF)o3dP*%COEGV= znOd%}Y2+rlg%?)NW#T25*``fxnPjQiG|Eb)8u3D8b;$^*a;)T&D1mnl~2bGn2X(Tn#-@iDDrP& zTil6}W&ztxqCEw5uE7cCMGT|-25P|HFakq)#9|y$Wc{!;4n-}{k81x6cELH=5mzG< z+FPi0AGG8HX7wbrqth6QS5O^(#9;gzwZkBKt3DF7uuiD*?x-E5As-vWL-jeR_7k1Y zq1qQAA6v*Hg8A)b5^A^>wWBS_$KL0m$m~aTJcioYS>$6^d9XIS<5Xj{kL00tKGeqg zquOPoj$k5cfzM-rKby}(Az6+O;s#WQU8n&Lpe8)-%D+ZU@ICUe-+8FMEu*VE7S*p8 zYQmvBG+`d9U4hHbisJmWx zm+`3jzNiRiq59=HXG9Z!P4FTGe5}${yp4)LEow)fy8Krz{~fAd6Y{YT8fhbOsEK=^ zCd$Nk%tJ-C82MN^4@IIX;1b(W9cxfKtVe~c0Tq$+uKqG=;M=H6+J;dza6Avaerc$2 z#yTgX`jP!3oq#FQ6v8?#i2yHCP0N3T=Y3H);bJ zsEGJc3mWh0r=cQS?9~Ts2?-6f3e|8kYC*eDEB_F6h6hj+okX=e@A8ePiGD#%+>CrI zlupuz+SmZpQ4K-er92Gf{#iZ=b)1G8sHCOBY$ro5c?aGg!`kg`T=pw5B zb!QVQazTVs8;M4Z*9EnaJ{YF=Ka)gDs9eQ()W8L(4l|IktPJ(-T#0JG4t2S)u7DwR)9F9IJ3vmig!TNaOuQQ3~muE7jVlGx-8lFQR26y$|h9q3C zcDM#V!FjFBCeY|r@`t*yXdIbfmWaieg_Zadp2j5nn9Aw+O(OBvcls8ph$YQMyIad4Gl}8RXW3!fmI+6k` z$LTJA344=oL~S7YQSVNqB1M*uJ8%sS)cc>xb_*z&i7eg@<5PGSiKgWY+h2iQ$e+SO`~h``#y!S{ncpUn(0e);bv7@dA9o;Q z*|(?#bREHBa2EE*8swDh3MvvYelNs698EqAJL3ze`YKd}w_rT(LES$)PC^6S#4Jo2 z>78W}b|b$WHNZAh$79z~t?7nq1wQS~7VqI@ED#BAiA+9XtjD^MG*&m#T_B+gJU z8E<1x9GC50Kh%nsp+fcs>Q`|qCSf&l(d`84b!|pn=GLRU_7hMMn2KBljDA4RO~_eHeu4&P<$3elRLR?_n&~pcZ@#)&HFH2C7}~ z7;n7r=_GW<33wByqE`I)SZ{?hQAe{Hbr}z$LVpW&8UMs&OlI5KKrSj`Yj766Q(M>W rNN{-Jyt1N2rG;g4mJ}_no!5SLa%|3=(wPbWD^8fdKy_bc-0S!+nJ_|` delta 3046 zcmYM#drX&A9LMpmH;}lh2>CdTU@S+9F>~o3))OuAGR%dS zn6+hIDs8Ft({7VuZkf2b-^|KfH%U!P*NDZmFxLCybGF=%=XK6=&U4QBe$ROx*Kg}{ zYHJ_wr@{TV8~;A#Z#aL~2dHLtEb@O7DYjA{ir?TMyoPt;zsS!LqWpR~4yHa4Q*f@U zuf#a&4H%Bi7-QzyP71Ny*zY=g;yi_SaQ}PMfWKli{*4J3PKBb4!2XzxTHqK|{}~v- z3XI3q$b_~L)vx7t-7`B#K@qiL1cp!#oX39n2P(oY*WQa-*g!_p{UNA`Qcx3Qa#4F8 zYP_k=QdIwi$j_>|L^HqDQ&7j}P!VlFezu*9GP4);;1N`0ZOG5ga$zm@i?b8ezZcan zhKd49L-or=ZNXI30?X0k&nmeL!8%mO2GoOFkg@DdcmFVI;Lnhso#CSP4tKv3^;|z@ z(L_VJXrc^Mzp<`fhzhhcj{R3;k8)!m*0_#!s0r4gQrm>;w+*%TyHI=hk*l9Zes;;( zjcN~LHOlO8)N>imNvQE39z^~rTa9aY29<%$s7POP^@FZ{4E10L`Pt806v>~c1@xjO zisj)X%s^$f2sPd!F3Lo$bFD`~53WZ=*n&#gUQ|X7x%Q7y1Gl3N=LOWj-Kf_vf{MmT zcjls=FLpkJ!>BJp1yGNAYrN+vgi&ZjP0-{z>_M$Gh??-YyMGRu)2^UW`;W6fofJR} zDkA~Zf-+J4@==*Ba_wcvIG$BfP{(@IiW*QWe+jjRTTlb+L-jl4>TRfrPN60~hy3iK z^Cl{=Xa><%#iPzr25P( zsLcI<3gjAUyuVNr4f25}PJ#A?i=(-Le!ZAo_$`LCc5&i_26SdI7LdpH7rM5XE$He+}) zuO{xq6@ARI=+sDkdkXuCNvVA8un3E=27kx5F&&#}tiq$HPkTZ-`Ol#cptUap&O#lU zIV1g)EkH$7g-UfTGPkXD?m&XGBdD_yLZ$eMYrlnh?E-iC?c*>=eGX1zKJ!NLRl{PI zzmgm0aShJQ;^TvDqs>ZiNj4`N_ugZ+3OBIow7zCNq-#0#60H;YS>l6cZ(td+7VE@EFq5eB^!|Gk%DM3&l0}P{Ncyn=HE<*9FdoJiFob#= z$_vb%#x@*^<2dR%^|LX6Td*1rpw3RzWdHR{!dU7#IFk8oGKE51ii~A@Pz$(#GjQ}2 zz6n^5?1t?|MgAQs#T_^uyHHz~U+A}&BPq7Un1m~lb7z}S;~YY-h{9zGiI_FjPkkY3 zf-2O5wWvL9MD2Amrr}$t_LHuD3FE1UF{s|EBvi_0qatp=RD1<1@Pi`qpG6^Rntyo4 zqgGsiO4&Tr`~MiGV=Z#PtqFD5+EAzYOH}_s_1I0~<#B8VY;WvmRJz{i8_k*)oLug6x73dW7U G5&s`3I5o@w diff --git a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po index 82a6d39..112da9f 100644 --- a/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ru/LC_MESSAGES/katrain.po @@ -117,6 +117,7 @@ msgstr "Дополнительный анализ всех ходов-канди msgid "pass-button-text" msgstr "Пас" +#. TODO - updated msgid "teaching undo message" msgstr "" "Ход {move} отменён, т.к. это потеря {points_lost:.1f} очков. Наведите на " @@ -676,3 +677,7 @@ msgstr "Показывать потерянные очки текстом" #. TODO - resign the game msgid "resign" msgstr "Resign" + +#. TODO - Analyze again but exclude all currently considered moves +msgid "analysis:alternatives" +msgstr "Find alternative moves" diff --git a/katrain/img/Alternative.png b/katrain/img/Alternative.png new file mode 100644 index 0000000000000000000000000000000000000000..5f23ca22cec8ac3dd38368d220c1ea7990df68f6 GIT binary patch literal 4384 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 literal 0 HcmV?d00001