This commit is contained in:
Sander Land committed 2020-04-27 11:06:43 +02:00
1 parent b188f233f2
commit 1b36710eda
8 files changed
+129 -26

No files matched your search

+3 -1
View File
@@ -58,7 +58,9 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
weighted_coords = [(policy_grid[y][x], policy_grid[y][x], x, y) for x in range(size[0]) for y in range(size[1]) if policy_grid[y][x] > 0] weighted_coords = [(policy_grid[y][x], policy_grid[y][x], x, y) for x in range(size[0]) for y in range(size[1]) if policy_grid[y][x] > 0]
best = weighted_selection_without_replacement(weighted_coords, 1)[0] best = weighted_selection_without_replacement(weighted_coords, 1)[0]
aimove = Move(best[2:], player=cn.next_player) # just take a random move by policy w/o noise aimove = Move(best[2:], player=cn.next_player) # just take a random move by policy w/o noise
ai_thoughts += f"Playing policy-weighted random move {aimove.gtp()} ({best[0]:.1%})" + (" because one of them is pass." if top_5_pass else " because strategy is weighted.") ai_thoughts += f"Playing policy-weighted random move {aimove.gtp()} ({best[0]:.1%})" + (
" because one of them is pass." if top_5_pass else " because strategy is weighted."
)
elif "noise" in ai_mode: elif "noise" in ai_mode:
noise_str = ai_settings["noise_strength"] noise_str = ai_settings["noise_strength"]
d_noise = dirichlet_noise(len(legal_policy_moves)) d_noise = dirichlet_noise(len(legal_policy_moves))
+1 -1
View File
@@ -66,7 +66,7 @@ while not game.ended:
logger.log(f"Setting komi {game.root.properties}", OUTPUT_ERROR) logger.log(f"Setting komi {game.root.properties}", OUTPUT_ERROR)
elif "genmove" in line: elif "genmove" in line:
game.current_node.analyze(engine) game.current_node.analyze(engine)
game.root.add_property(f"P{game.current_node.next_player}", f"KaTrain {ai_strategy}") game.root.properties[f"P{game.current_node.next_player}"] = [f"KaTrain {ai_strategy}"]
move, node = ai_move(game, ai_strategy, ai_settings) move, node = ai_move(game, ai_strategy, ai_settings)
logger.log(f"SENT TO GTP: = {move.gtp()}", OUTPUT_ERROR) logger.log(f"SENT TO GTP: = {move.gtp()}", OUTPUT_ERROR)
print(f"= {move.gtp()}\n") print(f"= {move.gtp()}\n")
+9 -7
View File
@@ -25,6 +25,7 @@
1, 1,
1, 1,
0.5, 0.5,
0,
0 0
], ],
"eval_thresholds": [ "eval_thresholds": [
@@ -32,7 +33,8 @@
6, 6,
3, 3,
1.5, 1.5,
0.5 0.5,
0
], ],
"eval_off_show_last": 3, "eval_off_show_last": 3,
"eval_show_ai": false "eval_show_ai": false
@@ -112,32 +114,32 @@
[ [
0.447, 0.447,
0.129, 0.129,
0.42 0.42,1
], ],
[ [
0.8, 0.8,
0, 0,
0 0,1
], ],
[ [
0.9, 0.9,
0.4, 0.4,
0.1 0.1,1
], ],
[ [
0.85, 0.85,
0.89, 0.89,
0.3 0.3,1
], ],
[ [
0.67, 0.67,
0.9, 0.9,
0.18 0.18,1
], ],
[ [
0.117, 0.117,
0.588, 0.588,
0 0,1
] ]
], ],
"line_color": [ "line_color": [
+7 -1
View File
@@ -3,7 +3,7 @@ from kivy.graphics.vertex_instructions import Line, SmoothLine
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup from kivy.uix.popup import Popup
from gui.popups import ConfigAIPopup from gui.popups import ConfigAIPopup, ConfigTeacherPopup
class Controls(BoxLayout): class Controls(BoxLayout):
@@ -79,3 +79,9 @@ class Controls(BoxLayout):
popup_contents = ConfigAIPopup(self.katrain, config_popup, {self.ai_mode("B"), self.ai_mode("W")}) popup_contents = ConfigAIPopup(self.katrain, config_popup, {self.ai_mode("B"), self.ai_mode("W")})
config_popup.add_widget(popup_contents) config_popup.add_widget(popup_contents)
config_popup.open() config_popup.open()
def configure_teacher(self):
config_popup = Popup(title="Edit Teacher Settings", size_hint=(0.6, 0.8))
popup_contents = ConfigTeacherPopup(self.katrain, config_popup)
config_popup.add_widget(popup_contents)
config_popup.open()
+9
View File
@@ -15,6 +15,7 @@ from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.uix.spinner import Spinner from kivy.uix.spinner import Spinner
from kivy.uix.textinput import TextInput from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
class DarkLabel(Label): class DarkLabel(Label):
@@ -29,6 +30,14 @@ class LightHelpLabel(ScaledLightLabel):
pass pass
class BackgroundColor(Widget):
background = ListProperty([1, 1, 1, 0])
class BackgroundLabel(Label, BackgroundColor):
pass
class StyledButton(Button): class StyledButton(Button):
button_color = ListProperty([]) button_color = ListProperty([])
button_color_down = ListProperty([]) button_color_down = ListProperty([])
+82 -5
View File
@@ -9,15 +9,16 @@ from common import OUTPUT_DEBUG, OUTPUT_ERROR
from engine import KataGoEngine from engine import KataGoEngine
from game import Game, GameNode from game import Game, GameNode
from gui.kivyutils import ( from gui.kivyutils import (
BackgroundLabel,
LabelledCheckBox, LabelledCheckBox,
LabelledFloatInput, LabelledFloatInput,
LabelledIntInput, LabelledIntInput,
LabelledObjectInputArea, LabelledObjectInputArea,
LabelledSpinner, LabelledSpinner,
LabelledTextInput, LabelledTextInput,
LightHelpLabel,
ScaledLightLabel, ScaledLightLabel,
StyledButton, StyledButton,
LightHelpLabel,
) )
@@ -171,15 +172,15 @@ class ConfigPopup(QuickConfigGui):
class ConfigAIPopup(QuickConfigGui): class ConfigAIPopup(QuickConfigGui):
def __init__(self, katrain, popup, ai_modes, **kwargs): def __init__(self, katrain, popup, ai_modes, **kwargs):
super().__init__(katrain, popup, katrain.ai_settings, **kwargs) self.settings = self.katrain.config("ai")
self.settings = self.katrain.ai_settings super().__init__(katrain, popup, self.settings, **kwargs)
self.ai_modes = ai_modes self.ai_modes = ai_modes
Clock.schedule_once(self._build, 0) Clock.schedule_once(self._build, 0)
self.orientation = "vertical" self.orientation = "vertical"
def _build(self, _dt): def _build(self, _dt):
colbox = BoxLayout(spacing=5) colbox = BoxLayout(spacing=5)
for mode in self.ai_modes: for i, mode in enumerate(self.ai_modes):
mode_settings = self.settings[mode] mode_settings = self.settings[mode]
num_rows = len(mode_settings) - 2 num_rows = len(mode_settings) - 2
column = GridLayout(cols=2, rows=max(num_rows, 4) + 3, spacing=1, padding=3) column = GridLayout(cols=2, rows=max(num_rows, 4) + 3, spacing=1, padding=3)
@@ -195,9 +196,14 @@ class ConfigAIPopup(QuickConfigGui):
column.add_widget(ScaledLightLabel(text=f"")) column.add_widget(ScaledLightLabel(text=f""))
column.add_widget(ScaledLightLabel(text=f"")) column.add_widget(ScaledLightLabel(text=f""))
colbox.add_widget(column) colbox.add_widget(column)
if i == 0:
colbox.add_widget(BackgroundLabel(text=f"", size_hint=(0.02, 1), background=(1, 1, 1, 1)))
if len(self.ai_modes) == 1: if len(self.ai_modes) == 1:
colbox.add_widget(ScaledLightLabel(text=f"")) colbox.add_widget(ScaledLightLabel(text=f""))
self.info_label = Label()
bl = BoxLayout(size_hint=(1, 0.2), spacing=2) bl = BoxLayout(size_hint=(1, 0.2), spacing=2)
bl.add_widget(self.info_label)
bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False))) bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False)))
bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True))) bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
self.add_widget(colbox) self.add_widget(colbox)
@@ -207,10 +213,81 @@ class ConfigAIPopup(QuickConfigGui):
try: try:
for k, v in self.collect_properties(self).items(): for k, v in self.collect_properties(self).items():
k1, k2 = k.split("/") k1, k2 = k.split("/")
print(k1, k2, v, self.settings[k1][k2]) self.settings[k1][k2] = v
if self.settings[k1][k2] != v: if self.settings[k1][k2] != v:
self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG) self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG)
if save_to_file:
self.katrain.save_config()
self.popup.dismiss()
except InputParseError as e:
self.info_label.text = str(e)
self.katrain.log(e, OUTPUT_ERROR)
return
self.popup.dismiss()
class ConfigTeacherPopup(QuickConfigGui):
def __init__(self, katrain, popup, **kwargs):
self.settings = katrain.config("trainer")
self.ui_settings = katrain.config("board_ui")
super().__init__(katrain, popup, self.settings, **kwargs)
Clock.schedule_once(self._build, 0)
self.orientation = "vertical"
self.spacing = 2
def _build(self, _dt):
thresholds = self.settings["eval_thresholds"]
undos = self.settings["num_undo_prompts"]
colors = self.ui_settings["eval_colors"]
thrbox = GridLayout(spacing=1, padding=2, cols=4, rows=len(thresholds) + 1)
thrbox.add_widget(ScaledLightLabel(text="Point loss greater than", bold=True))
thrbox.add_widget(ScaledLightLabel(text="Gives this many undos", bold=True))
thrbox.add_widget(ScaledLightLabel(text="Color (fixed)", bold=True))
thrbox.add_widget(ScaledLightLabel(text="Visibility (0=hidden)", bold=True))
for i, (thr, undos, color) in enumerate(zip(thresholds, undos, colors)):
thrbox.add_widget(LabelledFloatInput(text=str(thr), input_property=f"threshold::{i}"))
thrbox.add_widget(LabelledFloatInput(text=str(undos), input_property=f"undo::{i}"))
thrbox.add_widget(BackgroundLabel(background=color[:3]))
thrbox.add_widget(LabelledFloatInput(text=str(color[3]), input_property=f"alpha::{i}"))
self.add_widget(thrbox)
xsettings = BoxLayout(size_hint=(1, 0.15), spacing=2)
xsettings.add_widget(ScaledLightLabel(text="Show last <n> dots"))
xsettings.add_widget(LabelledIntInput(size_hint=(0.5,1), text=str(self.settings['eval_off_show_last']),input_property = "eval_off_show_last" ))
self.add_widget(xsettings)
xsettings = BoxLayout(size_hint=(1, 0.15), spacing=2)
xsettings.add_widget(ScaledLightLabel(text="Show dots for AI players"))
xsettings.add_widget(LabelledCheckBox(size_hint=(0.5,1), text=str(self.settings['eval_show_ai']),input_property = "eval_show_ai" ))
self.add_widget(xsettings)
bl = BoxLayout(size_hint=(1, 0.2), spacing=2)
bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False)))
bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
self.add_widget(bl)
def update_config(self, save_to_file=False):
try:
for k, v in self.collect_properties(self).items():
if '::' in k:
k1, i = k.split("::")
i=int(i)
if 'alpha' not in k1:
if self.settings[k1][i] != v:
self.settings[k1][i] = v
self.katrain.log(f"Updating setting {k1}[{i}] = {v}", OUTPUT_DEBUG)
else:
if self.ui_settings['eval_colors'][i][3] != v:
self.katrain.log(f"Updating alpha {i} = {v}", OUTPUT_DEBUG)
self.ui_settings['eval_colors'][i][3] = v
else:
if self.settings[k] != v:
self.settings[k] = v
self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG)
if save_to_file:
pass
self.popup.dismiss() self.popup.dismiss()
except InputParseError as e: except InputParseError as e:
self.info_label.text = str(e) self.info_label.text = str(e)
+15 -7
View File
@@ -11,6 +11,16 @@
#:set WHITE [0.95,0.95,0.95,1] #:set WHITE [0.95,0.95,0.95,1]
#:set GREY [0.5,0.5,0.5,1] #:set GREY [0.5,0.5,0.5,1]
<BackgroundColor>:
canvas.before:
Color:
rgb: root.background
Rectangle:
pos: self.pos
size: self.size
<StyledButton>: <StyledButton>:
color: WHITE color: WHITE
font_size: self.size[1] * 0.45 font_size: self.size[1] * 0.45
@@ -475,17 +485,15 @@
on_text: if W_player_mode.children: W_player_mode.children[0].trigger_action(duration=0) on_text: if W_player_mode.children: W_player_mode.children[0].trigger_action(duration=0)
BoxLayout: BoxLayout:
size_hint: 1,0.05 size_hint: 1,0.05
padding: 1 padding: 5,0
spacing: 1 spacing: 1
Label: StyledButton:
size_hint: 0.55,1 text: 'Configure Teacher'
on_press: root.configure_teacher()
size_hint: 1.33, 1
StyledButton: StyledButton:
text: 'Configure AIs' text: 'Configure AIs'
on_press: root.configure_ais() on_press: root.configure_ais()
size_hint: 0.44,1
Label:
size_hint: None,1
width: 3
LargeLabel: LargeLabel:
text: '' text: ''
size_hint: 1,0.2 size_hint: 1,0.2
+3 -4
View File
@@ -38,8 +38,7 @@ class KaTrainGui(BoxLayout):
self._load_config() self._load_config()
self.debug_level = self.config("debug/level", OUTPUT_INFO) self.debug_level = self.config("debug/level", OUTPUT_INFO)
self.ai_settings = self.config("ai") self.controls.ai_mode_groups["W"].values = self.controls.ai_mode_groups["B"].values = self.config("ai").keys()
self.controls.ai_mode_groups["W"].values = self.controls.ai_mode_groups["B"].values = self.ai_settings.keys()
self.message_queue = Queue() self.message_queue = Queue()
self._keyboard = Window.request_keyboard(None, self, "") self._keyboard = Window.request_keyboard(None, self, "")
@@ -145,7 +144,7 @@ class KaTrainGui(BoxLayout):
def _do_ai_move(self, node=None): def _do_ai_move(self, node=None):
if node is None or self.game.current_node == node: if node is None or self.game.current_node == node:
mode = self.controls.ai_mode(self.game.current_node.next_player) mode = self.controls.ai_mode(self.game.current_node.next_player)
settings = self.ai_settings[mode] settings = self.config("ai/mode")
if settings: if settings:
ai_move(self.game, mode, settings) ai_move(self.game, mode, settings)
@@ -193,7 +192,7 @@ class KaTrainGui(BoxLayout):
def _do_config_popup(self): def _do_config_popup(self):
config_popup = Popup(title="Edit Settings", size_hint=(0.9, 0.9)) config_popup = Popup(title="Edit Settings", size_hint=(0.9, 0.9))
popup_contents = ConfigPopup(self, config_popup, dict(self._config), ignore_cats=("board_ui", "ai")) popup_contents = ConfigPopup(self, config_popup, dict(self._config), ignore_cats=("trainer", "ai"))
config_popup.add_widget(popup_contents) config_popup.add_widget(popup_contents)
config_popup.open() config_popup.open()