517 lines
16 KiB
Plaintext
517 lines
16 KiB
Plaintext
#:kivy 1.11.0
|
|
#:import ew kivy.uix.effectwidget
|
|
|
|
|
|
#:set AI_MODES ['Default','Balance','Policy']
|
|
#:set PLAYER_MODES ['Human', 'Teach','AI:']
|
|
#:set BUTTON_COLOR [0.21, 0.28, 0.31, 1]
|
|
#:set ICON_BUTTON_COLOR [0.71, 0.78, 0.81, 1]
|
|
|
|
<StyledButton>:
|
|
font_size: self.size[1] * 0.45
|
|
radius: (self.size[1]/7,)
|
|
# dont set these
|
|
disabled_mask: (0.5,0.5,0.5,1) if self.disabled else (1,1,1,1)
|
|
color: self.disabled_mask if self.disabled else self.text_color
|
|
background_color: 0,0,0,0
|
|
background_normal: ''
|
|
face_color: [c*m for c,m in zip(self.button_color if root.state=='normal' else self.button_color_down,self.disabled_mask)]
|
|
canvas.before:
|
|
Color:
|
|
rgba: root.face_color or [0,0,0,0]
|
|
RoundedRectangle:
|
|
size: self.size[0]-self.margin[0]-self.margin[2],self.size[1]-self.margin[1]-self.margin[3]
|
|
pos: (self.pos[0]+self.margin[0],self.pos[1]+self.margin[1])
|
|
radius: root.radius or (0.0,)
|
|
|
|
<StyledSpinnerOption@SpinnerOption>:
|
|
font_size: self.size[1] * 0.45
|
|
background_color: BUTTON_COLOR
|
|
background_normal: ''
|
|
color: (1,1,1,1)
|
|
|
|
<StyledSpinner>:
|
|
text: self.values[0] if self.values else ''
|
|
font_size: self.size[1] * 0.45
|
|
sync_height: True
|
|
background_color: [*[c*255/88 for c in BUTTON_COLOR[:3]], 1] # compensate for texture
|
|
option_cls: 'StyledSpinnerOption'
|
|
|
|
<StyledToggleButton>:
|
|
|
|
<StyledTabButton@StyledToggleButton>:
|
|
bold: True
|
|
radius: (self.size[1]/3,self.size[1]/3,0,0)
|
|
|
|
<ToggleButtonContainer>:
|
|
|
|
|
|
<StyledIconButton@StyledButton>:
|
|
button_color: ICON_BUTTON_COLOR
|
|
icon_margin: 0.15 * self.size[0]
|
|
icon: ''
|
|
icon_size: min(self.size[0]-self.margin[0]-self.margin[2]-2*self.icon_margin,self.size[1]-self.margin[1]-self.margin[3]-2*self.icon_margin)
|
|
#EffectWidget: effects: [ew.FXAAEffect()]
|
|
Image:
|
|
size: (root.icon_size or 0,root.icon_size or 0) # square
|
|
pos: [root.pos[i] + (root.size[i] - root.icon_size)/2 for i in [0,1]] if root.icon_size else [0,0]
|
|
source: root.icon
|
|
|
|
<TransparentIconButton@Button>:
|
|
background_normal: ''
|
|
background_color: (0,0,0,0)
|
|
margin: (1,1,1,1)
|
|
icon_size: min(self.size[0]-self.margin[0]-self.margin[2],self.size[1]-self.margin[1]-self.margin[3])
|
|
icon: ''
|
|
Image:
|
|
size: (root.icon_size or 0,root.icon_size or 0) # square
|
|
pos: [root.pos[i] + (root.size[i] - root.icon_size)/2 for i in [0,1]] if root.icon_size else [0,0]
|
|
source: root.icon
|
|
|
|
|
|
<DarkLabel>:
|
|
color: (0.05,0.05,0.05,1)
|
|
|
|
<LargeLabel@DarkLabel>:
|
|
bold: True
|
|
|
|
<CheckBox>:
|
|
color: (0.05,0.05,0.05,1)
|
|
|
|
<LabelledCheckBox>:
|
|
color: (0.95,0.95,0.95,1)
|
|
|
|
<CheckBoxHintLabel@ButtonBehavior+DarkLabel>:
|
|
halign: 'center'
|
|
valign: 'center'
|
|
|
|
<CheckBoxHint>:
|
|
orientation: 'vertical'
|
|
checkbox: checkbox
|
|
label: label
|
|
text: ''
|
|
default_active: False
|
|
position: (0,0)
|
|
CheckBoxHintLabel:
|
|
size_hint: 1,0.45 if root.orientation=='vertical' else (0.8,1)
|
|
font_size: root.height * 0.2 if root.orientation=='vertical' else root.height
|
|
text: root.text
|
|
on_press: if not checkbox.disabled: checkbox._do_press()
|
|
id: label
|
|
CheckBox:
|
|
size_hint: 1,0.55 if root.orientation=='vertical' else (0.2,1)
|
|
id: checkbox
|
|
on_active: root.dispatch('on_active')
|
|
active: root.default_active
|
|
|
|
<CensorableLabel>:
|
|
orientation: 'horizontal'
|
|
text: ''
|
|
label: ''
|
|
CheckBoxHintLabel:
|
|
size_hint: 0.6,1
|
|
text: root.label
|
|
font_size: self.height * 0.6
|
|
on_press: value.opacity = 1 if value.opacity==0 else 0
|
|
DarkLabel:
|
|
size_hint: 0.4,1
|
|
text: root.text
|
|
font_size: self.height * 0.6
|
|
id: value
|
|
bold: True
|
|
|
|
<BaseCircleWithText>:
|
|
text: ''
|
|
color: 0.95,0.95,0.95,1
|
|
font_size: min(self.height,self.width) * 0.6 / (0.5 + 0.5 * len(self.text))
|
|
halign: 'center'
|
|
valign: 'center'
|
|
bold: True
|
|
|
|
<BlackCircleWithText@BaseCircleWithText>:
|
|
canvas.before:
|
|
Color:
|
|
rgba: 0.05,0.05,0.05,1
|
|
Ellipse:
|
|
pos: self.pos[0] + self.width/2 - min(self.height,self.width) * root.radius, self.pos[1] + self.height/2 - min(self.height,self.width) * root.radius
|
|
size: min(self.height,self.width) * 2 * root.radius, min(self.height,self.width) * 2* root.radius
|
|
|
|
<WhiteCircleWithText@BaseCircleWithText>:
|
|
color: 0.05,0.05,0.05,1
|
|
outline: True
|
|
canvas.before:
|
|
Color:
|
|
rgba: 0.95,0.95,0.95,1
|
|
Ellipse:
|
|
pos: self.pos[0] + self.width/2 - min(self.height,self.width) * root.radius, self.pos[1] + self.height/2 - min(self.height,self.width) * root.radius
|
|
size: min(self.height,self.width) * 2 * root.radius, min(self.height,self.width) * 2 * root.radius
|
|
canvas.after:
|
|
Color:
|
|
rgba: 0.05,0.05,0.05,1
|
|
Line:
|
|
circle: self.pos[0] + self.width/2, self.pos[1] + self.height/2, min(self.height,self.width) * root.radius - 1
|
|
width: 1.1 if root.outline else 0.0001
|
|
|
|
<BadukPanWidget>:
|
|
size: self.parent.height, self.parent.height
|
|
katrain: self.parent.parent
|
|
|
|
|
|
<BadukPanControls>:
|
|
katrain: self.parent.parent
|
|
black_prisoners: black_prisoners
|
|
white_prisoners: white_prisoners
|
|
mid_circles_container: mid_circles_container
|
|
pass_btn: pass_btn
|
|
Label:
|
|
size_hint: 0.05, 1
|
|
StyledButton:
|
|
text: 'Pass'
|
|
font_size: 0.35*self.size[1]
|
|
id: pass_btn
|
|
on_press: root.katrain("play",None)
|
|
size_hint: 0.1, 1
|
|
margin: (0, self.size[1]/5, 0, self.size[1]/5)
|
|
Label:
|
|
size_hint: 0.1, 1
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/previous999.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('undo',999)
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/previous5.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('undo',5)
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/previous.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('undo')
|
|
FloatLayout:
|
|
size_hint: 0.2, 1
|
|
id: mid_circles_container
|
|
BlackCircleWithText:
|
|
id: black_prisoners
|
|
pos: (self.parent.pos[0]-self.height/3,self.parent.pos[1]) if self.parent else (0,0)
|
|
radius: 0.4
|
|
WhiteCircleWithText:
|
|
id: white_prisoners
|
|
pos: (self.parent.pos[0]+self.height/3,self.parent.pos[1]) if self.parent else (0,0)
|
|
radius: 0.4
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/next.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('redo')
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/next5.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('redo',5)
|
|
TransparentIconButton:
|
|
icon: 'img/flaticon/next999.png'
|
|
margin: (3, self.size[1]/3, 3, self.size[1]/3)
|
|
size_hint: 0.1, 1
|
|
on_press: root.katrain('redo',999)
|
|
Label:
|
|
size_hint: 0.07, 1
|
|
StyledButton:
|
|
text: 'AI Move'
|
|
font_size: 0.35*self.size[1]
|
|
id: pass_btn
|
|
on_press: root.katrain("ai-move",None)
|
|
size_hint: 0.14, 1
|
|
margin: (0, self.size[1]/5, 0, self.size[1]/5)
|
|
Label:
|
|
size_hint: 0.04, 1
|
|
|
|
|
|
<Controls>:
|
|
orientation: 'vertical'
|
|
play_tab_button: play_tab_button
|
|
analyze_tab_button: analyze_tab_button
|
|
info: info
|
|
win_rate: win_rate
|
|
points_lost: points_lost
|
|
score: score
|
|
hints: hints
|
|
ownership: ownership
|
|
policy: policy
|
|
eval: eval
|
|
player_mode_groups: {'B':B_player_mode,'W':W_player_mode}
|
|
ai_mode_groups: {'B':B_AI_mode,'W':W_AI_mode}
|
|
graph: graph
|
|
katrain: self.parent
|
|
canvas.before:
|
|
Color:
|
|
rgba: 0.95, 0.95, 0.95, 1
|
|
Rectangle:
|
|
pos: self.pos
|
|
size: root.size
|
|
BoxLayout:
|
|
size_hint: 1,0.05
|
|
orientation: 'horizontal'
|
|
StyledTabButton:
|
|
text: 'Analyze'
|
|
id: analyze_tab_button
|
|
margin: (3,0,1,3)
|
|
group: 'tabs'
|
|
on_press:
|
|
analyze_tab.size_hint[0] = 1
|
|
analyze_tab.opacity = 1
|
|
play_tab.size_hint_x = None
|
|
play_tab.width = 0
|
|
play_tab.opacity = 0
|
|
self.state = 'down'
|
|
StyledTabButton:
|
|
text: 'Play'
|
|
group: 'tabs'
|
|
state: 'down'
|
|
id: play_tab_button
|
|
margin: (1,0,3,3)
|
|
on_press:
|
|
play_tab.size_hint[0] = 1
|
|
play_tab.opacity = 1
|
|
analyze_tab.size_hint_x = None
|
|
analyze_tab.width = 0
|
|
analyze_tab.opacity = 0
|
|
self.state = 'down'
|
|
BoxLayout:
|
|
size_hint: 1,0.25
|
|
orientation: 'horizontal'
|
|
BoxLayout: # ----------- analyze -----------
|
|
size_hint: 0,1
|
|
id: analyze_tab
|
|
opacity: 0
|
|
orientation: 'vertical'
|
|
Label:
|
|
size_hint: 1,0.02
|
|
GridLayout:
|
|
cols: 6
|
|
rows: 1
|
|
size_hint: 1, 0.5
|
|
Label:
|
|
size_hint: 0.05, 1
|
|
CheckBoxHint:
|
|
size_hint: 0.2, 0.5
|
|
id: eval
|
|
text: 'show\nall dots'
|
|
default_active: False
|
|
on_active: root.katrain.update_state()
|
|
CheckBoxHint:
|
|
size_hint: 0.2, 0.5
|
|
id: hints
|
|
text: 'show\ntop move'
|
|
on_active: root.katrain.update_state()
|
|
CheckBoxHint:
|
|
size_hint: 0.2, 0.5
|
|
id: ownership
|
|
text: 'show\nowner'
|
|
on_active: root.katrain.update_state()
|
|
CheckBoxHint:
|
|
size_hint: 0.2, 0.5
|
|
id: policy
|
|
text: 'show\npolicy'
|
|
on_active: root.katrain.update_state()
|
|
Label:
|
|
size_hint: 0.05, 1
|
|
ScoreGraph:
|
|
id: graph
|
|
size_hint: 1,0.5
|
|
CensorableLabel:
|
|
id: win_rate
|
|
size_hint: 1, 0.15
|
|
label: 'Win rate'
|
|
text: ''
|
|
CensorableLabel:
|
|
id: score
|
|
size_hint: 1, 0.15
|
|
label: 'Score'
|
|
text: ''
|
|
BoxLayout: # ----------- play -----------
|
|
orientation: 'vertical'
|
|
size_hint: 1,1
|
|
opacity: 1
|
|
id: play_tab
|
|
Label:
|
|
size_hint: 1,0.02
|
|
GridLayout:
|
|
cols: 4
|
|
rows: 2
|
|
size_hint: 1,0.125
|
|
BlackCircleWithText:
|
|
text: 'B'
|
|
size_hint: 0.1, 1
|
|
ToggleButtonContainer:
|
|
size_hint: 0.6, 1
|
|
id: B_player_mode
|
|
options: ['human','human+undo','ai']
|
|
labels: PLAYER_MODES
|
|
on_selection: root.katrain.update_state()
|
|
StyledSpinner:
|
|
id: B_AI_mode
|
|
size_hint: 0.3, 1
|
|
values: AI_MODES
|
|
Label:
|
|
size_hint: None,1
|
|
width: 3
|
|
WhiteCircleWithText:
|
|
text: 'W'
|
|
size_hint: 0.1, 1
|
|
ToggleButtonContainer:
|
|
size_hint: 0.6, 1
|
|
id: W_player_mode
|
|
options: ['human','human+undo','ai']
|
|
labels: PLAYER_MODES
|
|
on_selection: root.katrain.update_state()
|
|
StyledSpinner:
|
|
id: W_AI_mode
|
|
size_hint: 0.3, 1
|
|
values: AI_MODES
|
|
Label:
|
|
size_hint: None,1
|
|
width: 3
|
|
LargeLabel:
|
|
text: ''
|
|
size_hint: 1,0.25
|
|
CensorableLabel:
|
|
id: points_lost
|
|
size_hint: 1, 0.03
|
|
label: 'Point loss'
|
|
text: ''
|
|
TextInput:
|
|
id: info
|
|
size_hint: 1, 0.25
|
|
valign: 'middle'
|
|
BoxLayout:
|
|
orientation: 'horizontal'
|
|
size_hint: 1, None
|
|
height: self.width * 0.25
|
|
StyledIconButton:
|
|
icon: 'img/flaticon/go-game.png'
|
|
size_hint: 0.25, 1
|
|
on_press: root.katrain("new-game-popup")
|
|
StyledIconButton:
|
|
icon: 'img/flaticon/open-folder.png'
|
|
size_hint: 0.25, 1
|
|
on_press: root.katrain("analyze-sgf-popup")
|
|
StyledIconButton:
|
|
icon: 'img/flaticon/bar.png'
|
|
size_hint: 0.25, 1
|
|
on_press: root.katrain('output-sgf')
|
|
StyledIconButton:
|
|
icon: 'img/flaticon/gears.png'
|
|
size_hint: 0.25, 1
|
|
on_press: root.katrain('config-popup')
|
|
|
|
<KaTrainGui>:
|
|
board_gui: board_gui
|
|
controls: controls
|
|
board_controls: board_controls
|
|
board_aspect_ratio: 1.075
|
|
BoxLayout:
|
|
canvas.before:
|
|
Color:
|
|
rgb: root.board_gui.board_color if root.board_gui else (0,0,0)
|
|
Rectangle:
|
|
pos: root.pos
|
|
size: root.size
|
|
orientation: 'vertical'
|
|
size_hint: 1 - controls.size_hint[0], 1
|
|
BadukPanWidget:
|
|
id: board_gui
|
|
size_hint: (1,1)
|
|
BadukPanControls:
|
|
id: board_controls
|
|
size_hint: (1,root.board_aspect_ratio-1)
|
|
Controls:
|
|
id: controls
|
|
size_hint: max(0.25,(root.width - root.height/root.board_aspect_ratio)/root.width), 1
|
|
|
|
|
|
|
|
<LoadSGFPopup>:
|
|
fast: fast
|
|
rewind: rewind
|
|
filesel: filesel
|
|
orientation: 'vertical'
|
|
Label:
|
|
text: root.filesel.path
|
|
size_hint: 1,0.05
|
|
halign: 'left'
|
|
FileChooserListView:
|
|
id: filesel
|
|
multiselect: False
|
|
filters: ["*.sgf"]
|
|
path: "."
|
|
size_hint: 1,0.88
|
|
BoxLayout:
|
|
orientation: 'horizontal'
|
|
size_hint: 1,0.07
|
|
canvas.before:
|
|
Color:
|
|
rgb: 0.4, 0.4, 0.4
|
|
Rectangle:
|
|
pos: self.pos
|
|
size: self.size
|
|
Label:
|
|
text: "Analyze Extra Fast"
|
|
size_hint: 0.45,1
|
|
halign: 'right'
|
|
CheckBox:
|
|
id: fast
|
|
color: (0.95, 0.95, 0.95)
|
|
size_hint: 0.05,1
|
|
Label:
|
|
text: "Rewind to Start"
|
|
halign: 'right'
|
|
size_hint: 0.45,1
|
|
CheckBox:
|
|
id: rewind
|
|
active: True
|
|
color: (0.95, 0.95, 0.95)
|
|
size_hint: 0.05,1
|
|
|
|
<NewGamePopup>:
|
|
orientation: 'vertical'
|
|
rules_spinner: rules_spinner
|
|
info: info
|
|
GridLayout:
|
|
size_hint: 1, 0.8
|
|
rows: 5
|
|
cols: 2
|
|
Label:
|
|
text: "Size"
|
|
LabelledTextInput:
|
|
text: '19'
|
|
input_property: 'SZ'
|
|
Label:
|
|
text: "Handicap"
|
|
LabelledIntInput:
|
|
text: '0'
|
|
input_property: 'HA'
|
|
Label:
|
|
text: "Komi"
|
|
LabelledFloatInput:
|
|
text: '6.5'
|
|
input_property: 'KM'
|
|
Label:
|
|
text: "Ruleset"
|
|
LabelledSpinner:
|
|
input_property: 'RU'
|
|
id: rules_spinner
|
|
Label:
|
|
text: "Use x:y (e.g. 19:9) to play on a non-square board, but note that handicaps above 9 are not supported."
|
|
size_hint: 1,3
|
|
halign: 'center'
|
|
valign: 'center'
|
|
multiline: True
|
|
text_size: self.size
|
|
id: info
|
|
StyledButton:
|
|
text: 'Start\nGame'
|
|
font_size: 0.3 * self.size[1]
|
|
on_press: root.new_game()
|