diff --git a/katrain/__main__.py b/katrain/__main__.py index 46dfaa9..a81ad72 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -1,6 +1,4 @@ from kivy.config import Config # isort:skip -from kivy.uix.screenmanager import Screen - ICON = "img/icon.png" Config.set("kivy", "window_icon", ICON) # isort:skip # set icon Config.set("input", "mouse", "mouse,multitouch_on_demand") # isort:skip # no red dots on right click @@ -20,6 +18,7 @@ from kivymd.app import MDApp from kivy.core.clipboard import Clipboard from kivy.storage.jsonstore import JsonStore from kivy.uix.popup import Popup +from kivy.uix.screenmanager import Screen from katrain.core.ai import ai_move from katrain.core.common import OUTPUT_INFO, OUTPUT_ERROR, OUTPUT_DEBUG, OUTPUT_EXTRA_DEBUG, OUTPUT_KATAGO_STDERR, find_package_resource @@ -31,11 +30,12 @@ from katrain.gui.badukpan import BadukPanWidget from katrain.gui.controlspanel import ControlsPanel from katrain.gui.popups import NewGamePopup, ConfigPopup, LoadSGFPopup -__version__ = "1.0.6" +__version__ = "1.1.0" class KaTrainGui(Screen): """Top level class responsible for tying everything together""" + zen = BooleanProperty(False) def __init__(self, **kwargs): @@ -130,8 +130,8 @@ class KaTrainGui(Screen): self.board_controls.mid_circles_container.clear_widgets() self.board_controls.mid_circles_container.add_widget(bot) self.board_controls.mid_circles_container.add_widget(top) - self.controls.players['W'].captures = prisoners["W"] - self.controls.players['B'].captures = prisoners["B"] + self.controls.players["W"].captures = prisoners["W"] + self.controls.players["B"].captures = prisoners["B"] # update engine status dot if not self.engine or not self.engine.katago_process or self.engine.katago_process.poll() is not None: @@ -305,7 +305,7 @@ class KaTrainGui(Screen): self(*shortcut) elif keycode[1] == "tab": self.controls.switch_mode() - elif keycode[1]== "spacebar": + elif keycode[1] == "spacebar": self.controls.timer.paused = not self.controls.timer.paused elif keycode[1] in ["`", "~", "m"]: self.zen = not self.zen diff --git a/katrain/gui.kv b/katrain/gui.kv index 0eacbaa..7446ea5 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -677,7 +677,7 @@ ScrollableLabel: id: status size_hint: 1, None - height: 50 #min(self.parent.height*0.66,self.label.text_size[1]) + height: min(self.parent.height*0.66,self.label.texture_size[1]) outline_color: RED ScrollableLabel: id: info @@ -716,6 +716,7 @@ : + katrain: app.gui orientation: 'vertical' button_size: (self.size[1] * 0.08 , self.size[1] * 0.04) size_hint_x: None @@ -728,6 +729,9 @@ policy: policy hints: hints ownership: ownership + analyze_extra: analyze_extra + analyze_equalize: analyze_equalize + analyze_sweep: analyze_sweep graph: {'winrate': winrate_graph,'score':score_graph,'points':points_graph} ButtonBoxHolder: size_hint_y: PLAYER_BOX_HEIGHT diff --git a/katrain/gui/badukpan.py b/katrain/gui/badukpan.py index b779219..8e6ec22 100644 --- a/katrain/gui/badukpan.py +++ b/katrain/gui/badukpan.py @@ -212,7 +212,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.controls.player_mode(p)!=PLAYER_AI for p in Move.PLAYERS} + show_dots_for = {p: self.trainer_config["eval_show_ai"] or katrain.controls.player_mode(p) != PLAYER_AI for p in Move.PLAYERS} nodes = katrain.game.current_node.nodes_from_root realized_points_lost = None for i, node in enumerate(nodes[::-1]): # reverse order! @@ -257,7 +257,13 @@ class BadukPanWidget(Widget): Rectangle(pos=(self.gridpos_x[x] - rsz / 2, self.gridpos_y[y] - rsz / 2), size=(rsz, rsz)) policy = current_node.policy - if not policy and current_node.parent and current_node.parent.policy and katrain.controls.player_mode("B")==PLAYER_AI and katrain.controls.player_mode("W")==PLAYER_AI: + if ( + not policy + and current_node.parent + and current_node.parent.policy + and katrain.controls.player_mode("B") == PLAYER_AI + and katrain.controls.player_mode("W") == PLAYER_AI + ): policy = current_node.parent.policy # in the case of AI self-play we allow the policy to be one step out of date pass_btn = katrain.board_controls.pass_btn @@ -399,13 +405,11 @@ class BadukPanControls(MDFloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.analysis_menu = None - Clock.schedule_once(self.init_menus,1) + Clock.schedule_once(self.init_menus, 1) - def init_menus(self,_dt): + def init_menus(self, _dt): menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)] - self.analysis_menu = MDDropdownMenu( - caller=self.analysis_button, items=menu_items, width_mult=4 - ) + self.analysis_menu = MDDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=4) def open_analysis_menu(self): if self.analysis_menu: diff --git a/katrain/gui/controlspanel.py b/katrain/gui/controlspanel.py index fbc996c..199feff 100644 --- a/katrain/gui/controlspanel.py +++ b/katrain/gui/controlspanel.py @@ -28,8 +28,6 @@ class ControlsPanel(BoxLayout): def check_hide_show(self, *_args): pass - - def set_status(self, msg, at_node=None): self.status_msg = msg self.status_node = at_node or self.katrain and self.katrain.game and self.katrain.game.current_node diff --git a/katrain/gui/kivyutils.py b/katrain/gui/kivyutils.py index 5322ba3..6b07430 100644 --- a/katrain/gui/kivyutils.py +++ b/katrain/gui/kivyutils.py @@ -19,7 +19,7 @@ from kivy.uix.textinput import TextInput from kivy.uix.widget import Widget -#--new +# --new from kivymd.uix.behaviors import RectangularRippleBehavior from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.button import BaseButton @@ -31,28 +31,34 @@ from kivymd.uix.navigationdrawer import MDNavigationDrawer class BackgroundColor(Widget): background_color = ListProperty([1, 1, 1, 0]) + class OutlineColor(Widget): outline_color = ListProperty([1, 1, 1, 0]) outline_width = NumericProperty(1) -class RightButtonControls(MDBoxLayout): - button_size = ListProperty([100,33]) -class SmallMDFlatButton(RectangularRippleBehavior,BaseButton,BackgroundColor,OutlineColor): +class RightButtonControls(MDBoxLayout): + button_size = ListProperty([100, 33]) + + +class SmallMDFlatButton(RectangularRippleBehavior, BaseButton, BackgroundColor, OutlineColor): text = StringProperty("") - text_color = ListProperty([1,1,1,1]) + text_color = ListProperty([1, 1, 1, 1]) color = ListProperty([1, 1, 1, 1]) font_size = NumericProperty(sp(20)) -class SmallMDFlatToggleButton(SmallMDFlatButton,ToggleButtonBehavior): + +class SmallMDFlatToggleButton(SmallMDFlatButton, ToggleButtonBehavior): @property def active(self): - return self.state=='down' + return self.state == "down" + class LightLabel(MDLabel): pass -class BackgroundLabel(MDLabel,BackgroundColor): + +class BackgroundLabel(MDLabel, BackgroundColor): pass @@ -73,7 +79,7 @@ class ScoreGraph(BackgroundLabel): def __init__(self, **kwargs): super().__init__(**kwargs) - self.bind(pos=self.update_graph,size=self.update_graph) + self.bind(pos=self.update_graph, size=self.update_graph) def initialize_from_game(self, root): self.nodes = [root] @@ -94,11 +100,9 @@ class ScoreGraph(BackgroundLabel): xscale = self.width / max(len(values) - 1, 15) available_height = self.height - line_points = [ - [self.pos[0] + i * xscale, self.pos[1] + self.height / 2 + available_height / 2 * (val / self.y_scale)] for i, val in enumerate(values) - ] + line_points = [[self.pos[0] + i * xscale, self.pos[1] + self.height / 2 + available_height / 2 * (val / self.y_scale)] for i, val in enumerate(values)] self.score_points = sum(line_points, []) - self.winrate_points = self.score_points # TODO + self.winrate_points = self.score_points # TODO if self.highlighted_index is not None: self.highlighted_index = min(self.highlighted_index, len(values) - 1) @@ -158,20 +162,21 @@ class ToolTipBehavior(object): self.tooltip.text = self.tooltip_text Window.add_widget(self.tooltip) + class MyNavigationDrawer(MDNavigationDrawer): def on_touch_up(self, touch): - if self.status == "opened" and self.close_on_click and not self.collide_point(touch.ox, touch.oy): - self.set_state("close", animation=True) - return True + if self.status == "opened" and self.close_on_click and not self.collide_point(touch.ox, touch.oy): + self.set_state("close", animation=True) + return True return super().on_touch_up(touch) - class CircleWithText(MDFloatLayout): text = StringProperty("0") - player = OptionProperty("Black",options=["Black","White"]) + player = OptionProperty("Black", options=["Black", "White"]) min_size = NumericProperty(50) + class ScaledLightLabel(LightLabel, ToolTipBehavior): num_lines = NumericProperty(1) @@ -179,14 +184,11 @@ class ScaledLightLabel(LightLabel, ToolTipBehavior): # --- not checked - - class LightHelpLabel(ScaledLightLabel): pass - -class ScrollableLabel(ScrollView,BackgroundColor,OutlineColor): +class ScrollableLabel(ScrollView, BackgroundColor, OutlineColor): __events__ = ["on_ref_press"] text = StringProperty("") markup = BooleanProperty(False) @@ -217,7 +219,7 @@ class StyledSpinner(Spinner): def __init__(self, **kwargs): super().__init__(**kwargs) - self.bind(size=self._update_dropdown_size_frac,pos=self._update_dropdown_size_frac) + self.bind(size=self._update_dropdown_size_frac, pos=self._update_dropdown_size_frac) def _update_dropdown_size_frac(self, *largs): if not self.sync_height_frac: @@ -286,7 +288,6 @@ class ToggleButtonContainer(GridLayout): return self.options[0] - class LabelledTextInput(TextInput): input_property = StringProperty("") multiline = BooleanProperty(False) @@ -358,7 +359,6 @@ class LabelledIntInput(LabelledTextInput): return int(self.text) - def draw_text(pos, text, **kw): label = CoreLabel(text=text, bold=True, **kw) label.refresh() diff --git a/setup.py b/setup.py index 75cc384..3a92b7d 100644 --- a/setup.py +++ b/setup.py @@ -36,16 +36,17 @@ setup( url="https://github.com/sanderland/katrain", license="MIT", install_requires=[ - "wheel", "setuptools", + "wheel", + "setuptools", "importlib_resources ;python_version<'3.7'", - "cython>=0.24,<=0.29.14,!=0.27,!=0.27.2", # kivy wants this + "cython>=0.24,<=0.29.14,!=0.27,!=0.27.2", # kivy wants this "kivy_deps.glew;platform_system=='Windows'", "kivy_deps.sdl2;platform_system=='Windows'", "kivy_deps.gstreamer;platform_system=='Windows'", "kivy>=1.11 ;python_version<'3.8'", "kivy>=2.0.0rc2 ;python_version>='3.8'", "kivymd>=0.104.0", - ], + ], python_requires=">=3.6, <4", entry_points={"console_scripts": ["katrain=katrain.__main__:run_app"]}, classifiers=["Development Status :: 4 - Beta", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3"],