ais and bugs
This commit is contained in:
1 parent
d70515235a
commit
97dc12df10
15 files changed
+241
-76
No files matched your search
+10
-23
@@ -87,7 +87,7 @@ class KaTrainGui(Screen, KaTrainSettings):
|
||||
self.controls.set_status(f"KataGo engine ready.")
|
||||
if "ready" in message.lower():
|
||||
self.controls.set_status(f"KataGo engine ready.")
|
||||
if level == OUTPUT_ERROR or (level == OUTPUT_KATAGO_STDERR and "error" in message.lower()):
|
||||
if (level == OUTPUT_ERROR or (level == OUTPUT_KATAGO_STDERR and "error" in message.lower())) and getattr(self, "controls", None):
|
||||
self.controls.set_status(f"ERROR: {message}")
|
||||
|
||||
@property
|
||||
@@ -109,17 +109,12 @@ class KaTrainGui(Screen, KaTrainSettings):
|
||||
def update_state(self, redraw_board=False): # is called after every message and on receiving analyses and config changes
|
||||
# AI and Trainer/auto-undo handlers
|
||||
cn = self.game.current_node
|
||||
last_player, next_player = self.game.players[cn.player], self.game.players[cn.next_player]
|
||||
if self.play_analyze_mode == MODE_PLAY:
|
||||
teaching_undo = cn.player and self.game.players[cn.player].being_taught
|
||||
teaching_undo = cn.player and last_player.being_taught
|
||||
if teaching_undo and cn.analysis_ready and cn.parent and cn.parent.analysis_ready and not cn.children and not self.game.ended:
|
||||
self.game.analyze_undo(cn) # not via message loop
|
||||
if (
|
||||
cn.analysis_ready
|
||||
and "ai" in self.controls.player_mode(cn.next_player).lower()
|
||||
and not cn.children
|
||||
and not self.game.ended
|
||||
and not (teaching_undo and cn.auto_undo is None)
|
||||
):
|
||||
if cn.analysis_ready and next_player.ai and not cn.children and not self.game.ended and not (teaching_undo and cn.auto_undo is None):
|
||||
self._do_ai_move(cn) # cn mismatch stops this if undo fired. avoid message loop here or fires repeatedly.
|
||||
|
||||
# Handle prisoners and next player display
|
||||
@@ -174,26 +169,23 @@ class KaTrainGui(Screen, KaTrainSettings):
|
||||
if self.game:
|
||||
self.message_queue.put([self.game.game_id, message, *args])
|
||||
|
||||
def update_players(self):
|
||||
for player in "BW":
|
||||
self.controls.players[player].player_type = self.game.players[player].player_type
|
||||
self.game.players[player].player_subtype = self.game.players[player].player_subtype
|
||||
|
||||
def _do_new_game(self, move_tree=None, analyze_fast=False):
|
||||
self.board_gui.animating_pv = None
|
||||
self.engine.on_new_game() # clear queries
|
||||
self.game = Game(self, self.engine, move_tree=move_tree, analyze_fast=analyze_fast)
|
||||
for bw, player_widget in self.nav_drawer_contents.player_setup.players.items():
|
||||
self.game.players[bw].update(**player_widget.player_def)
|
||||
self.controls.graph.initialize_from_game(self.game.root)
|
||||
self.controls.periods_used = {"B": 0, "W": 0}
|
||||
self.update_state(redraw_board=True)
|
||||
self.update_players()
|
||||
|
||||
def _do_ai_move(self, node=None):
|
||||
if node is None or self.game.current_node == node:
|
||||
mode = self.controls.ai_mode(self.game.current_node.next_player)
|
||||
mode = self.game.next_player.strategy
|
||||
settings = self.config(f"ai/{mode}")
|
||||
if settings:
|
||||
ai_move(self.game, mode, settings)
|
||||
else:
|
||||
self.log(f"AI Mode {mode} not found!", OUTPUT_ERROR)
|
||||
|
||||
def _do_undo(self, n_times=1):
|
||||
if n_times == "smart":
|
||||
@@ -287,12 +279,7 @@ class KaTrainGui(Screen, KaTrainSettings):
|
||||
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("sgf/sgf_save"),
|
||||
trainer_config=self.config("trainer"),
|
||||
save_feedback=self.config("sgf/save_feedback"),
|
||||
eval_thresholds=self.config("trainer/eval_thresholds"),
|
||||
)
|
||||
msg = self.game.write_sgf(self.config("general/sgf_save"))
|
||||
self.log(msg, OUTPUT_INFO)
|
||||
self.controls.set_status(msg)
|
||||
|
||||
|
||||
+11
-23
@@ -20,15 +20,15 @@
|
||||
"sgf_load": "~/Downloads",
|
||||
"sgf_save": "./sgfout",
|
||||
"anim_pv_time": 0.5,
|
||||
"debug_level": 3,
|
||||
"debug_level": 1,
|
||||
"language": "en"
|
||||
},
|
||||
"game": {
|
||||
"size": "13",
|
||||
"komi": 0.5,
|
||||
"handicap": 2,
|
||||
"rules": "chinese",
|
||||
"clear_cache": true
|
||||
"size": "19",
|
||||
"komi": 6.5,
|
||||
"handicap": 0,
|
||||
"rules": "japanese",
|
||||
"clear_cache": false
|
||||
},
|
||||
"trainer": {
|
||||
"num_undo_prompts": [
|
||||
@@ -60,32 +60,20 @@
|
||||
"lock_ai": false
|
||||
},
|
||||
"ai": {
|
||||
"Default": {
|
||||
"default": {
|
||||
"_help_right": "No settings available for Default KataGo AI, strength is mainly affected by `max_visits` and `model` in the main settings `engine` section.",
|
||||
"_help_left": ""
|
||||
},
|
||||
"Balance": {
|
||||
"target_score": 2,
|
||||
"random_loss": 1,
|
||||
"max_loss": 5,
|
||||
"min_visits": 20,
|
||||
"_help_left": "Will try to win by `target_score`, lose at most `random_loss` when behind and `max_loss` when ahead.",
|
||||
"_help_right": "Never plays moves with less than `min_visits` visits, so also check engine settings."
|
||||
},
|
||||
"Jigo": {
|
||||
"jigo": {
|
||||
"target_score": 0.5,
|
||||
"_help_left": "Will try to win by `target_score`, without further restrictions.",
|
||||
"_help_right": "Also affected by engine settings such as `max_visits`."
|
||||
},
|
||||
"ScoreLoss": {
|
||||
"strength": 0.5,
|
||||
"_help_left": "Plays moves weighted inversely by point loss.",
|
||||
"_help_right": "Also affected by engine settings such as `max_visits`, likely to play more varied/weaker with higher visits."
|
||||
"scoreloss": {
|
||||
"strength": 0.5
|
||||
},
|
||||
"Policy": {
|
||||
"opening_moves": 0.05,
|
||||
"_help_left": "Strength is mainly affected by `model` in engine settings, but should be high dan regardless.",
|
||||
"_help_right": "Plays the P:Weighted strategy during the first `opening_moves` * <number of intersections> moves to allow variety."
|
||||
"opening_moves": 20
|
||||
},
|
||||
"P:Weighted": {
|
||||
"_help_right": "pick_override` determines when top move is chosen without randomness, and `lower_bound` determines the lower bound policy value that is allowed.",
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
|
||||
policy_grid = var_to_grid(cn.policy, size) # type: List[List[float]]
|
||||
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 "policy" in ai_mode and cn.depth <= int(ai_settings["opening_moves"] * (game.board_size[0] * game.board_size[1])):
|
||||
if "policy" in ai_mode and cn.depth <= ai_settings["opening_moves"]:
|
||||
ai_mode = "p: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}
|
||||
@@ -151,7 +151,7 @@ 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:
|
||||
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
|
||||
|
||||
@@ -5,3 +5,4 @@ PLAYING_NORMAL, PLAYING_TEACHING = "game:normal", "game:teach"
|
||||
GAME_TYPES = [PLAYING_NORMAL, PLAYING_TEACHING]
|
||||
|
||||
AI_DEFAULT = "default"
|
||||
AI_STRATEGIES = [AI_DEFAULT]
|
||||
+16
-5
@@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Union
|
||||
from typing import Dict, List, Union, Optional
|
||||
|
||||
from katrain.core.utils import var_to_grid, OUTPUT_INFO, OUTPUT_DEBUG, i18n
|
||||
from katrain.core.engine import KataGoEngine
|
||||
@@ -23,9 +23,12 @@ class KaTrainSGF(SGF):
|
||||
class Player:
|
||||
def __init__(self, player="B", player_type=PLAYER_HUMAN, player_subtype=PLAYING_NORMAL, periods_used=0):
|
||||
self.player = player
|
||||
self.update(player_type, player_subtype)
|
||||
self.periods_used = periods_used
|
||||
|
||||
def update(self, player_type, player_subtype):
|
||||
self.player_type = player_type
|
||||
self.player_subtype = player_subtype
|
||||
self.periods_used = periods_used
|
||||
|
||||
@property
|
||||
def ai(self):
|
||||
@@ -39,6 +42,7 @@ class Player:
|
||||
def being_taught(self):
|
||||
return self.player_type == PLAYER_HUMAN and self.player_subtype == PLAYING_TEACHING
|
||||
|
||||
@property
|
||||
def strategy(self):
|
||||
return self.player_subtype if self.ai else AI_DEFAULT
|
||||
|
||||
@@ -275,7 +279,14 @@ class Game:
|
||||
def __repr__(self):
|
||||
return "\n".join("".join(self.chains[c][0].player if c >= 0 else "-" for c in line) for line in self.board) + f"\ncaptures: {self.prisoner_count}"
|
||||
|
||||
def write_sgf(self, path=None, trainer_config={}, save_feedback=(True,), eval_thresholds=(0,)):
|
||||
def write_sgf(self, path: str, trainer_config: Optional[Dict] = None, save_feedback: Optional[List] = None, eval_thresholds: Optional[List] = None):
|
||||
if trainer_config is None:
|
||||
trainer_config = self.katrain.config("trainer")
|
||||
if save_feedback is None:
|
||||
save_feedback = self.katrain.config("trainer/save_feedback")
|
||||
if eval_thresholds is None:
|
||||
eval_thresholds = self.katrain.config("trainer/eval_thresholds")
|
||||
|
||||
black, white = self.root.get_property("PB"), self.root.get_property("PW")
|
||||
black = re.sub(r"['<>:\"/\\|?*]", "", black or "Black")
|
||||
white = re.sub(r"['<>:\"/\\|?*]", "", white or "White")
|
||||
@@ -283,11 +294,11 @@ class Game:
|
||||
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 = {p: trainer_config.get("eval_show_ai", True) or "ai" not in self.katrain.controls.player_mode(p) for p in Move.PLAYERS}
|
||||
show_dots_for = {bw: trainer_config.get("eval_show_ai", True) or pl.human for bw, pl in self.players.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)
|
||||
return f"SGF with analysis written to {file_name}"
|
||||
return i18n._("sgf written").format(file_name=file_name)
|
||||
|
||||
def analyze_extra(self, mode):
|
||||
stones = {s.coords for s in self.stones}
|
||||
|
||||
@@ -32,7 +32,7 @@ class KaTrainSettings:
|
||||
|
||||
def log(self, message, level=OUTPUT_INFO):
|
||||
if level == OUTPUT_ERROR:
|
||||
print(f"ERROR: {message}", sys.stderr)
|
||||
print(f"ERROR: {message}", file=sys.stderr)
|
||||
elif self.debug_level >= level:
|
||||
print(message)
|
||||
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import os
|
||||
import sys
|
||||
from typing import Any, List, Tuple, Callable
|
||||
|
||||
from kivy.event import EventDispatcher
|
||||
from numbers import Number
|
||||
from typing import List, Tuple, Callable
|
||||
from kivy.lang import Observable
|
||||
import gettext
|
||||
|
||||
from kivy.properties import StringProperty
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.textinput import TextInput
|
||||
from kivymd.uix.label import MDIcon
|
||||
from kivymd.uix.textfield import MDTextField
|
||||
|
||||
from katrain.gui.style import DEFAULT_FONT
|
||||
|
||||
@@ -27,7 +23,7 @@ OUTPUT_EXTRA_DEBUG = 2
|
||||
MODE_PLAY, MODE_ANALYZE = "play", "analyze"
|
||||
|
||||
|
||||
def var_to_grid(array_var: List[Any], size: Tuple[int, int]) -> List[List[Any]]:
|
||||
def var_to_grid(array_var: List[Number], size: Tuple[int, int]) -> List[List[Number]]:
|
||||
"""convert ownership/policy to grid format such that grid[y][x] is for move with coords x,y"""
|
||||
ix = 0
|
||||
grid = [[]] * size[1]
|
||||
@@ -103,6 +99,9 @@ class Lang(Observable):
|
||||
try:
|
||||
func(args[0], None, None)
|
||||
widget.font_name = self.font_name
|
||||
for sub_widget in [getattr(widget, "_hint_lbl", None), getattr(widget, "_msg_lbl", None)]: # MDText
|
||||
if sub_widget:
|
||||
sub_widget.font_name = self.font_name
|
||||
except ReferenceError:
|
||||
pass # proxy no longer exists
|
||||
for cb in self.callbacks:
|
||||
|
||||
+31
-12
@@ -29,6 +29,7 @@
|
||||
#:set GREEN [0.1,0.8,0.1,1]
|
||||
#:set LIGHTBLUE [0.3,0.7,0.9,1]
|
||||
#:set YELLOW [0.8,0.8,0.1,1]
|
||||
#:set DARKRED [0.3,0.1,0.1,1]
|
||||
|
||||
|
||||
#:set SCORE_COLOR LIGHTBLUE
|
||||
@@ -691,28 +692,39 @@
|
||||
on_option_state:
|
||||
info.size_hint_y = int(args[1]['info'])+1e-9
|
||||
info.opacity = int(args[1]['info'])
|
||||
note.size_hint_y = int(args[1]['notes'])+1e-9
|
||||
note.opacity = int(args[1]['notes'])
|
||||
notebox.size_hint_y = int(args[1]['notes'])*0.66+1e-9
|
||||
notebox.opacity = int(args[1]['notes'])
|
||||
options_height: root.tab_option_height
|
||||
MDBoxLayout:
|
||||
BGMDBoxLayout:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
orientation: 'vertical'
|
||||
ScrollableLabel:
|
||||
id: status
|
||||
size_hint: 1, None
|
||||
height: min(self.parent.height*0.66,self.label.texture_size[1])
|
||||
outline_color: RED
|
||||
background_color: DARKRED
|
||||
ScrollableLabel:
|
||||
id: info
|
||||
markup: True
|
||||
on_ref_press: root.katrain.board_gui.show_pv_from_comments(args[1])
|
||||
size_hint: 1, 1
|
||||
height: self.parent.height - status.height - note.height - 1
|
||||
TextInput:
|
||||
id: note
|
||||
font_size: NOTES_FONT_SIZE
|
||||
size_hint: 1, 1
|
||||
on_text: root.katrain.set_note(self.text)
|
||||
hint_text: i18n._('SGF Notes Hint')
|
||||
AnchorLayout:
|
||||
padding: 0
|
||||
id: notebox
|
||||
size_hint: 1,0
|
||||
MDTextField:
|
||||
id: note
|
||||
font_size: NOTES_FONT_SIZE
|
||||
multiline: True
|
||||
on_text: root.katrain.set_note(self.text)
|
||||
hint_text: i18n._('SGF Notes Hint')
|
||||
color_mode: 'custom'
|
||||
line_color_focus: TEXT_COLOR
|
||||
size_hint: 1, 1
|
||||
# mode: "rectangle"
|
||||
# width: info.width - dp(26)
|
||||
Label:
|
||||
size_hint_y: 1e-9 # takes up remaining space if info is closed
|
||||
|
||||
@@ -891,19 +903,24 @@
|
||||
spacing: 3*CP_SPACING
|
||||
padding: CP_PADDING
|
||||
height: (self.parent.item_height or 50) * 5
|
||||
players: {'B':black,'W':white}
|
||||
PlayerSetup:
|
||||
player: 'B'
|
||||
id: black
|
||||
PlayerSetup:
|
||||
player: 'W'
|
||||
id: white
|
||||
|
||||
<ContentNavigationDrawer@MDBoxLayout+BackgroundMixin>:
|
||||
<HamburgerMenuContents@MDBoxLayout+BackgroundMixin>:
|
||||
katrain: app.gui
|
||||
player_setup: player_setup
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
orientation: 'vertical'
|
||||
item_height: self.height/20
|
||||
MenuLabel:
|
||||
text: i18n._('menu:playersetup')
|
||||
PlayerSetupBlock:
|
||||
id: player_setup
|
||||
MenuLabel:
|
||||
size_hint: 1,1
|
||||
MenuLabel:
|
||||
@@ -988,10 +1005,10 @@
|
||||
PlayAnalyzeButton:
|
||||
text: i18n._('btn:Play')
|
||||
id: play
|
||||
state: 'down'
|
||||
PlayAnalyzeButton:
|
||||
text: i18n._('btn:Analysis')
|
||||
id: analyze
|
||||
state: 'down'
|
||||
|
||||
<KaTrainGui>:
|
||||
board_gui: board_gui
|
||||
@@ -1000,6 +1017,7 @@
|
||||
play_mode: play_mode
|
||||
analysis_controls: analysis_controls
|
||||
nav_drawer: nav_drawer
|
||||
nav_drawer_contents: nav_drawer_contents
|
||||
zen: False
|
||||
NavigationLayout:
|
||||
ScreenManager:
|
||||
@@ -1039,7 +1057,8 @@
|
||||
width: self.height * 0.5
|
||||
height: root.height - analysis_controls.height
|
||||
swipe_edge_width: 0
|
||||
ContentNavigationDrawer:
|
||||
HamburgerMenuContents:
|
||||
id: nav_drawer_contents
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -239,12 +239,15 @@ class PlayerSetup(MDBoxLayout):
|
||||
self.player_subtype.text = self.player_subtype.values[0]
|
||||
self.set_player()
|
||||
|
||||
@property
|
||||
def player_def(self):
|
||||
return {"player_type": self.player_type.selected[1], "player_subtype": self.player_subtype.selected[1]}
|
||||
|
||||
def set_player(self):
|
||||
katrain = MDApp.get_running_app().gui
|
||||
game = katrain and katrain.game
|
||||
if game:
|
||||
game.players[self.player].player_type = self.player_type.selected[1]
|
||||
game.players[self.player].player_subtype = self.player_subtype.selected[1]
|
||||
game.players[self.player].update(**self.player_def)
|
||||
katrain.controls.update_players()
|
||||
katrain.update_state()
|
||||
|
||||
|
||||
Binary file not shown.
@@ -279,6 +279,9 @@ msgid "new game"
|
||||
msgstr "Start New Game"
|
||||
|
||||
#. misc errors and info messages
|
||||
msgid "sgf written"
|
||||
msgstr "SGF with analysis written to {file_name}"
|
||||
|
||||
msgid "wait-before-equalize"
|
||||
msgstr "Wait for initial analysis to complete before requesting a refinement."
|
||||
|
||||
@@ -309,3 +312,51 @@ msgid "Engine died unexpectedly"
|
||||
msgstr ""
|
||||
"Engine died unexpectedly without sending output, possibly due to out of "
|
||||
"memory: {e}"
|
||||
|
||||
#. AI names, help etc
|
||||
msgid "strength:kyu"
|
||||
msgstr "k"
|
||||
|
||||
msgid "strength:dan"
|
||||
msgstr "d"
|
||||
|
||||
msgid "ainame:default"
|
||||
msgstr "KataGo"
|
||||
|
||||
msgid "aihelp:default"
|
||||
msgstr ""
|
||||
"Full strength KataGo AI. Strength is mainly affected by `max_visits` and "
|
||||
"`model` in the general settings `engine` section."
|
||||
|
||||
msgid "ainame:jigo"
|
||||
msgstr "KataJigo"
|
||||
|
||||
msgid "aihelp:jigo"
|
||||
msgstr ""
|
||||
"Will try to win by a set amount of points (default 0.5), without further "
|
||||
"restrictions."
|
||||
|
||||
msgid "ainame:jigo"
|
||||
msgstr "KataJigo"
|
||||
|
||||
msgid "aihelp:jigo"
|
||||
msgstr ""
|
||||
"Will try to win by a set amount of points (default 0.5), without further "
|
||||
"restrictions."
|
||||
|
||||
msgid "ainame:scoreloss"
|
||||
msgstr "Score Loss"
|
||||
|
||||
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."
|
||||
|
||||
msgid "ainame:policy"
|
||||
msgstr "Policy"
|
||||
|
||||
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."
|
||||
Binary file not shown.
@@ -345,3 +345,56 @@ 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"
|
||||
Binary file not shown.
@@ -377,3 +377,56 @@ 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"
|
||||
Reference in new issue
Block a user