Last active
April 20, 2018 09:42
-
-
Save tshirtman/a6b6eddcd4e9898e261694daba35bea0 to your computer and use it in GitHub Desktop.
A little board game for two players, no attention paid to graphics, no AI yet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from kivy.app import App | |
| from kivy.animation import Animation | |
| from kivy.uix.widget import Widget | |
| from kivy.uix.button import ButtonBehavior | |
| from kivy.uix.gridlayout import GridLayout | |
| from kivy.properties import ListProperty, NumericProperty, \ | |
| ObjectProperty, StringProperty | |
| class Cell(ButtonBehavior, Widget): | |
| content = ListProperty([]) | |
| selection = NumericProperty() | |
| col = NumericProperty() | |
| row = NumericProperty() | |
| def on_press(self): | |
| app.manage_press(self) | |
| class Pogo(App): | |
| turn = StringProperty('white') | |
| selected = ObjectProperty(allownone=True) | |
| def build(self): | |
| self.reset() | |
| def reset(self, *args): | |
| grid = self.root.ids.board | |
| grid.clear_widgets() | |
| for i in range(3): | |
| for j in range(3): | |
| cell = Cell(row=i, col=j) | |
| if i == 0: | |
| cell.content = ['black', 'black'] | |
| elif i == 2: | |
| cell.content = ['white', 'white'] | |
| else: | |
| cell.content = [] | |
| grid.add_widget(cell) | |
| def manage_press(self, cell): | |
| selected = self.selected | |
| turn = self.turn | |
| if ( | |
| selected is cell or | |
| (not selected and cell.content and cell.content[0] == turn) | |
| ): | |
| self.selected = cell | |
| cell.selection += 1 | |
| cell.selection %= min(4, len(cell.content) + 1) | |
| if not cell.selection: | |
| self.selected = None | |
| elif selected: | |
| selection = selected.selection | |
| dist = ( | |
| abs(selected.col - cell.col) + | |
| abs(selected.row - cell.row) | |
| ) | |
| if dist == selection: | |
| # weird not to be able to use += | |
| cell.content = selected.content[:selection] + cell.content | |
| selected.content = selected.content[selection:] | |
| selected.selection = 0 | |
| self.turn = 'white' if turn == 'black' else 'black' | |
| self.selected = None | |
| def on_turn(self, *args): | |
| if all( | |
| not x.content or x.content[0] != self.turn | |
| for x in self.root.ids.board.children | |
| ): | |
| self.win('black' if self.turn == 'white' else 'white') | |
| def win(self, color): | |
| a = Animation(opacity=1, t='out_quad') + Animation(opacity=0, t='in_quad') | |
| a.bind(on_complete=self.reset) | |
| a.start(self.root.ids.won) | |
| pass | |
| if __name__ == '__main__': | |
| app = Pogo() | |
| app.run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #:import F kivy.factory.Factory | |
| FloatLayout: | |
| BoxLayout: | |
| orientation: 'vertical' | |
| Label: | |
| text: "%s's turn" % app.turn | |
| top: self.height and root.top - 10 | |
| center_x: self.width and root.center_x | |
| size_hint: None, None | |
| size: self.texture_size | |
| font_size: '48dp' | |
| pos_hint: {'center_x': .5} | |
| GridLayout: | |
| id: board | |
| size_hint: .9, .9 | |
| rows: 3 | |
| pos_hint: {'center_x': .5} | |
| Button: | |
| text: 'rules' | |
| size: self.texture_size[0] + dp(10), self.texture_size[1] + dp(10) | |
| font_size: '48dp' | |
| pos_hint: {'center_x': .5} | |
| x: '10dp' | |
| size_hint: None, None | |
| on_press: | |
| F.Rules().open() | |
| Label: | |
| id: won | |
| text: '%s WON!' % ('black' if app.turn == 'white' else 'white') | |
| opacity: 0 | |
| font_size: '100dp' | |
| <Cell>: | |
| canvas.before: | |
| Line: | |
| rectangle: self.x, self.y, self.width, self.height | |
| Label: | |
| markup: True | |
| text: | |
| '\n'.join( | |
| ( | |
| '[b]%s[/b]' if i < root.selection | |
| else '%s' | |
| ) % s for i, s in enumerate(root.content) | |
| ) | |
| size: self.texture_size | |
| center: self.size and root.center | |
| <Rules@ModalView>: | |
| size_hint: .5, None | |
| height: label.height | |
| Label: | |
| id: label | |
| size: self.texture_size[0] + dp(10), self.texture_size[1] + dp(10) | |
| text_size: root.width - dp(20), None | |
| markup: True | |
| text: | |
| ''' | |
| - Each cell of the 3x3 grid can contain a stack of tokens. | |
| - At each player's turn, the current player can take up to 3 \ | |
| tokens from the top of a stack of its color (the topmost \ | |
| token is of the player's color). | |
| - The player has to move these tokens together by as many \ | |
| movements as tokens were taken. So if the player took 2 \ | |
| tokens, they have to be moved by 2 steps, the tokens are \ | |
| added to the top of the stack on the destination cell. | |
| - Each movement can be to the top, left, down or right \ | |
| direction, not crossing the board's borders. | |
| - When a player can't play anymore, because all stacks are | |
| empty, or toped by their opponent's color, they lose the \ | |
| game. | |
| ''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment