nearly ready!
This commit is contained in:
1 parent
48f6166d48
commit
42b1df2015
18 files changed
+63
-786
No files matched your search
@@ -1,10 +1,10 @@
|
||||
# KaTrain v1.0.6
|
||||
# KaTrain v1.1
|
||||
[](https://github.com/sanderland/katrain/releases)
|
||||
[](https://pypi.org/project/katrain)
|
||||

|
||||

|
||||
[](#Installation)
|
||||
[](https://github.com/psf/black)
|
||||

|
||||
[](https://pepy.tech/project/katrain)
|
||||
[](https://discord.com/channels/417022162348802048/629446365688365067)
|
||||
|
||||
KaTrain is a tool for analyzing and playing go with AI feedback from KataGo.
|
||||
@@ -24,19 +24,11 @@ but has since grown to include a wide range of features, including:
|
||||
| ------------- | ------------- |
|
||||
|  |  |
|
||||
|
||||
## Quickstart
|
||||
|
||||
* You can right-click most button or checkbox labels to get a tooltip with help.
|
||||
* To analyze a game, load it using the button in the bottom right, or press `ctrl-L`
|
||||
* To play against AI, pick an AI from the dropdown and either 'human' or 'teach' for yourself and start playing.
|
||||
* For different board sizes, use the button with the little goban in the bottom right for a new game.
|
||||
|
||||
|
||||
# Documentation
|
||||
|
||||
## Installation
|
||||
* See the [releases tab](https://github.com/sanderland/katrain/releases) for pre-built installers for windows.
|
||||
* Alternatively use `pip3 install -U katrain` to install the latest version from PyPI on any OS.
|
||||
* Alternatively use `pip3 install -U katrain` to install the latest version from PyPI on any 64-bit OS.
|
||||
* Note that on MacOS you will need to set up KataGo using brew, as described [here](INSTALL.md).
|
||||
* See [here](INSTALL.md#MacPrereq) for detailed instructions for running from source files on Window, Linux and MacOS,
|
||||
as well as setting up KataGo to use multiple GPUs.
|
||||
@@ -44,37 +36,27 @@ but has since grown to include a wide range of features, including:
|
||||
## Manual
|
||||
|
||||
### Play
|
||||
* Select the players in the main menu, or under 'New Game'.
|
||||
* In a teaching game, KaTrain will analyze your moves and automatically undo those that are sufficiently bad.
|
||||
|
||||
Under the 'play' tab you can select who is playing black and white.
|
||||
#### Instant feedback while playing.
|
||||
|
||||
* Human is simple play with potential feedback, but without auto-undo.
|
||||
* Teach will give you instant feedback, and auto-undo bad moves to give you a second chance.
|
||||
* Settings for this mode can be found under 'Configure Teacher'
|
||||
* AI will activate the AI in the dropdown menu next to the buttons.
|
||||
* Settings for all AIs can be found under 'Configure AIs'
|
||||
|
||||
If you do not want to see 'Points lost' or other feedback for your moves,
|
||||
set 'show last n dots' to 0 under 'Configure Teacher', and click on the words 'Points lost' to hide its value.
|
||||
|
||||
#### What are all these coloured dots?
|
||||
|
||||
The dots indicate how many points were lost by that move.
|
||||
The dots on the move indicate how many points were lost by that move.
|
||||
|
||||
* The colour indicates the size of the mistake according to KataGo
|
||||
* The size indicates if the mistake was actually punished. Going from fully punished at maximal size,
|
||||
to no actual effect on the score at minimal size.
|
||||
|
||||
In short, if you are a weaker player you should mostly on large dots that are red or purple,
|
||||
while stronger players can pay more attention to smaller mistakes. If you want to hide some colours, you
|
||||
can do so under 'Configure Teacher'.
|
||||
while stronger players can pay more attention to smaller mistakes. If you want to hide some colours
|
||||
on the board or not output details for them in SGFs,you can do so under 'Configure Teacher'.
|
||||
|
||||
#### AIs
|
||||
|
||||
Available AIs, with strength indicating an estimate for the default settings based on their current OGS rankings, are:
|
||||
|
||||
* **[9p+]** **Default** is full KataGo, above professional level.
|
||||
* **(RECOMMENDED)** **[~5k]** **ScoreLoss** is KataGo making moves with probability `~ e^(-strength * points lost)`, playing a varied style with small mistakes.
|
||||
* **Balance** is KataGo occasionally making weaker moves, attempting to win by ~2 points. It can still win by more if you make too many mistakes.
|
||||
* **[9p+]** **KataGo** is full KataGo, above professional level.
|
||||
* <font color="#336699">**[~5k]** **ScoreLoss**</font> is KataGo making moves with probability `~ e^(-strength * points lost)`, playing a varied style with small mistakes.
|
||||
* **Jigo** is KataGo aggressively making weaker moves, attempting to win by 0.5 points.
|
||||
* **[~4d]** **Policy** uses the top move from the policy network (it's 'shape sense' without reading), should be around high dan level depending on the model used. There is a setting to increase variety in the opening, but otherwise it plays deterministically.
|
||||
* **(RECOMMENDED)** **[~3k]**: **P:Weighted** picks a random move weighted by the policy,
|
||||
@@ -175,5 +157,3 @@ In addition to shortcuts mentioned above, there are:
|
||||
* You can also 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 give feedback, or simply show your appreciation.
|
||||
* Some people have also asked me how to donate. Something go-related such as a book or teaching time is highly appreciated.
|
||||
|
||||

|
||||
[](https://pepy.tech/project/katrain)
|
||||
@@ -9,6 +9,7 @@ locales = set(os.listdir(localedir))
|
||||
print("locales found:", locales)
|
||||
|
||||
strings_to_langs = defaultdict(dict)
|
||||
strings_to_keys = defaultdict(dict)
|
||||
lang_to_strings = defaultdict(set)
|
||||
|
||||
DEFAULT_LANG = "en"
|
||||
@@ -27,12 +28,19 @@ for lang in locales:
|
||||
num_todo[lang] += 1
|
||||
else:
|
||||
strings_to_langs[entry.msgid][lang] = entry.msgstr
|
||||
strings_to_keys[entry.msgid][lang] = set(re.findall("{.*?}",entry.msgstr))
|
||||
lang_to_strings[lang].add(entry.msgid)
|
||||
if num_todo[lang]:
|
||||
print(f"{lang} has {num_todo[lang]} TODO entries")
|
||||
|
||||
|
||||
for lang in locales:
|
||||
if lang != DEFAULT_LANG:
|
||||
for msgid in lang_to_strings[lang]:
|
||||
if DEFAULT_LANG in strings_to_keys[msgid] and strings_to_keys[msgid][lang] != strings_to_keys[msgid][DEFAULT_LANG]:
|
||||
print(f"{msgid} has inconstent formatting keys for {lang}: ",strings_to_keys[msgid][lang],'is different from default', strings_to_keys[msgid][DEFAULT_LANG])
|
||||
errors=True
|
||||
|
||||
for msgid in strings_to_langs.keys() - lang_to_strings[lang]:
|
||||
if lang == DEFAULT_LANG:
|
||||
print("Message id", msgid, "found as ", strings_to_langs[msgid], "but missing in default", DEFAULT_LANG)
|
||||
|
||||
+7
-13
@@ -265,12 +265,6 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
self.fileselect_popup.open()
|
||||
|
||||
def _do_output_sgf(self):
|
||||
for pl in Move.PLAYERS:
|
||||
if not self.game.root.get_property(f"P{pl}"):
|
||||
_, model_file = os.path.split(self.engine.config["model"])
|
||||
self.game.root.set_property(
|
||||
f"P{pl}", f"AI {self.controls.ai_mode(pl)} (KataGo { os.path.splitext(model_file)[0]})" if "ai" in self.controls.player_mode(pl) else "Player"
|
||||
)
|
||||
msg = self.game.write_sgf(self.config("general/sgf_save"))
|
||||
self.log(msg, OUTPUT_INFO)
|
||||
self.controls.set_status(msg)
|
||||
@@ -330,13 +324,7 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
first_child.dismiss()
|
||||
|
||||
shortcuts = self.shortcuts
|
||||
if keycode[1] in shortcuts.keys():
|
||||
shortcut = shortcuts[keycode[1]]
|
||||
if isinstance(shortcut, Widget):
|
||||
shortcut.trigger_action(duration=0)
|
||||
else:
|
||||
self(*shortcut)
|
||||
elif keycode[1] == "tab":
|
||||
if keycode[1] == "tab":
|
||||
self.play_mode.switch_mode()
|
||||
elif keycode[1] == "shift":
|
||||
self.nav_drawer.set_state("toggle")
|
||||
@@ -361,6 +349,12 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
self.controls.set_status(i18n._("Copied SGF to clipboard."))
|
||||
elif keycode[1] == "v" and "ctrl" in modifiers:
|
||||
self.load_sgf_from_clipboard()
|
||||
elif keycode[1] in shortcuts.keys() and "ctrl" not in modifiers:
|
||||
shortcut = shortcuts[keycode[1]]
|
||||
if isinstance(shortcut, Widget):
|
||||
shortcut.trigger_action(duration=0)
|
||||
else:
|
||||
self(*shortcut)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@
|
||||
true
|
||||
],
|
||||
"eval_off_show_last": 3,
|
||||
"eval_show_ai": true,
|
||||
"eval_show_ai": false,
|
||||
"lock_ai": true
|
||||
},
|
||||
"ai": {
|
||||
|
||||
+6
-31
@@ -5,7 +5,7 @@ import time
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
from katrain.core.utils import var_to_grid
|
||||
from katrain.core.constants import OUTPUT_INFO, OUTPUT_DEBUG, AI_STRATEGIES_POLICY, AI_POLICY, AI_WEIGHTED
|
||||
from katrain.core.constants import OUTPUT_INFO, OUTPUT_DEBUG, AI_STRATEGIES_POLICY, AI_POLICY, AI_WEIGHTED, AI_STRATEGIES_PICK, AI_JIGO, AI_SCORELOSS, AI_DEFAULT
|
||||
from katrain.core.engine import EngineDiedException
|
||||
from katrain.core.game import Game, GameNode, Move
|
||||
|
||||
@@ -44,7 +44,7 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
|
||||
top_policy_move = policy_moves[0][1]
|
||||
ai_thoughts += f"Using policy based strategy, base top 5 moves are {fmt_moves(policy_moves[:5])}. "
|
||||
if ai_mode == AI_POLICY and cn.depth <= ai_settings["opening_moves"]:
|
||||
ai_mode = "p:weighted"
|
||||
ai_mode = AI_WEIGHTED
|
||||
ai_thoughts += f"Switching to weighted strategy in the opening {int(ai_settings['opening_moves'] * (game.board_size[0]*game.board_size[1]))} moves. "
|
||||
ai_settings = {"pick_override": 0.9, "weaken_fac": 1, "lower_bound": 0.02}
|
||||
if top_5_pass:
|
||||
@@ -77,21 +77,7 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
|
||||
ai_thoughts += f"Playing policy-weighted random move {aimove.gtp()} ({policy_value:.1%})" + (
|
||||
" because no other moves were found." if not top else f" because strategy is weighted (lower bound={lower_bound:.2%}, num moves > lb={len(weighted_coords)})."
|
||||
)
|
||||
elif "noise" in ai_mode: # DEPRECATED
|
||||
noise_str = ai_settings["noise_strength"]
|
||||
lower_bound = max(0, ai_settings["lower_bound"])
|
||||
selected_policy_moves = [(pol, mv) for pol, mv in policy_moves if not mv.is_pass if pol > lower_bound]
|
||||
d_noise = dirichlet_noise(len(selected_policy_moves))
|
||||
noisy_policy_moves = [(((1 - noise_str) * pol + noise_str * noise), mv) for ((pol, mv), noise) in zip(selected_policy_moves, d_noise)]
|
||||
new_top = heapq.nlargest(5, noisy_policy_moves)
|
||||
ai_thoughts += f"Noisy policy strategy (strength={noise_str:.2f}) generated 5 moves {fmt_moves(new_top)} "
|
||||
aimove = new_top[0][1]
|
||||
if new_top[0][0] < pass_policy:
|
||||
ai_thoughts += f", but found pass ({pass_policy:.2%} to be higher rated than {aimove.gtp()} ({new_top[0][0]:.2%}) so will play top policy move instead."
|
||||
aimove = top_policy_move
|
||||
else:
|
||||
ai_thoughts += f" so picked {aimove.gtp()} ({policy_grid[aimove.coords[1]][aimove.coords[0]]:.2%})."
|
||||
elif "p:" in ai_mode:
|
||||
elif ai_mode in AI_STRATEGIES_PICK:
|
||||
legal_policy_moves = [(pol, mv) for pol, mv in policy_moves if not mv.is_pass if pol > 0]
|
||||
n_moves = int(ai_settings["pick_frac"] * len(legal_policy_moves) + ai_settings["pick_n"])
|
||||
if "influence" in ai_mode or "territory" in ai_mode:
|
||||
@@ -151,30 +137,19 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
|
||||
aimove = top_cand
|
||||
ai_thoughts += f"Top move is pass, so passing regardless of strategy."
|
||||
else:
|
||||
if "balance" in ai_mode: # deprecated
|
||||
sign = cn.player_sign(cn.next_player)
|
||||
sel_moves = [ # top move, or anything not too bad, or anything that makes you still ahead
|
||||
move
|
||||
for i, move in enumerate(candidate_ai_moves)
|
||||
if i == 0
|
||||
or move["visits"] >= ai_settings["min_visits"]
|
||||
and (move["pointsLost"] < ai_settings["random_loss"] or move["pointsLost"] < ai_settings["max_loss"] and sign * move["scoreLead"] > ai_settings["target_score"])
|
||||
]
|
||||
aimove = Move.from_gtp(random.choice(sel_moves)["move"], player=cn.next_player)
|
||||
ai_thoughts += f"Balance strategy selected moves {sel_moves} based on target score and max points lost, and randomly chose {aimove.gtp()}."
|
||||
elif "jigo" in ai_mode:
|
||||
if ai_mode == AI_JIGO:
|
||||
sign = cn.player_sign(cn.next_player)
|
||||
jigo_move = min(candidate_ai_moves, key=lambda move: abs(sign * move["scoreLead"] - ai_settings["target_score"]))
|
||||
aimove = Move.from_gtp(jigo_move["move"], player=cn.next_player)
|
||||
ai_thoughts += f"Jigo strategy found {len(candidate_ai_moves)} candidate moves (best {top_cand.gtp()}) and chose {aimove.gtp()} as closest to 0.5 point win"
|
||||
elif "scoreloss" in ai_mode:
|
||||
elif ai_mode == AI_SCORELOSS:
|
||||
c = ai_settings["strength"]
|
||||
moves = [(d["pointsLost"], math.exp(min(200, -c * max(0, d["pointsLost"]))), Move.from_gtp(d["move"], player=cn.next_player)) for d in candidate_ai_moves]
|
||||
topmove = weighted_selection_without_replacement(moves, 1)[0]
|
||||
aimove = topmove[2]
|
||||
ai_thoughts += f"ScoreLoss strategy found {len(candidate_ai_moves)} candidate moves (best {top_cand.gtp()}) and chose {aimove.gtp()} (weight {topmove[1]:.3f}, point loss {topmove[0]:.1f}) based on score weights."
|
||||
else:
|
||||
if "default" not in ai_mode and "katago" not in ai_mode:
|
||||
if ai_mode != AI_DEFAULT:
|
||||
game.katrain.log(f"Unknown AI mode {ai_mode} or policy missing, using default.", OUTPUT_INFO)
|
||||
ai_thoughts += f"Strategy {ai_mode} not found or unexpected fallback."
|
||||
aimove = top_cand
|
||||
|
||||
@@ -22,7 +22,8 @@ AI_TERRITORY = "ai:p:territory"
|
||||
AI_CONFIG_DEFAULT = AI_SCORELOSS
|
||||
|
||||
AI_STRATEGIES_ENGINE = [AI_DEFAULT, AI_SCORELOSS, AI_JIGO]
|
||||
AI_STRATEGIES_POLICY = [AI_WEIGHTED, AI_POLICY, AI_PICK, AI_LOCAL, AI_TENUKI, AI_INFLUENCE, AI_TERRITORY]
|
||||
AI_STRATEGIES_PICK = [AI_PICK, AI_LOCAL, AI_TENUKI, AI_INFLUENCE, AI_TERRITORY]
|
||||
AI_STRATEGIES_POLICY = [AI_WEIGHTED, AI_POLICY] + AI_STRATEGIES_PICK
|
||||
AI_STRATEGIES = AI_STRATEGIES_ENGINE + AI_STRATEGIES_POLICY
|
||||
AI_STRATEGIES_RECOMMENDED_ORDER = [AI_DEFAULT, AI_SCORELOSS, AI_WEIGHTED, AI_PICK, AI_POLICY, AI_LOCAL, AI_TENUKI, AI_TERRITORY, AI_INFLUENCE, AI_JIGO]
|
||||
|
||||
|
||||
@@ -246,12 +246,15 @@ class Game:
|
||||
if eval_thresholds is None:
|
||||
eval_thresholds = self.katrain.config("trainer/eval_thresholds")
|
||||
|
||||
player_names = {bw: re.sub(r"['<>:\"/\\|?*]", "", self.root.get_property("P" + bw) or str(self.katrain.players_info[bw])) for bw in "BW"}
|
||||
def player_name(player_info):
|
||||
return f"{i18n._(player_info.player_type)} ({i18n._(player_info.player_subtype)})"
|
||||
|
||||
player_names = {bw: re.sub(r"['<>:\"/\\|?*]", "", self.root.get_property("P" + bw) or player_name(self.katrain.players_info[bw])) for bw in "BW"}
|
||||
game_name = f"katrain_{player_names['B']} vs {player_names['W']} {self.game_id}"
|
||||
file_name = os.path.abspath(os.path.join(path, f"{game_name}.sgf"))
|
||||
os.makedirs(os.path.dirname(file_name), exist_ok=True)
|
||||
|
||||
show_dots_for = {bw: trainer_config.get("eval_show_ai", True) or pl.human for bw, pl in self.players.items()}
|
||||
show_dots_for = {bw: trainer_config.get("eval_show_ai", True) or pl.human for bw, pl in self.katrain.players_info.items()}
|
||||
sgf = self.root.sgf(save_comments_player=show_dots_for, save_comments_class=save_feedback, eval_thresholds=eval_thresholds)
|
||||
with open(file_name, "w") as f:
|
||||
f.write(sgf)
|
||||
|
||||
@@ -125,7 +125,7 @@ class GameNode(SGFNode):
|
||||
if not self.parent or not single_move: # root
|
||||
return ""
|
||||
|
||||
text = f"Move {self.depth}: {single_move.player} {single_move.gtp()}\n"
|
||||
text = f"{i18n._('move')} {self.depth}: {single_move.player} {single_move.gtp()}\n"
|
||||
if self.analysis_ready:
|
||||
score = self.score
|
||||
if sgf:
|
||||
@@ -137,7 +137,7 @@ class GameNode(SGFNode):
|
||||
if previous_top_move["move"] != single_move.gtp():
|
||||
points_lost = self.points_lost
|
||||
if sgf and points_lost > 0.5:
|
||||
text += i18n._("Info:point loss").format(points=points_lost) + "\n"
|
||||
text += i18n._("Info:point loss").format(points_lost=points_lost) + "\n"
|
||||
text += i18n._("Info:top move").format(top_move=previous_top_move["move"], score=self.format_score(previous_top_move["scoreLead"])) + "\n"
|
||||
else:
|
||||
text += i18n._("Info:best move") + "\n"
|
||||
|
||||
+8
-15
@@ -31,22 +31,18 @@
|
||||
#:set WINRATE_COLOR GREEN
|
||||
#:set GRAPH_DOT_COLOR [0.85, 0.3, 0.3,1]
|
||||
|
||||
|
||||
#:set BUTTON_INACTIVE_COLOR LIGHTGREY
|
||||
|
||||
|
||||
#:set NOTES_FONT_SIZE dp(18)
|
||||
|
||||
|
||||
|
||||
# for sizing help
|
||||
<Label>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: RED
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
#<Label>:
|
||||
# canvas.before:
|
||||
# Color:
|
||||
# rgba: RED
|
||||
# Line:
|
||||
# rectangle: (*self.pos,*self.size)
|
||||
# width: 1
|
||||
|
||||
# mixins
|
||||
<BackgroundMixin>:
|
||||
@@ -903,7 +899,7 @@
|
||||
text: i18n._('menu:save')
|
||||
icon: 'img/flaticon/floppy-disk.png'
|
||||
shortcut: 'Ctrl-S'
|
||||
on_action: root.katrain("analyze-sgf-popup")
|
||||
on_action: root.katrain("output-sgf")
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:load')
|
||||
icon: 'img/flaticon/folder.png'
|
||||
@@ -937,9 +933,6 @@
|
||||
LangButton:
|
||||
icon: 'img/flaticon/flag-uk.png'
|
||||
on_press: app.language = 'en'
|
||||
LangButton:
|
||||
icon: 'img/flaticon/flag-nl.png'
|
||||
on_press: app.language = 'nl'
|
||||
LangButton:
|
||||
icon: 'img/flaticon/flag-ko.png'
|
||||
on_press: app.language = 'ko'
|
||||
|
||||
@@ -236,7 +236,7 @@ class BadukPanWidget(Widget):
|
||||
for m in katrain.game.stones:
|
||||
has_stone[m.coords] = m.player
|
||||
|
||||
show_dots_for = {p: self.trainer_config["eval_show_ai"] or katrain.game.players[p].human for p in Move.PLAYERS}
|
||||
show_dots_for = {p: self.trainer_config["eval_show_ai"] or katrain.players_info[p].human for p in Move.PLAYERS}
|
||||
show_dots_for_class = self.trainer_config["show_dots"]
|
||||
nodes = katrain.game.current_node.nodes_from_root
|
||||
realized_points_lost = None
|
||||
|
||||
Binary file not shown.
@@ -187,6 +187,10 @@ msgstr "Win rate: {winrate}"
|
||||
msgid "Info:point loss"
|
||||
msgstr "Estimated point loss: {points_lost:.1f}"
|
||||
|
||||
#. as in 'Move 125: B5'
|
||||
msgid "move"
|
||||
msgstr "Move"
|
||||
|
||||
msgid "Info:top move"
|
||||
msgstr "Predicted top move was {top_move} ({score})."
|
||||
|
||||
|
||||
Binary file not shown.
@@ -512,3 +512,6 @@ msgstr "ㅋㅋYour SGF notes for this position here."
|
||||
|
||||
msgid "pass-button-text"
|
||||
msgstr "ㅋㅋPass"
|
||||
|
||||
msgid "move"
|
||||
msgstr "ㅋㅋMove"
|
||||
Binary file not shown.
@@ -648,3 +648,7 @@ msgstr "Manual"
|
||||
#. TODO
|
||||
msgid "ai settings"
|
||||
msgstr "Advanced AI Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "move"
|
||||
msgstr "Move"
|
||||
Binary file not shown.
@@ -1,688 +0,0 @@
|
||||
# KaTrain i18n file
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: Nederlands\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "pass-button-text"
|
||||
msgstr "Pas"
|
||||
|
||||
#. TODO
|
||||
msgid "tab:info"
|
||||
msgstr "Info"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:PV"
|
||||
msgstr "PV: {pv}"
|
||||
|
||||
#. TODO
|
||||
msgid "board-pass"
|
||||
msgstr "pass"
|
||||
|
||||
#. TODO
|
||||
msgid "closedlabel:scoregraph"
|
||||
msgstr "Score Graph"
|
||||
|
||||
#. TODO
|
||||
msgid "Starting default Kata failed"
|
||||
msgstr ""
|
||||
"Starting KataGo with command '{command}' failed with error {error}. If on "
|
||||
"MacOS, see the manual on how to use brew to install katago first, and add it"
|
||||
" to your path or 'engine/katago' setting."
|
||||
|
||||
#. TODO
|
||||
msgid "Failed to load SGF"
|
||||
msgstr "Failed to load SGF. Parse Error: {error}"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:AI thoughts"
|
||||
msgstr "AI thought process: {thoughts}"
|
||||
|
||||
#. TODO
|
||||
msgid "tab:winrate"
|
||||
msgstr "Win Rate"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:undo predicted PV"
|
||||
msgstr "Predicted follow-up: {pv}"
|
||||
|
||||
#. TODO
|
||||
msgid "tab:notes"
|
||||
msgstr "Notes"
|
||||
|
||||
#. TODO
|
||||
msgid "SGF start message"
|
||||
msgstr ""
|
||||
"Moves marked 'X' indicate the top move according to KataGo, those with a "
|
||||
"square are moves that lose less than 0.5 points"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:teaching undo"
|
||||
msgstr "Move was automatically undone in teaching mode."
|
||||
|
||||
#. TODO
|
||||
msgid "Failed to import from clipboard"
|
||||
msgstr ""
|
||||
"Failed to import game from clipboard: {error}\n"
|
||||
"Clipboard contents: {contents}..."
|
||||
|
||||
#. TODO
|
||||
msgid "Info:policy best"
|
||||
msgstr "Top policy move was {move} ({probability:.1%})."
|
||||
|
||||
#. TODO
|
||||
msgid "Info:policy rank"
|
||||
msgstr "Move was #{rank} according to policy ({probability:.2%})."
|
||||
|
||||
#. TODO
|
||||
msgid "Analyzing move..."
|
||||
msgstr "Analyzing move..."
|
||||
|
||||
#. TODO
|
||||
msgid "Copied SGF to clipboard."
|
||||
msgstr "Copied SGF to clipboard."
|
||||
|
||||
#. TODO
|
||||
msgid "Engine died unexpectedly"
|
||||
msgstr ""
|
||||
"Engine died unexpectedly without sending output, possibly due to out of "
|
||||
"memory: {e}"
|
||||
|
||||
#. TODO
|
||||
msgid "board-game-end"
|
||||
msgstr ""
|
||||
"game\n"
|
||||
"end"
|
||||
|
||||
#. TODO
|
||||
msgid "Starting Kata failed"
|
||||
msgstr ""
|
||||
"Starting kata with command '{command}' failed with error {error}. Please "
|
||||
"make sure the 'katago' value under 'engine' in settings points to the "
|
||||
"correct KataGo executable."
|
||||
|
||||
#. TODO
|
||||
msgid "closedlabel:movestats"
|
||||
msgstr "Move Stats"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:top move"
|
||||
msgstr "Predicted top move was {top_move} ({score})."
|
||||
|
||||
#. TODO
|
||||
msgid "Info:score"
|
||||
msgstr "Score: {score}"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:point loss"
|
||||
msgstr "Estimated point loss: {points_lost:.1f}"
|
||||
|
||||
#. TODO
|
||||
msgid "No analysis available"
|
||||
msgstr "No analysis available"
|
||||
|
||||
#. TODO
|
||||
msgid "tab:score"
|
||||
msgstr "Score"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:best move"
|
||||
msgstr "Move was predicted best move"
|
||||
|
||||
#. TODO
|
||||
msgid "tab:points"
|
||||
msgstr "Point Loss"
|
||||
|
||||
#. TODO
|
||||
msgid "Info:winrate"
|
||||
msgstr "Win rate: {winrate}"
|
||||
|
||||
#. TODO
|
||||
msgid "closedlabel:info¬es"
|
||||
msgstr "Move Info & Notes"
|
||||
|
||||
#. TODO
|
||||
msgid "btn:Analysis"
|
||||
msgstr "Analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "btn:Play"
|
||||
msgstr "Play"
|
||||
|
||||
#. TODO
|
||||
msgid "stats:winrate"
|
||||
msgstr "Win Rate"
|
||||
|
||||
#. TODO
|
||||
msgid "stats:pointslost"
|
||||
msgstr "Points Lost"
|
||||
|
||||
#. TODO
|
||||
msgid "stats:score"
|
||||
msgstr "Estimated Score"
|
||||
|
||||
#. TODO
|
||||
msgid "stats:pointsgained"
|
||||
msgstr "Points Gained"
|
||||
|
||||
#. TODO
|
||||
msgid "SGF Notes Hint"
|
||||
msgstr "Your SGF notes for this position here."
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:territory"
|
||||
msgstr ""
|
||||
"Expected\n"
|
||||
"Territory"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:topmoves"
|
||||
msgstr ""
|
||||
"Top\n"
|
||||
"Moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:dots"
|
||||
msgstr ""
|
||||
"Show\n"
|
||||
"Dots"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:nextmoves"
|
||||
msgstr ""
|
||||
"Next\n"
|
||||
"Moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:policy"
|
||||
msgstr ""
|
||||
"Policy\n"
|
||||
"Moves"
|
||||
|
||||
#. TODO
|
||||
msgid "ai-ponder"
|
||||
msgstr ""
|
||||
"This simply indicates the Engine status, going from green (idle) to orange "
|
||||
"(processing queries). It turns red when the engine has crashed or fails to "
|
||||
"start."
|
||||
|
||||
#. TODO
|
||||
msgid "menu:newgame"
|
||||
msgstr "New Game"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:load"
|
||||
msgstr "Load Game"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:save"
|
||||
msgstr "Save Game"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:lang"
|
||||
msgstr "Language"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:settings"
|
||||
msgstr "General Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:playersetup"
|
||||
msgstr "Player Setup"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:sweep"
|
||||
msgstr "Fast analysis of all moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:equalize"
|
||||
msgstr "Equalize visits of potential moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:aimove"
|
||||
msgstr "Force AI Move"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "undo-button-text"
|
||||
msgstr "Undo"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:support"
|
||||
msgstr "Support or Contribute"
|
||||
|
||||
#. TODO
|
||||
msgid "wait-before-equalize"
|
||||
msgstr "Wait for initial analysis to complete before requesting a refinement."
|
||||
|
||||
#. TODO
|
||||
msgid "game:teaching"
|
||||
msgstr "Teaching Game"
|
||||
|
||||
#. TODO
|
||||
msgid "aistrategy"
|
||||
msgstr "AI Strategy"
|
||||
|
||||
#. TODO
|
||||
msgid "game:normal"
|
||||
msgstr "Normal Game"
|
||||
|
||||
#. TODO
|
||||
msgid "player:human"
|
||||
msgstr "Mens"
|
||||
|
||||
#. TODO
|
||||
msgid "player:type"
|
||||
msgstr "Player"
|
||||
|
||||
#. TODO
|
||||
msgid "gametype"
|
||||
msgstr "Game Type"
|
||||
|
||||
#. TODO
|
||||
msgid "player:ai"
|
||||
msgstr "AI"
|
||||
|
||||
#. TODO
|
||||
msgid "game:teach"
|
||||
msgstr "Teaching Game"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:clocksettings"
|
||||
msgstr "Timer Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:teachsettings"
|
||||
msgstr "Teaching Game Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:aisettings"
|
||||
msgstr "AI Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "timer settings"
|
||||
msgstr "Adjust Timer Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "update timer"
|
||||
msgstr "Update Timer Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "byoyomi length"
|
||||
msgstr "Time per Byo-yomi Period"
|
||||
|
||||
#. TODO
|
||||
msgid "byoyomi periods"
|
||||
msgstr "Number of Periods"
|
||||
|
||||
#. TODO
|
||||
msgid "japanese"
|
||||
msgstr "Japanese Rules"
|
||||
|
||||
#. TODO
|
||||
msgid "aga"
|
||||
msgstr "American Go Association Rules"
|
||||
|
||||
#. TODO
|
||||
msgid "new game"
|
||||
msgstr "Start New Game"
|
||||
|
||||
#. TODO
|
||||
msgid "board size"
|
||||
msgstr "Board size"
|
||||
|
||||
#. TODO
|
||||
msgid "ruleset"
|
||||
msgstr "Rules"
|
||||
|
||||
#. TODO
|
||||
msgid "komi"
|
||||
msgstr "Komi"
|
||||
|
||||
#. TODO
|
||||
msgid "avoids replaying"
|
||||
msgstr ""
|
||||
"'avoids replaying\n"
|
||||
"identical games"
|
||||
|
||||
#. TODO
|
||||
msgid "clear cache"
|
||||
msgstr "Clear Cache"
|
||||
|
||||
#. TODO
|
||||
msgid "korean"
|
||||
msgstr "Korean Rules"
|
||||
|
||||
#. TODO
|
||||
msgid "chinese"
|
||||
msgstr "Chinese Rules"
|
||||
|
||||
#. TODO
|
||||
msgid "non square board hint"
|
||||
msgstr "Use x:y (e.g. 19:9) to play on a non-square board."
|
||||
|
||||
#. TODO
|
||||
msgid "handicap"
|
||||
msgstr "Handicap"
|
||||
|
||||
#. TODO
|
||||
msgid "handicap hint"
|
||||
msgstr "Note that handicaps above 9 are not supported on non-square boards."
|
||||
|
||||
#. TODO
|
||||
msgid "New Game title"
|
||||
msgstr "Setup New Game"
|
||||
|
||||
#. TODO
|
||||
msgid "sgf written"
|
||||
msgstr "SGF with analysis written to {file_name}"
|
||||
|
||||
#. TODO
|
||||
msgid "ainame:jigo"
|
||||
msgstr "KataJigo"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:policy"
|
||||
msgstr ""
|
||||
"Plays the top move from the policy network, without any reading. Strength is"
|
||||
" mainly affected by `model` in engine settings. The opening moves setting "
|
||||
"affects how many moves in the opening are more random."
|
||||
|
||||
#. TODO
|
||||
msgid "ainame:policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#. TODO
|
||||
msgid "ainame:scoreloss"
|
||||
msgstr "Score Loss"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:default"
|
||||
msgstr ""
|
||||
"Full strength KataGo AI. Strength is mainly affected by `max_visits` and "
|
||||
"`model` in the general settings `engine` section."
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:jigo"
|
||||
msgstr ""
|
||||
"Will try to win by a set amount of points (default 0.5), without further "
|
||||
"restrictions."
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:scoreloss"
|
||||
msgstr ""
|
||||
"Plays moves that lead to more points lost with lower probability. Likely to "
|
||||
"play more varied/weaker with higher visits settings."
|
||||
|
||||
#. TODO
|
||||
msgid "ainame:default"
|
||||
msgstr "KataGo"
|
||||
|
||||
#. TODO
|
||||
msgid "strength:kyu"
|
||||
msgstr "k"
|
||||
|
||||
#. TODO
|
||||
msgid "strength:dan"
|
||||
msgstr "d"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:weighted"
|
||||
msgstr ""
|
||||
"Plays moves according to policy probability, with `weaken_fac` influencing "
|
||||
"how much more likely weaker moves are played. A high negative value plays "
|
||||
"like the `Policy` AI.`pick_override` determines when top move is chosen "
|
||||
"without randomness, and `lower_bound` determines the lower bound policy "
|
||||
"value that is allowed."
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:pick"
|
||||
msgstr ""
|
||||
"Picks `pick_n + pick_frac * <number of legal moves>` at random and plays the"
|
||||
" best one. For `pick_frac=1` plays like the `Policy` AI. Plays top move if "
|
||||
"policy value is above `pick_override` to avoid obvious mistakes."
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:influence"
|
||||
msgstr "Influential Style"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:local"
|
||||
msgstr "Respond Locally"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:tenuki"
|
||||
msgstr ""
|
||||
"Picks `pick_n + pick_frac * <number of legal moves>` weighted away from the "
|
||||
"last move and plays the best one. Plays top move if policy value is above "
|
||||
"`pick_override` to avoid obvious mistakes."
|
||||
|
||||
#. TODO
|
||||
msgid "ai:scoreloss"
|
||||
msgstr "Score Loss"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:influence"
|
||||
msgstr ""
|
||||
"Picks moves biased above the `threshold` line and plays the best "
|
||||
"one.Increase `line_weight` to penalize moves near the edge more. Stops "
|
||||
"strategy after the 'endgame' fraction of the board is filled."
|
||||
|
||||
#. TODO
|
||||
msgid "ai:default"
|
||||
msgstr "KataGo"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:tenuki"
|
||||
msgstr "Tenuki Style"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:pick"
|
||||
msgstr "Blinded Policy"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:weighted"
|
||||
msgstr "Policy Weighted"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#. TODO
|
||||
msgid "ai:jigo"
|
||||
msgstr "KataJigo"
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:local"
|
||||
msgstr ""
|
||||
"Picks moves biased below the `threshold` line and plays the best "
|
||||
"one.Increase `line_weight` to penalize moves near the center more. Stops "
|
||||
"strategy after the 'endgame' fraction of the board is filled."
|
||||
|
||||
#. TODO
|
||||
msgid "aihelp:p:territory"
|
||||
msgstr ""
|
||||
"Picks moves biased below the `threshold` line and plays the best "
|
||||
"one.Increase `line_weight` to penalize moves near the center more. Stops "
|
||||
"strategy after the 'endgame' fraction of the board is filled."
|
||||
|
||||
#. TODO
|
||||
msgid "ai:p:territory"
|
||||
msgstr "Respond Locally"
|
||||
|
||||
#. TODO
|
||||
msgid "save dots"
|
||||
msgstr "Save in SGF"
|
||||
|
||||
#. TODO
|
||||
msgid "num undos"
|
||||
msgstr "Number of undos"
|
||||
|
||||
#. TODO
|
||||
msgid "teacher settings"
|
||||
msgstr "Edit Teacher Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "show dots"
|
||||
msgstr "Show dots"
|
||||
|
||||
#. TODO
|
||||
msgid "point loss threshold"
|
||||
msgstr "Point loss greater than"
|
||||
|
||||
#. TODO
|
||||
msgid "dot color"
|
||||
msgstr "Colour (fixed)"
|
||||
|
||||
#. TODO
|
||||
msgid "show ai dots"
|
||||
msgstr "Show dots/SGF comments for AI players"
|
||||
|
||||
#. TODO
|
||||
msgid "restarting engine"
|
||||
msgstr "Restarting Engine after Settings Change."
|
||||
|
||||
#. TODO
|
||||
msgid "lock ai when teaching"
|
||||
msgstr "Disable analysis while in teach mode"
|
||||
|
||||
#. TODO
|
||||
msgid "show last n dots"
|
||||
msgstr "Show dots for the last <this many> moves"
|
||||
|
||||
#. TODO
|
||||
msgid "update teacher"
|
||||
msgstr "Update Teaching Game Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:max_visits"
|
||||
msgstr "Maximum number of visits in analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "general settings"
|
||||
msgstr "General Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "update settings"
|
||||
msgstr "Update Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:max_time"
|
||||
msgstr "Maximum time for analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:fast_visits"
|
||||
msgstr "Maximum number of visits in fast analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:config"
|
||||
msgstr "Path to KataGo config file"
|
||||
|
||||
#. TODO
|
||||
msgid "general:sgf_save"
|
||||
msgstr "Path for saving SGF files"
|
||||
|
||||
#. TODO
|
||||
msgid "general:sgf_load"
|
||||
msgstr "Path for loading SGF files"
|
||||
|
||||
#. TODO
|
||||
msgid "general:debug_level"
|
||||
msgstr "Debug level in the console"
|
||||
|
||||
#. TODO
|
||||
msgid "general settings title"
|
||||
msgstr "General and Engine Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "engine settings"
|
||||
msgstr "KataGo Engine Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:model"
|
||||
msgstr "Path to KataGo model file"
|
||||
|
||||
#. TODO
|
||||
msgid "general:anim_pv_time"
|
||||
msgstr "Time between moves when animating a sequence"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:katago"
|
||||
msgstr "Path to KataGo executable"
|
||||
|
||||
#. TODO
|
||||
msgid "general:debug_level:hint"
|
||||
msgstr "Use 0 for little output, 1 for getting details when reporting errors"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:max_time:hint"
|
||||
msgstr "Time in seconds"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:time:hint"
|
||||
msgstr "Time in seconds"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:katago:hint"
|
||||
msgstr "Leave blank to use included executable"
|
||||
|
||||
#. TODO
|
||||
msgid "file not found"
|
||||
msgstr "Path does not exist"
|
||||
|
||||
#. TODO
|
||||
msgid "engine:wide_root_noise:hint"
|
||||
msgstr ""
|
||||
"Use a value of 0.02-0.1 to show more possible moves, at the cost of "
|
||||
"weakening analysis."
|
||||
|
||||
#. TODO
|
||||
msgid "engine:wide_root_noise"
|
||||
msgstr "Wide root noise (increases variety of moves considered)"
|
||||
|
||||
#. TODO
|
||||
msgid "lock ai when playing"
|
||||
msgstr ""
|
||||
"Disable analysis\n"
|
||||
" while in play mode"
|
||||
|
||||
#. TODO
|
||||
msgid "update ai settings"
|
||||
msgstr "Update AI Settings"
|
||||
|
||||
#. TODO
|
||||
msgid "Select AI"
|
||||
msgstr "Select AI strategy to configure"
|
||||
|
||||
#. TODO
|
||||
msgid "load sgf rewind"
|
||||
msgstr "Rewind to start"
|
||||
|
||||
#. TODO
|
||||
msgid "load sgf fast analysis"
|
||||
msgstr "Use fast analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "load sgf title"
|
||||
msgstr "Load SGF File to Analyze"
|
||||
|
||||
#. TODO
|
||||
msgid "btn:Analyze"
|
||||
msgstr "Analyze"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:homepage"
|
||||
msgstr "Homepage"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:manual"
|
||||
msgstr "Manual"
|
||||
|
||||
#. TODO
|
||||
msgid "ai settings"
|
||||
msgstr "Advanced AI Settings"
|
||||
Reference in new issue
Block a user