Пример #1
0
 def __init__(self, *args, **kwargs):
     self.register_event_type('on_win')
     if 'use_ai' in kwargs:
         use_ai = kwargs.pop('use_ai')
     else:
         use_ai = False
     super(Board, self).__init__(*args, **kwargs)
     self.abstractboard = AbstractBoard(shape=self.grid)
     self.abstractboard.reset()
     self.use_ai = use_ai
Пример #2
0
 def reset_gridsize(self, newsize):
     self.gridsize = newsize
     self.abstractboard = AbstractBoard(gridsize=newsize)
     print 'New gridsize is', self.gridsize
     print 'New abstractboard gridsize', self.abstractboard.game.size
Пример #3
0
class GuiBoard(Widget):
    gridsize = NumericProperty(19)  # Board size
    navmode = StringProperty('Navigate')  # How to scale the board
    abstractboard = ObjectProperty(
        None, allownone=True)  # Object to query for where to play moves
    uielements = DictProperty({})
    makemovemarker = ObjectProperty(None, allownone=True)
    touchoffset = ListProperty([0, 0])
    guesses = ListProperty([0, 0])
    gameinfo = DictProperty({})

    # Save state
    user_saved = BooleanProperty(False)
    temporary_filepath = StringProperty('')
    permanent_filepath = StringProperty('')
    has_unsaved_data = BooleanProperty(False)

    # Score mode
    ld_markers = DictProperty({})
    scoreboard = ObjectProperty(None, allownone=True)

    variations_exist = BooleanProperty(False)

    showcoords = BooleanProperty(False)

    wname = StringProperty('')
    wrank = StringProperty('')
    bname = StringProperty('')
    brank = StringProperty('')
    next_to_play = StringProperty('e')

    comment_pre_text = StringProperty('')
    comment_text = StringProperty('')

    # Board flipping
    flip_horiz = BooleanProperty(False)
    flip_vert = BooleanProperty(False)
    flip_forwardslash = BooleanProperty(True)
    flip_backslash = BooleanProperty(False)

    # Transient widgets
    playmarker = ObjectProperty(
        None, allownone=True)  # Circle marking last played move
    boardmarkers = DictProperty({})
    guesspopup = ObjectProperty(None, allownone=True)
    varstones = DictProperty({})

    # Coordinates widget
    coordinate_letter = 'abcdefghjklmnopqrstuv'
    coordinate_number = [
        '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13',
        '14', '15', '16', '17', '18', '19'
    ]
    coordinates = BooleanProperty(False)
    coordinate_labels = ListProperty([])

    def on_coordinates(self, obj, val):
        print 'on_coordinates', obj, val
        if val:
            print 'adding coordinates'
            self.add_coordinates()
        else:
            print 'removing coordinates'
            self.remove_coordinates()

    stones = DictProperty({})
    starpoints = DictProperty()
    starpoint_positions = DictProperty(starposs)

    gobansize = ListProperty((100, 100))
    numcells = NumericProperty(10)
    boardindent = ListProperty((100, 100))
    stonesize = ListProperty((100, 100))
    gridspacing = NumericProperty(10)
    gridlines = ListProperty([])

    gobanpos = ListProperty((100, 100))

    def __init__(self, *args, **kwargs):
        super(GuiBoard, self).__init__(*args, **kwargs)
        print 'GuiBoard init, making abstractboard with gridsize', self.gridsize
        self.abstractboard = AbstractBoard(gridsize=self.gridsize)
        self.reset_abstractboard()

    def add_handicap_stones(self, num):
        print 'asked to add handicap stones', num
        if handicap_positions.has_key(self.gridsize):
            stone_positions = handicap_positions[self.gridsize]
            if stone_positions.has_key(num):
                stone_coords = stone_positions[num]
                print 'handicap positions are', stone_coords
                for coord in stone_coords:
                    self.toggle_background_stone(coord, 'b')
        self.next_to_play = 'w'

    def start_autoplay(self, *args, **kwargs):
        Clock.schedule_interval(self.advance_one_move, 0.25)
        self.pre_text = '[b]Autoplay[/b] activated. Tap on the navigation buttons (or the board in navigation mode) to stop autoplaying.'

    def stop_autoplay(self, *args, **kwargs):
        try:
            Clock.unschedule(self.advance_one_move)
        except:
            pass

    def set_game_info(self, info):
        print 'asked to set with info', info
        self.abstractboard.set_gameinfo(info)
        self.get_game_info()

    def get_game_info(self):
        self.gameinfo = self.abstractboard.get_gameinfo()
        self.get_player_details()
        if not self.user_saved:
            if self.gameinfo.has_key('filepath'):
                self.permanent_filepath = self.gameinfo['filepath']

    def view_game_info(self):
        gi = GameInfo(board=self)
        gi.populate_from_gameinfo(self.gameinfo)
        popup = Popup(content=gi, title='Game info.', size_hint=(0.85, 0.85))
        popup.content.popup = popup
        popup.open()

    def save_sgf(self, saveas=False, autosave=False, refresh=True):
        # if refresh and self.permanent_filepath != '':
        #     newn = self.build_savefile_name()
        #     newns = newn.split('_')
        #     curn = self.permanent_filepath
        #     curns = curn.split('_')
        if autosave:
            if self.permanent_filepath != '':
                self.abstractboard.save_sgf(self.permanent_filepath)
            else:
                if self.temporary_filepath == '':
                    self.temporary_filepath = get_temp_filepath()
                self.abstractboard.save_sgf(self.temporary_filepath)
        elif saveas:
            self.ask_where_to_save()
        else:
            if self.permanent_filepath != '':
                self.abstractboard.save_sgf(self.permanent_filepath)
            else:
                self.ask_where_to_save()

    def ask_where_to_save(self, force=True):
        sq = SaveQuery(board=self)
        popup = Popup(content=sq,
                      title='Where to save?',
                      size_hint=(0.85, 0.85))
        popup.content.popup = popup
        fileh = open('game_collection_locations.json', 'r')
        collection_folders = jsonload(fileh)
        fileh.close()
        collections_args_converter = get_collectioninfo_from_dir
        list_adapter = ListAdapter(data=collection_folders,
                                   args_converter=collections_args_converter,
                                   selection_mode='single',
                                   allow_empty_selection=True,
                                   cls=CollectionChooserButton)
        sq.collections_list.adapter = list_adapter
        popup.open()

    def make_savefile_in_dir(self, dirn):
        filen = self.build_savefile_name(dirn)
        self.permanent_filepath = filen
        self.user_saved = True
        self.save_sgf()

    def build_savefile_name(self, dirn):
        filen = ''.join((dirn, '/', asctime().replace(' ', '_')))
        if 'wname' in self.gameinfo:
            filen += '_' + self.gameinfo['wname']
        else:
            filen += '_' + 'wunknown'
        if 'bname' in self.gameinfo:
            filen += '_' + self.gameinfo['bname']
        else:
            filen += '_' + 'bunknown'
        if 'event' in self.gameinfo:
            filen += '_' + self.gameinfo['event']
        else:
            filen += '_' + 'eunknown'
        filen += '.sgf'
        return filen

    def back_to_varbranch(self):
        instructions = self.abstractboard.jump_to_varbranch()
        self.follow_instructions(instructions)

    def take_stone_input(self, coords):
        if tuple(coords) not in self.stones:
            if self.navmode == 'Play':
                existingvars = map(lambda j: j.get_move(),
                                   self.abstractboard.curnode)
                alreadyexists = False
                for entry in existingvars:
                    if entry[0] == self.next_to_play and entry[1][0] == coords[
                            0] and entry[1][1] == coords[1]:
                        instructions = self.abstractboard.jump_to_node(
                            self.abstractboard.curnode[existingvars.index(
                                entry)])
                        print 'entry already exists!'
                        self.follow_instructions(instructions)
                        return True
                children_exist = self.abstractboard.do_children_exist()
                if not children_exist:
                    self.add_new_stone(coords)
                else:
                    popup = Popup(content=PickNewVarType(board=self,
                                                         coord=coords),
                                  title='Do you want to...',
                                  size_hint=(0.85, 0.85))
                    popup.content.popup = popup
                    popup.open()
            elif self.navmode == 'Guess':
                self.guesses[1] += 1
                nextcoords = self.abstractboard.get_next_coords()
                if nextcoords[0] is not None and nextcoords[1] is not None:
                    correct = False
                    if coords[0] == nextcoords[0] and coords[1] == nextcoords[
                            1]:
                        self.guesses[0] += 1
                        correct = True
                        instructions = self.abstractboard.advance_position()
                        self.follow_instructions(instructions)
                    pre_text = '%.1f%% correct' % (
                        100 * float(self.guesses[0]) / self.guesses[1])
                    if not correct:
                        off_by_x = abs(coords[0] - nextcoords[0])
                        off_by_y = abs(coords[1] - nextcoords[1])
                        self.set_guess_popup(coords, max(off_by_x, off_by_y))
                        pre_text = '[color=ff0000]Wrong[/color] - ' + pre_text
                    else:
                        pre_text = '[color=00ff00]Correct![/color] - ' + pre_text
                    pre_text += '\n-----\n'
                    self.comment_pre_text = pre_text

    def set_guess_popup(self, centre, size):
        if self.guesspopup is not None:
            self.remove_widget(self.guesspopup)
            self.guesspopup = None
        centrecoords = self.coord_to_pos(centre)
        cx, cy = centrecoords
        lr = (cx - (size + 0.25) * self.stonesize[0],
              cy - (size + 0.25) * self.stonesize[1])
        tr = (cx + (size + 1.25) * self.stonesize[0],
              cy + (size + 1.25) * self.stonesize[1])
        markerpos = lr
        markersize = (tr[0] - lr[0], tr[1] - lr[1])
        markercolour = [
            0. + size / (0.5 * self.gridsize),
            1. - size / (0.5 * self.gridsize), 0.
        ]
        gp = GuessPopup(pos=markerpos,
                        size=markersize,
                        colour=markercolour,
                        alpha=0.1)
        self.guesspopup = gp
        ani = Animation(alpha=1.0, t='in_out_quad', duration=0.2) + Animation(
            alpha=(0.15), t='in_out_quad', duration=0.5)
        #ani.bind(on_complete=self.remove_guess_popup)
        ani.start(gp)
        self.add_widget(gp)

    def remove_guess_popup(self, *args, **kwargs):
        if self.guesspopup is not None:
            self.remove_widget(self.guesspopup)
            self.guesspopup = None

    def toggle_background_stone(self, coords, colour='b', force='toggle'):
        instructions = self.abstractboard.toggle_background_stone(
            coords, colour, force)
        print 'toggle background got instructions', instructions
        self.follow_instructions(instructions)

    def add_new_stone(self, coords, newtype='newvar'):
        print 'Called add_new_stone', coords, newtype
        colour = self.next_to_play
        if newtype == 'newvar':
            instructions = self.abstractboard.add_new_node(
                coords, self.next_to_play)
            self.follow_instructions(instructions)
        if newtype == 'newmain':
            instructions = self.abstractboard.add_new_node(coords,
                                                           self.next_to_play,
                                                           newmainline=True)
            self.follow_instructions(instructions)
        if newtype == 'replacenext':
            instructions = self.abstractboard.replace_next_node(
                coords, self.next_to_play)
            self.follow_instructions(instructions)
        if newtype == 'insert':
            instructions = self.abstractboard.insert_before_next_node(
                coords, self.next_to_play)
            self.follow_instructions(instructions)
        print 'add_new_stone received instructions:', instructions

    def open_sgf_dialog(self, *args, **kwargs):
        popup = Popup(content=OpenSgfDialog(board=self),
                      title='Open SGF',
                      size_hint=(0.85, 0.85))
        popup.content.popup = popup
        popup.open()

    def load_sgf_from_file(self, path, filen):
        print 'asked to load from', path, filen
        self.abstractboard.load_sgf_from_file(filen[0])
        self.permanent_filepath = self.abstractboard.filepath
        self.reset_abstractboard()

    def get_new_comment(self, *args, **kwargs):
        print 'get new comment called'
        if self.comment_text == '[color=444444]Long press to add comment.[/color]':
            popup = Popup(content=CommentInput(board=self, comment=''),
                          title='Edit comment:',
                          size_hint=(0.85, 0.85))
        else:
            popup = Popup(content=CommentInput(board=self,
                                               comment=self.comment_text),
                          title='Edit comment:',
                          size_hint=(0.85, 0.55),
                          pos=(0.075 * Window.width, 0.95 * Window.height))
        popup.content.popup = popup
        if platform() == 'android':
            import android
            android.vibrate(0.1)
        popup.open()

    def set_new_comment(self, comment):
        self.comment_text = comment
        self.abstractboard.curnode.set('C', comment)

    def clear_ld_markers(self):
        for coords in self.ld_markers:
            marker = self.ld_markers[coords]
            self.remove_widget(marker)
        self.ld_markers = {}
        print 'new self.ld_markers', self.ld_markers

    def make_scoreboard(self):
        if self.scoreboard is not None:
            self.scoreboard = None
        sb = ScoreBoard(self.gridsize)
        sb.board = self.abstractboard.get_current_boardpos()
        self.scoreboard = sb

    def set_navmode(self, spinner, mode):
        self.scoreboard = None
        self.clear_ld_markers()
        if mode != 'Guess':
            self.remove_guess_popup()
        self.navmode = mode
        if mode == 'Navigate':
            self.comment_pre_text = navigate_text + '\n-----\n'
        elif mode == 'Play':
            self.comment_pre_text = play_text + '\n-----\n'
        elif mode == 'Score':
            self.make_scoreboard()
            score = self.scoreboard.get_score()
            self.comment_pre_text = score_text + '\n-----\n'
        elif mode == 'Guess':
            self.comment_pre_text = guess_text + '\n-----\n'
        elif mode == 'Zoom':
            self.comment_pre_text = zoom_text + '\n-----\n'

    def clear_transient_widgets(self):
        self.remove_playmarker()
        # self.remove_komarker()
        self.clear_markers()
        self.clear_variation_stones()

    ## Board markers
    def toggle_ld_marker(self, coord):
        if self.ld_markers.has_key(coord):
            existingmarker = self.ld_markers.pop(coord)
            self.remove_widget(existingmarker)
        else:
            newmarker = LDMarker(size=self.stonesize,
                                 pos=self.coord_to_pos(coord))
            self.add_widget(newmarker)
            self.ld_markers[coord] = newmarker

    def add_marker(self, coord, mtype, other=[]):
        print 'adding marker:', coord, mtype
        if self.boardmarkers.has_key(coord):
            existingmarker = self.boardmarkers.pop(coord)
            self.remove_widget(existingmarker)

        if mtype == 'triangle':
            newmarker = TriangleMarker(size=self.stonesize,
                                       pos=self.coord_to_pos(coord))
        elif mtype == 'square':
            newmarker = SquareMarker(size=self.stonesize,
                                     pos=self.coord_to_pos(coord))
        elif mtype == 'circle':
            newmarker = CircleMarker(size=self.stonesize,
                                     pos=self.coord_to_pos(coord))
        elif mtype == 'cross':
            newmarker = CrossMarker(size=self.stonesize,
                                    pos=self.coord_to_pos(coord))
        elif mtype == 'text':
            newmarker = TextMarker(size=self.stonesize,
                                   pos=self.coord_to_pos(coord))
            newmarker.text = other[0]
        else:
            return None

        self.colour_marker_for_contrast(coord, newmarker)
        self.add_widget(newmarker)
        self.boardmarkers[coord] = newmarker

    def remove_marker(self, coord):
        if self.boardmarkers.has_key(coord):
            marker = self.boardmarkers.pop(coord)
            self.remove_widget(marker)

    def clear_markers(self):
        for coord in self.boardmarkers.keys():
            marker = self.boardmarkers.pop(coord)
            self.remove_widget(marker)

    def update_markers(self):
        for coord in self.boardmarkers.keys():
            marker = self.boardmarkers[coord]
            marker.size = self.stonesize
            marker.pos = self.coord_to_pos(coord)
            self.remove_widget(marker)
            self.add_widget(marker)

    def marker_colour(self, coord):
        if self.stones.has_key(coord):
            stone_colour = self.stones[coord].colour
            return [
                1 - stone_colour[0], 1 - stone_colour[1], 1 - stone_colour[2]
            ]
        else:
            return [0, 0, 0]

    def colour_marker_for_contrast(self, coord, marker):
        markercolour = self.marker_colour(coord)
        marker.markercolour = markercolour

    ## Playmarker
    def set_playmarker(self, coord):
        self.remove_widget(self.playmarker)
        marker = PlayMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        self.colour_marker_for_contrast(coord, marker)
        marker.coord = coord
        self.add_widget(marker)
        self.playmarker = marker

    def remove_playmarker(self):
        self.remove_widget(self.playmarker)
        self.playmarker = None

    def update_playmarker(self):
        if self.playmarker is not None:
            self.set_playmarker(self.playmarker.coord)
        self.set_playmarker

    def on_size(self, *args, **kwargs):
        print '%%% ON_SIZE %%%'
        self.gobanpos = self.pos
        self.gridlines = self.get_gridlines()

        self.update_starpoints()
        self.update_stones()
        self.update_playmarker()
        self.update_markers()
        self.update_coordinates()

    def on_pos(self, *args, **kwargs):
        self.on_size()

    def on_gobanpos(self, *args, **kwargs):
        self.gridlines = self.get_gridlines()

        self.update_starpoints()
        self.update_stones()
        self.update_playmarker()
        self.update_markers()

    def coord_to_pos(self, coord, dotransformations=True):
        gridspacing = self.gridspacing
        realcoord = [coord[0], coord[1]]
        if dotransformations:
            if self.flip_horiz:
                realcoord[0] = self.game.size - 1 - realcoord[0]
            if self.flip_vert:
                realcoord[1] = self.game.size - 1 - realcoord[1]
            if self.flip_forwardslash:
                realcoord = realcoord[::-1]
            if self.flip_backslash:
                realcoord = realcoord[self.game.size - 1 - realcoord[0],
                                      self.game.size - 1 - realcoord[1]][::-1]

        coord = realcoord

        coord = (coord[0] - 0.5, coord[1] - 0.5)
        return (self.gobanpos[0] + self.boardindent[0] +
                coord[0] * gridspacing, self.gobanpos[1] +
                self.boardindent[1] + coord[1] * gridspacing)

    def pos_to_coord(self, pos):
        gridspacing = self.gridspacing
        relx = (pos[0] -
                (self.gobanpos[0] + self.boardindent[0])) / gridspacing
        rely = (pos[1] -
                (self.gobanpos[1] + self.boardindent[1])) / gridspacing
        relx += self.touchoffset[0]
        rely += self.touchoffset[1]
        realcoord = (int(round(relx)), int(round(rely)))
        if self.flip_horiz:
            realcoord[0] = self.game.size - 1 - realcoord[0]
        if self.flip_vert:
            realcoord[1] = self.game.size - 1 - realcoord[1]
        if self.flip_forwardslash:
            realcoord = realcoord[::-1]
        if self.flip_backslash:
            realcoord = realcoord[self.game.size - 1 - realcoord[0],
                                  self.game.size - 1 - realcoord[1]][::-1]
        return realcoord

    def get_gridlines(self):
        startx = self.boardindent[0] + self.gobanpos[0]
        starty = self.boardindent[1] + self.gobanpos[1]
        gridspacing = self.gridspacing
        length = self.boardlength
        gridnum = self.gridsize

        gridline = []

        curx = startx
        cury = starty

        dir = 1.0
        for y in range(self.gridsize - 1):
            curx += dir * length
            gridline.append([curx, cury])
            cury += gridspacing
            gridline.append([curx, cury])
            dir *= -1
        dir *= -1
        for x in range(self.gridsize - 1):
            cury += dir * length
            gridline.append([curx, cury])
            curx += gridspacing
            gridline.append([curx, cury])
            dir *= -1

        return reduce(lambda j, k: j + k, gridline)

    # Stone methods
    def follow_instructions(self, instructions, *args, **kwargs):
        print '### instructions are', instructions

        t1 = time()

        self.clear_transient_widgets()
        self.reset_uielements()
        self.remove_guess_popup()

        t2 = time()

        if 'remove' in instructions:
            remove_stones = instructions['remove']
            for stone in remove_stones:
                self.remove_stone(coord=stone[0],
                                  colour=colourname_to_colour(stone[1]))
        if 'add' in instructions:
            add_stones = instructions['add']
            for stone in add_stones:
                self.add_stone(coord=stone[0],
                               colour=colourname_to_colour(stone[1]))
        if 'empty' in instructions:
            empty_stones = instructions['empty']
            for stone in empty_stones:
                self.empty_stone(coord=stone[0])

        t3 = time()

        if 'playmarker' in instructions:
            pm = instructions['playmarker']
            print 'Asked to draw pm at', pm
            if pm is not None:
                self.set_playmarker(pm)
        if 'markers' in instructions:
            markers = instructions['markers']
            print 'received markers:', markers
            for marker in markers:
                if marker[1] == 'TR':
                    self.add_marker(marker[0], 'triangle')
                elif marker[1] == 'SQ':
                    self.add_marker(marker[0], 'square')
                elif marker[1] == 'CR':
                    self.add_marker(marker[0], 'circle')
                elif marker[1] == 'MA':
                    self.add_marker(marker[0], 'cross')
                elif marker[1] == 'LB':
                    self.add_marker(marker[0], 'text', marker[2:])
        if 'variations' in instructions:
            curvar, varnum = instructions['variations']
            if varnum > 1:
                if self.uielements.has_key('varbutton'):
                    for button in self.uielements['varbutton']:
                        button.background_color = [0, 1, 0, 1]
                        button.text = 'Next var\n  (%d / %d)' % (curvar,
                                                                 varnum)
        if 'varpositions' in instructions:
            vars = instructions['varpositions']
            for entry in vars:
                colour, coord, number = entry
                self.add_variation_stone(coord, colour, number)

        t4 = time()

        if 'comment' in instructions:
            commenttext = instructions['comment']
            self.comment_text = commenttext
        else:
            self.comment_text = '[color=444444]Long press to add comment.[/color]'

        if 'nextplayer' in instructions:
            player = instructions['nextplayer']
            if player in ['b', 'w']:
                print 'next_to_play from', self.next_to_play
                self.next_to_play = player
                print '-->', self.next_to_play
            elif player == 'a':
                self.next_to_play = alternate_colour(self.next_to_play)

        if 'pre_text' in instructions:
            text = instructions['pre_text']
            self.comment_pre_text = text

        if 'unsaved' in instructions:
            self.has_unsaved_data = True
        if 'saved' in instructions:
            self.has_unsaved_data = False

        t5 = time()

        tottime = t5 - t1
        # print '## Follow instruction times'
        # print '## Total', t5-t1
        # print '## Reset', t2-t1, (t2-t1)/tottime
        # print '## Add remove empty', t3-t2, (t3-t2)/tottime
        # print '## Playmarker, positions etc.', t4-t3, (t4-t3)/tottime
        # print '## Comment and saved', t5-t4, (t5-t4)/tottime

    def get_player_details(self, *args, **kwargs):
        wname, bname = self.abstractboard.get_player_names()
        wrank, brank = self.abstractboard.get_player_ranks()
        self.wrank = wrank
        self.wname = wname
        self.brank = brank
        self.bname = bname

    def advance_one_move(self, *args, **kwargs):
        print '%% Advancing one move!', time()
        t1 = time()
        instructions = {
            'add': [((randint(0, 18), randint(0, 18)), ['w',
                                                        'b'][randint(0, 1)])]
        }
        self.follow_instructions(instructions)
        t3 = time()
        print '%% Total time for button function to complete', t3 - t1
        # if self.navmode == 'Score':
        #     self.clear_ld_markers()
        #     self.make_scoreboard()
        # t1 = time()
        # children_exist = self.abstractboard.do_children_exist()
        # t2 = time()
        # if children_exist:
        #     instructions = self.abstractboard.advance_position()
        #     self.follow_instructions(instructions)
        # else:
        #     if platform() == 'android':
        #         import android
        #         android.vibrate(0.1)
        # t3 = time()
        # print '%% Total time for button function to complete', t3-t1
        # print '%% Children exist', t2-t1
        # print '%% Follow instructions', t3-t2
        # print '%%'

    def time_start(self):
        print 'time_start called'
        t = time()
        self.timestart = t

    def time_stop(self):
        t = time()
        t0 = self.timestart
        print '``` Time between press and release:', t - t0

    def retreat_one_move(self, *args, **kwargs):
        print '%% Advancing one move!', time()
        t1 = time()
        instructions = {'remove': [(self.stones.keys()[0], 'b')]}
        print instructions
        self.follow_instructions(instructions)
        t3 = time()
        print '%% Total time for retreat button function to complete', t3 - t1
        # if self.navmode == 'Score':
        #     self.clear_ld_markers()
        #     self.make_scoreboard()
        # instructions = self.abstractboard.retreat_position()
        # self.follow_instructions(instructions)

    def jump_to_start(self, *args, **kwargs):
        instructions = self.abstractboard.jump_to_node(
            self.abstractboard.game.root)
        self.follow_instructions(instructions)

    def jump_to_end(self, *args, **kwargs):
        instructions = self.abstractboard.jump_to_node(
            self.abstractboard.game.get_last_node())
        self.follow_instructions(instructions)

    def reset_uielements(self, *args, **kwargs):
        self.comment_pre_text = ''
        self.comment_text = ''

        #self.next_to_play = 'b'

        for elementtype in self.uielements:
            elements = self.uielements[elementtype]
            for element in elements:
                if elementtype == 'varbutton':
                    element.background_color = [1, 0, 0, 1]
                    element.text = 'Next var\n  (1 / 1)'

    def add_variation_stone(self,
                            coord=(1, 1),
                            colour='black',
                            num=1,
                            *args,
                            **kwargs):
        stonesize = self.stonesize
        stone = VarStone(size=stonesize,
                         pos=self.coord_to_pos(coord),
                         text=str(num))
        stone.set_colour(colour)
        if self.varstones.has_key(coord):
            self.remove_stone(coord)
        self.varstones[coord] = stone
        self.add_widget(stone)

    def clear_variation_stones(self):
        for coord in self.varstones.keys():
            stone = self.varstones.pop(coord)
            self.remove_widget(stone)

    def add_coordinates(self):
        self.remove_coordinates()
        stonesize = self.stonesize
        for i in range(self.gridsize):
            label = Label(text=self.coordinate_letter[i],
                          size=stonesize,
                          pos=self.coord_to_pos((i, -0.75),
                                                dotransformations=False),
                          font_size=(0.4 * stonesize[1], 'px'),
                          color=(0, 0, 0, 1))
            self.add_widget(label)
            self.coordinate_labels.append(label)
        for j in range(self.gridsize):
            label = Label(text=self.coordinate_number[j],
                          size=stonesize,
                          pos=self.coord_to_pos((-0.75, j),
                                                dotransformations=False),
                          font_size=(0.4 * stonesize[1], 'px'),
                          color=(0, 0, 0, 1))
            self.add_widget(label)
            self.coordinate_labels.append(label)

    def remove_coordinates(self):
        for widget in self.coordinate_labels:
            self.remove_widget(widget)
        self.coordinate_labels = []

    def update_coordinates(self):
        self.remove_coordinates()
        if self.coordinates:
            self.add_coordinates()

    def add_stone(self, coord=(1, 1), colour='black', *args, **kwargs):
        stonesize = self.stonesize
        t1 = time()
        stone = Stone(size=stonesize, pos=self.coord_to_pos(coord))
        stone.set_colour(colour)
        t2 = time()
        if self.stones.has_key(coord):
            self.remove_stone(coord)
        self.stones[coord] = stone
        t3 = time()
        self.add_widget(stone)
        t4 = time()
        # print '@@ total', t4-t1
        # print '@@ make stone', t2-t1, (t2-t1)/(t4-t1)
        # print '@@ add to dict', t3-t2, (t3-t2)/(t4-t1)
        # print '@@ add widget', t4-t3, (t4-t3)/(t4-t1)

    def remove_stone(self, coord=(1, 1), *args, **kwargs):
        print coord, self.stones.keys()
        print self.stones[coord]
        if self.stones.has_key(coord):
            stone = self.stones.pop(coord)
            self.remove_widget(stone)
        else:
            print 'Tried to remove stone that doesn\'t exist'

    def empty_stone(self, coord=(1, 1), *args, **kwargs):
        if self.stones.has_key(coord):
            stone = self.stones.pop(coord)
            self.remove_widget(stone)

    def update_stones(self):
        for coord in self.stones.keys():
            self.stones[coord].pos = self.coord_to_pos(coord)
            self.stones[coord].size = self.stonesize

    def redraw_stones(self):
        for coord in self.stones.keys():
            stone = self.stones[coord]
            self.remove_widget(stone)
            self.add_widget(stone)

    def clear_stones(self):
        for coord in self.stones.keys():
            stone = self.stones.pop(coord)
            self.remove_widget(stone)

    # Star point methods
    def draw_starpoints(self):
        self.remove_starpoints()
        if self.starpoint_positions.has_key(self.gridsize):
            coords = self.starpoint_positions[self.gridsize]
            for entry in coords:
                self.add_starpoint(entry)

    def add_starpoint(self, coord=(1, 1), *args, **kwargs):
        stonesize = self.stonesize
        sp = StarPoint(size=stonesize, pos=self.coord_to_pos(coord))
        if self.starpoints.has_key(coord):
            self.remove_starpoint(coord)
        self.starpoints[coord] = sp
        self.add_widget(sp)
        self.redraw_stones()

    def remove_starpoint(self, coord=(1, 1), *args, **kwargs):
        if self.starpoints.has_key(coord):
            sp = self.starpoints.pop(coord)
            self.remove_widget(ssp)
        else:
            print 'Tried to remove starpoint that doesn\'t exist'

    def remove_starpoints(self):
        for entry in self.starpoints:
            sp = self.starpoints[entry]
            self.remove_widget(sp)
        self.starpoints = {}

    def update_starpoints(self):
        self.remove_starpoints()
        self.draw_starpoints()

    def redraw_starpoints(self):
        for coord in self.starpoints.keys():
            sp = self.starpoints[coord]
            self.remove_widget(ssp)
            self.add_widget(sp)
        self.redraw_stones()

    # Variation handling
    def next_variation(self, *args, **kwargs):
        instructions = self.abstractboard.increment_variation()
        self.follow_instructions(instructions)

    def prev_variation(self, *args, **kwargs):
        instructions = self.abstractboard.decrement_variation()
        self.follow_instructions(instructions)

    # Syncing
    def reset_abstractboard(self):
        self.clear_transient_widgets()
        self.reset_uielements()
        self.clear_stones()
        instructions = self.abstractboard.reset_position()
        self.get_player_details()
        self.follow_instructions(instructions)
        self.gameinfo = self.abstractboard.get_gameinfo()

    def reset_gridsize(self, newsize):
        self.gridsize = newsize
        self.abstractboard = AbstractBoard(gridsize=newsize)
        print 'New gridsize is', self.gridsize
        print 'New abstractboard gridsize', self.abstractboard.game.size
Пример #4
0
 def __init__(self, *args, **kwargs):
     super(GuiBoard, self).__init__(*args, **kwargs)
     print 'GuiBoard init, making abstractboard with gridsize', self.gridsize
     self.abstractboard = AbstractBoard(gridsize=self.gridsize)
     self.reset_abstractboard()
Пример #5
0
class Board(Widget):
    grid_x = NumericProperty(15)
    grid_y = NumericProperty(19)
    grid = ReferenceListProperty(grid_x, grid_y)

    shape_x = NumericProperty(15)
    shape_y = NumericProperty(19)
    shape = ReferenceListProperty(shape_x, shape_y)

    padding_x = NumericProperty(0)
    padding_y = NumericProperty(0)
    padding = ReferenceListProperty(padding_x, padding_y)

    cell_size_x = NumericProperty()
    cell_size_y = NumericProperty()
    cell_size = ReferenceListProperty(cell_size_x, cell_size_y)

    portrait = BooleanProperty()  # True if shape_x < shape_y
    aspect_ratio = NumericProperty()

    player = OptionProperty('bottom', options=['top', 'bottom'])

    board_image = StringProperty('boards/edphoto_section_light.png')

    grid_points = ListProperty([])
    goal_rectangle_size = ListProperty([0, 0])
    top_rectangle_pos = ListProperty([0, 0])
    bottom_rectangle_pos = ListProperty([0, 0])

    ball = ObjectProperty(None, allownone=True)
    men = DictProperty({})
    legal_move_markers = DictProperty({})
    speculative_segment_markers = DictProperty({})

    abstractboard = ObjectProperty()
    use_ai = BooleanProperty(False)
    move_marker = ObjectProperty()
    touch = ObjectProperty(None, allownone=True)

    message = StringProperty('')

    current_player = OptionProperty('top', options=['top',
                                                    'bottom'])
    touch_mode = StringProperty('play_man', options=['play_man',
                                                     'move_ball',
                                                     'toggle_man',
                                                     'dormant'])
    can_confirm = BooleanProperty(False)
    touch_offset = NumericProperty(0)

    game_mode = StringProperty('normal')
    '''Property used to know what to do at the end of the game, e.g.
    return to menu, offer a new game, or more forward in the tutorials
    or puzzles.'''

    show_legal_moves = BooleanProperty(True)

    def __init__(self, *args, **kwargs):
        self.register_event_type('on_win')
        if 'use_ai' in kwargs:
            use_ai = kwargs.pop('use_ai')
        else:
            use_ai = False
        super(Board, self).__init__(*args, **kwargs)
        self.abstractboard = AbstractBoard(shape=self.grid)
        self.abstractboard.reset()
        self.use_ai = use_ai
#        Clock.schedule_once(self.initialise_ball, 0)
        #self.initialise_ball()

    def on_win(self, winner):
        # import ipdb
        # ipdb.set_trace()
        mode = self.game_mode
        print('mode is', mode)
        if mode[:8] == 'tutorial':
            number = int(mode[8:]) + 1
            if winner == 'bottom':
                number -= 1
            next_file = 'puzzles/dir01_tutorials/tutorial{}.phut'.format(number)
            next_mode = 'tutorial{}'.format(number)
            print('next file is', next_file, exists(next_file))
            if exists(next_file):
                if winner == 'bottom':
                    winner_text = 'You lose'
                    tutorial_text = 'Do you want to try again?'
                    next_text = 'Try again'
                else:
                    winner_text = '[color=#dbebc3]You win![/color]'
                    tutorial_text = 'Tutorial {} complete'.format(number-1)
                    next_text = 'Next tutorial'
                NextTutorialPopup(number=str(number-1),
                                  next_file=next_file,
                                  next_mode=next_mode,
                                  winner_text=winner_text,
                                  tutorial_text=tutorial_text,
                                  next_text=next_text).open()
            else:
                FinishedTutorialsPopup(number=str(number)).open()
        elif mode == 'ainormal':
            winner_text = {
                'top': '[color=#dbebc3]You win![/color]',
                'bottom': '[color=#ffcab2]You lose[/color]'}[winner]
            PlayAgainPopup(ai=True, winner_text=winner_text,
                           next_mode='ainormal').open()
        else:
            winner_text = '[color=#ffffff]{} player wins[/color]'.format(
                winner)
            PlayAgainPopup(ai=False, winner_text=winner_text,
                           next_mode='normal').open()

    def on_touch_mode(self, *args):
        mode = self.touch_mode
        if mode == 'play_man':
            self.abstractboard.reset_speculation()
            self.clear_transient_ui_elements()
            self.display_legal_moves()
            self.move_marker.mode = 'play_man'
        else:
            self.move_marker.mode = 'move_ball'

    def advance_player(self):
        if self.player == 'bottom':
            self.player = 'top'
        else:
            self.player = 'bottom'

    def check_for_win(self):
        '''Checks if either player has won, i.e. that the ball is in one of
        the goals.'''
        winner = self.abstractboard.check_for_win()
        if winner == 'top':
            self.dispatch('on_win', 'top')
        elif winner == 'bottom':
            self.dispatch('on_win', 'bottom')

    def follow_instructions(self, instructions):
        '''Takes instructions from an AbstractBoard and uses them to update
        the gui.'''

        if instructions is None:
            return  # Nothing changes

        if 'add' in instructions:
            add_coords = instructions['add']
            for coords in add_coords:
                self.add_man(coords)
        if 'remove' in instructions:
            remove_coords = instructions['remove']
            for coords in remove_coords:
                self.remove_man(coords)
        if 'speculative_marker' in instructions:
            speculative_markers = instructions['speculative_marker']
            self.sync_speculative_segment_markers(speculative_markers)
        if 'conflicting_paths' in instructions:
            conflicting_markers = instructions['conflicting_paths']
            self.draw_conflicting_markers(conflicting_markers)
        if 'clear_transient' in instructions:
            self.clear_transient_ui_elements()
            self.display_legal_moves()
        if 'move_ball_to' in instructions:
            ball_coords = instructions['move_ball_to']
            ball = self.ball
            ball.coords = ball_coords
            ball.pos = self.coords_to_pos(ball_coords)

    def draw_conflicting_markers(self, components):
        end_coords, paths = components
        end_pos = (Vector(self.coords_to_pos(end_coords)) +
                   Vector(self.cell_size)/2.)
        lines = []
        for path in paths:
            path = [Vector(self.coords_to_pos(coords)) +
                    Vector(self.cell_size)/2.
                    for coords in path]
            points = []
            for entry in path:
                points.append(entry[0])
                points.append(entry[1])
            points.append(end_pos[0])
            points.append(end_pos[1])
            lines.append(points)

        anim = Animation(opacity=0, duration=0.75, t='out_quad')
        for line in lines:
            marker = ConflictingSegmentMarker(points=line)
            self.add_widget(marker)
            anim.start(marker)
            anim.bind(on_complete=self.remove_widget_from_anim)

    def remove_widget_from_anim(self, animation, widget):
        self.remove_widget(widget)

    def sync_speculative_segment_markers(self, new_markers):
        existing_markers = self.speculative_segment_markers
        for identifier in new_markers:
            if identifier not in existing_markers:
                self.add_speculative_segment_marker(identifier)
        for identifier in list(existing_markers.keys()):
            if identifier not in new_markers:
                self.remove_speculative_segment_marker(identifier)

    def add_speculative_segment_marker(self, identifier):
        if identifier in self.speculative_segment_markers:
            return
        start_coords = tuple(identifier[:2])
        end_coords = tuple(identifier[2:])
        start_pos = (Vector(self.coords_to_pos(start_coords)) +
                     Vector(self.cell_size)/2.)
        end_pos = (Vector(self.coords_to_pos(end_coords)) +
                   Vector(self.cell_size)/2.)
        marker = SpeculativeSegmentMarker(start_coords=start_coords,
                                          end_coords=end_coords,
                                          start_pos=start_pos,
                                          end_pos=end_pos)
        self.add_widget(marker)
        self.speculative_segment_markers[identifier] = marker

    def remove_speculative_segment_marker(self, identifier):
        if identifier not in self.speculative_segment_markers:
            return
        marker = self.speculative_segment_markers.pop(identifier)
        self.remove_widget(marker)

    def clear_speculative_segment_markers(self):
        for identifier in list(self.speculative_segment_markers.keys()):
            self.remove_speculative_segment_marker(identifier)

    def add_man(self, coords):
        '''Adds a man (a black piece) at the given coordinates.'''
        coords = tuple(coords)
        if coords in self.men or (coords[0] == self.ball.coords[0] and
                                  coords[1] == self.ball.coords[1]):
            return
        man = Man(coords=coords)
        self.men[coords] = man
        man.pos = self.coords_to_pos(coords)
        man.size = self.cell_size
        self.add_widget(man)

    def remove_man(self, coords):
        '''Removes the man at the given coords, if one exists.'''
        coords = tuple(coords)
        if coords not in self.men:
            return
        man = self.men.pop(coords)
        self.remove_widget(man)

    def clear_men(self):
        '''Removes all men from the gui board.'''
        for coords in list(self.men.keys()):
            self.remove_man(coords)

    def toggle_man(self, coords):
        '''Toggles a man at the given coords.'''
        coords = tuple(coords)
        if coords == self.abstractboard.ball_coords:
            return
        if coords in self.men:
            self.remove_man(coords)
        else:
            self.add_man(coords)

    def add_legal_move_marker(self, coords):
        '''Toggles a LegalMoveMarker at the given coords.'''
        coords = tuple(coords)
        if coords in self.legal_move_markers:
            return
        marker = LegalMoveMarker(pos=self.coords_to_pos(coords),
                                 size=self.cell_size,
                                 coords=coords)
        self.legal_move_markers[coords] = marker
        self.add_widget(marker)

    def remove_legal_move_marker(self, coords):
        '''Removes any LegalMoveMarker at the given coords.'''
        coords = tuple(coords)
        if coords not in self.legal_move_markers:
            return
        marker = self.legal_move_markers.pop(coords)
        self.remove_widget(marker)

    def clear_legal_move_markers(self):
        for marker_coords in list(self.legal_move_markers.keys()):
            marker = self.legal_move_markers.pop(marker_coords)
            self.remove_widget(marker)

    def clear_transient_ui_elements(self, *args):
        '''Removes any transient ui elements, e.g. LegalMoveMarkers.'''
        self.clear_legal_move_markers()
        self.clear_speculative_segment_markers()

    def reposition_ui_elements(self, *args):
        '''Checks the coords of any ui elements (stones , rectangles etc.),
        and repositions them appropriately with respect to the
        board. Called on resize/position.

        '''
        if self.ball is not None:
            self.ball.pos = self.coords_to_pos(self.abstractboard.ball_coords)
            self.ball.size = self.cell_size
        for man_coords, man in self.men.items():
            man.pos = self.coords_to_pos(man.coords)
            man.size = self.cell_size
        for marker_coords, marker in self.legal_move_markers.items():
            marker.pos = self.coords_to_pos(marker.coords)
            marker.size = self.cell_size
        self.goal_rectangle_size = (Vector([self.grid[0], 2]) *
                                    Vector(self.cell_size))
        self.top_rectangle_pos = self.coords_to_pos((0, self.grid[1]-2))
        self.bottom_rectangle_pos = self.coords_to_pos((0, 0))

        cell_size = self.cell_size
        for marker_coords, marker in self.speculative_segment_markers.items():
            start_coords = marker.start_coords
            end_coords = marker.end_coords
            start_pos = (Vector(self.coords_to_pos(start_coords)) +
                         Vector(self.cell_size)/2.)
            end_pos = (Vector(self.coords_to_pos(end_coords)) +
                       Vector(self.cell_size)/2.)
            marker.start_pos = start_pos
            marker_end_pos = end_pos

        self.move_marker.size = cell_size
        self.move_marker.on_coords()

    def on_cell_size(self, *args):
        cell_size = self.cell_size
        if self.ball:
            self.ball.size = self.cell_size
        for man_coords in self.men:
            man = self.men[man_coords]
            man.size = self.cell_size
        for marker_coords, marker in self.legal_move_markers.items():
            marker.size = self.cell_size
        for marker_coords, marker in self.speculative_segment_markers.items():
            start_coords = marker.start_coords
            end_coords = marker.end_coords
            start_pos = (Vector(self.coords_to_pos(start_coords)) +
                         Vector(self.cell_size)/2.)
            end_pos = (Vector(self.coords_to_pos(end_coords)) +
                       Vector(self.cell_size)/2.)
            marker.start_pos = start_pos
            marker_end_pos = end_pos

    def initialise_ball(self, *args):
        if self.ball is None:
            self.ball = Ball()
            self.ball.size = self.cell_size
            self.add_widget(self.ball)

        centre_coords = list(map(int, Vector(self.grid)/2.0))
        self.ball.pos = self.coords_to_pos(centre_coords)
        self.ball.coords = centre_coords

        self.abstractboard.ball_coords = centre_coords
        self.abstractboard.speculative_ball_coords = centre_coords

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            self.touch = touch
            touch.grab(self)
            self.move_marker.anim_in()
            self.on_touch_move(touch)
        
    def on_touch_move(self, touch):
        if touch is not self.touch:
            return
        coords = self.pos_to_coords(touch.pos)
        coords = (coords[0], coords[1] + self.touch_offset)
        self.move_marker.coords = coords

    def on_touch_up(self, touch):
        if touch is not self.touch:
            return
        touch.ungrab(self)
        coords = self.pos_to_coords(touch.pos)
        self.do_move_at(coords)
        self.move_marker.anim_out()

    def do_move_at(self, coords):
        coords = tuple(coords)
        mode = self.touch_mode

        # Check if move is valid
        if coords in self.men:
            return
        if coords == tuple(self.ball.coords):
            return
        
        if mode == 'dormant':
            return
        elif mode == 'toggle_man':
            self.follow_instructions(self.abstractboard.toggle_man(coords))
        elif mode == 'play_man':
            instructions = self.abstractboard.play_man_at(coords)
            self.follow_instructions(instructions)
            if instructions is not None:
                self.advance_player()
            self.clear_speculative_segment_markers()
            self.switch_current_player()
        elif mode == 'move_ball':
            instructions = self.abstractboard.speculative_move_ball_to(coords)
            self.follow_instructions(instructions)

        self.clear_legal_move_markers()
        self.display_legal_moves()

    def on_current_player(self, *args):
        self.abstractboard.current_player = self.current_player

    def switch_current_player(self):
        self.current_player = {'top': 'bottom',
                               'bottom': 'top'}[self.current_player]
        if self.use_ai and self.current_player == 'bottom':
            self.do_ai_move()

    def do_ai_move(self, *args):
        self.abstractboard.do_ai_move()
        self.confirm_speculation()

    def confirm_speculation(self):
        instructions = self.abstractboard.confirm_speculation()
        if instructions is None:
            return
        self.follow_instructions(instructions)
        self.check_for_win()
        self.switch_current_player()
        self.touch_mode = 'play_man'

    def display_legal_moves(self, force=False):
        if self.show_legal_moves or force:
            legal_moves = self.abstractboard.speculative_legal_moves
            for coords in legal_moves:
                self.add_legal_move_marker(coords)

    def pos_to_coords(self, pos):
        '''Takes a pos in screen coordinates, and converts to a grid
        position.'''

        pos = Vector(pos)
        cell_size = Vector(self.cell_size)
        self_pos = Vector(self.pos) + Vector(cell_size) / 2.0
        padding = Vector(self.padding)
        diff = pos - (self_pos + padding * cell_size)
        number_of_steps = diff / cell_size

        return tuple(map(int, map(round, number_of_steps)))

    def coords_to_pos(self, coords):
        '''Takes coords on the board grid, and converts to a screen
        position.'''
        cell_size = Vector(self.cell_size)
        self_pos = Vector(self.pos)
        padding = Vector(self.padding)
        return self_pos + (padding + Vector(coords)) * cell_size

    def calculate_lines(self, *args):
        '''Calculates the points that should make up the board lines, and sets
        self.grid_points appropriately.'''

        pos = Vector(self.pos)
        padding = Vector(self.padding)
        shape = Vector(self.shape)
        grid = Vector(self.grid)
        cell_size = Vector(self.cell_size)

        # Initial offset
        init_offset = cell_size / 2.

        # grid corners
        bl = pos + init_offset + padding*cell_size
        br = bl + Vector((grid[0]-1) * cell_size[0], 0)
        tr = bl + (grid-Vector(1, 1)) * cell_size
        tl = bl + Vector(0, (grid[1]-1) * cell_size[1])

        points = [bl[0], bl[1], br[0], br[1],
                  tr[0], tr[1], tl[0], tl[1],
                  bl[0], bl[1]]

        cur_pos = bl
        dir = 1
        for x in range(grid[0]-1):
            cur_pos[0] += cell_size[0]
            points.append(cur_pos[0])
            points.append(cur_pos[1])
            cur_pos[1] += (grid[1]-1) * cell_size[1] * dir
            points.append(cur_pos[0])
            points.append(cur_pos[1])
            dir *= -1

        ydir = -1
        for y in range(grid[1]-1):
            cur_pos[1] += cell_size[1] * dir
            points.append(cur_pos[0])
            points.append(cur_pos[1])
            cur_pos[0] += (grid[0]-1) * cell_size[0] * ydir
            points.append(cur_pos[0])
            points.append(cur_pos[1])
            ydir *= -1

        self.grid_points = points

    def save_position(self, filen):
        '''Asks the AbstractBoard to save in the given filename.'''
        self.abstractboard.save_state(filen)

    def load_position(self, filen):
        '''Tries to load position from the given filename.'''
        self.abstractboard.load_file(filen)
        self.resync_with_abstractboard()
        

    def clear_all_transient_widgets(self):
        '''Clears all transient stones, markers etc.'''
        self.clear_transient_ui_elements()
        self.clear_men()
        self.clear_legal_move_markers()

    def resync_with_abstractboard(self):
        ab = self.abstractboard
        self.clear_all_transient_widgets()
        self.shape = ab.shape
        for coords in ab.man_coords:
            self.add_man(coords)
        self.display_legal_moves()
        Clock.schedule_once(self.sync_ball, 0)
        print('ab ball_coords are', ab.ball_coords)
        self.message = ab.message

    def sync_ball(self, *args):
        print('syncing ab ball_coords are', self.abstractboard.ball_coords)
        self.ball.pos = self.coords_to_pos(self.abstractboard.ball_coords)

    def reset(self, *args, **kwargs):
        self.abstractboard.reset()
        self.clear_all_transient_widgets()
        #self.clear_legal_move_markers()
        self.resync_with_abstractboard()
        self.initialise_ball()
        self.message = ''
        self.touch_mode = (kwargs['touch_mode'] if 'touch_mode' in kwargs
                           else 'play_man')
        self.game_mode = (kwargs['game_mode'] if 'game_mode' in kwargs
                          else 'normal')
Пример #6
0
 def reset_gridsize(self,newsize):
     self.gridsize = newsize
     self.abstractboard = AbstractBoard(gridsize=newsize)
     print 'New gridsize is', self.gridsize
     print 'New abstractboard gridsize', self.abstractboard.game.size
Пример #7
0
class GuiBoard(Widget):
    gridsize = NumericProperty(19) # Board size
    navmode = StringProperty('Navigate') # How to scale the board
    abstractboard = ObjectProperty(None,allownone=True) # Object to query for where to play moves
    uielements = DictProperty({})
    makemovemarker = ObjectProperty(None,allownone=True)
    touchoffset = ListProperty([0,0])
    guesses = ListProperty([0,0])
    gameinfo = DictProperty({})

    # Save state
    user_saved = BooleanProperty(False)
    temporary_filepath = StringProperty('')
    permanent_filepath = StringProperty('')
    has_unsaved_data = BooleanProperty(False)

    # Score mode 
    ld_markers = DictProperty({})
    scoreboard = ObjectProperty(None,allownone=True)

    variations_exist = BooleanProperty(False)

    showcoords = BooleanProperty(False)

    wname = StringProperty('')
    wrank = StringProperty('')
    bname = StringProperty('')
    brank = StringProperty('')
    next_to_play = StringProperty('e')


    comment_pre_text = StringProperty('')
    comment_text = StringProperty('')

    
    

    # Board flipping
    flip_horiz = BooleanProperty(False)
    flip_vert = BooleanProperty(False)
    flip_forwardslash = BooleanProperty(True)
    flip_backslash = BooleanProperty(False)

    # Transient widgets
    playmarker = ObjectProperty(None,allownone=True) # Circle marking last played move
    boardmarkers = DictProperty({})
    guesspopup = ObjectProperty(None,allownone=True)
    varstones = DictProperty({})

    # Coordinates widget
    coordinate_letter = 'abcdefghjklmnopqrstuv'
    coordinate_number = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19']
    coordinates = BooleanProperty(False)
    coordinate_labels = ListProperty([])
    def on_coordinates(self,obj,val):
        print 'on_coordinates',obj,val
        if val:
            print 'adding coordinates'
            self.add_coordinates()
        else:
            print 'removing coordinates'
            self.remove_coordinates()

    stones = DictProperty({})
    starpoints = DictProperty()
    starpoint_positions = DictProperty(starposs)

    gobansize = ListProperty((100,100))
    numcells = NumericProperty(10)
    boardindent = ListProperty((100,100))
    stonesize = ListProperty((100,100))
    gridspacing = NumericProperty(10)
    gridlines = ListProperty([])

    gobanpos = ListProperty((100,100))

    def __init__(self,*args,**kwargs):
        super(GuiBoard,self).__init__(*args,**kwargs)
        print 'GuiBoard init, making abstractboard with gridsize', self.gridsize
        self.abstractboard = AbstractBoard(gridsize=self.gridsize)
        self.reset_abstractboard()

    def add_handicap_stones(self,num):
        print 'asked to add handicap stones',num
        if handicap_positions.has_key(self.gridsize):
            stone_positions = handicap_positions[self.gridsize]
            if stone_positions.has_key(num):
                stone_coords = stone_positions[num]
                print 'handicap positions are',stone_coords
                for coord in stone_coords:
                    self.toggle_background_stone(coord,'b')
        self.next_to_play = 'w'

    def start_autoplay(self,*args,**kwargs):
        Clock.schedule_interval(self.advance_one_move,0.25)
        self.pre_text = '[b]Autoplay[/b] activated. Tap on the navigation buttons (or the board in navigation mode) to stop autoplaying.'
    def stop_autoplay(self,*args,**kwargs):
        try:
            Clock.unschedule(self.advance_one_move)
        except:
            pass

    def set_game_info(self,info):
        print 'asked to set with info',info
        self.abstractboard.set_gameinfo(info)
        self.get_game_info()

    def get_game_info(self):
        self.gameinfo = self.abstractboard.get_gameinfo()
        self.get_player_details()
        if not self.user_saved:
            if self.gameinfo.has_key('filepath'):
                self.permanent_filepath = self.gameinfo['filepath']

    def view_game_info(self):
        gi = GameInfo(board=self)
        gi.populate_from_gameinfo(self.gameinfo)
        popup = Popup(content=gi,title='Game info.',size_hint=(0.85,0.85))
        popup.content.popup = popup
        popup.open()

    def save_sgf(self,saveas=False,autosave=False,refresh=True):
        # if refresh and self.permanent_filepath != '':
        #     newn = self.build_savefile_name()
        #     newns = newn.split('_')
        #     curn = self.permanent_filepath
        #     curns = curn.split('_')
        if autosave:
            if self.permanent_filepath != '':
                self.abstractboard.save_sgf(self.permanent_filepath)
            else:
                if self.temporary_filepath == '':
                    self.temporary_filepath = get_temp_filepath()
                self.abstractboard.save_sgf(self.temporary_filepath)
        elif saveas:
            self.ask_where_to_save()
        else:
            if self.permanent_filepath != '':
                self.abstractboard.save_sgf(self.permanent_filepath)
            else:
                self.ask_where_to_save()

    def ask_where_to_save(self,force=True):
        sq = SaveQuery(board=self)
        popup = Popup(content=sq,title='Where to save?',size_hint=(0.85,0.85))
        popup.content.popup = popup
        fileh = open('game_collection_locations.json','r')
        collection_folders = jsonload(fileh)
        fileh.close()
        collections_args_converter = get_collectioninfo_from_dir
        list_adapter = ListAdapter(data=collection_folders,
                                   args_converter=collections_args_converter,
                                   selection_mode='single',
                                   allow_empty_selection=True,
                                   cls=CollectionChooserButton
                                   )
        sq.collections_list.adapter = list_adapter
        popup.open()

    def make_savefile_in_dir(self,dirn):
        filen = self.build_savefile_name(dirn)
        self.permanent_filepath = filen
        self.user_saved = True
        self.save_sgf()
    def build_savefile_name(self,dirn):
        filen = ''.join((dirn,'/',asctime().replace(' ','_')))
        if 'wname' in self.gameinfo:
            filen += '_' + self.gameinfo['wname']
        else:
            filen += '_' + 'wunknown'
        if 'bname' in self.gameinfo:
            filen += '_' + self.gameinfo['bname']
        else:
            filen += '_' + 'bunknown'
        if 'event' in self.gameinfo:
            filen += '_' + self.gameinfo['event']
        else:
            filen += '_' + 'eunknown'
        filen += '.sgf'
        return filen
        

    def back_to_varbranch(self):
        instructions = self.abstractboard.jump_to_varbranch()
        self.follow_instructions(instructions)

    def take_stone_input(self,coords):
        if tuple(coords) not in self.stones:
            if self.navmode == 'Play':
                existingvars = map(lambda j: j.get_move(),self.abstractboard.curnode)
                alreadyexists = False
                for entry in existingvars:
                    if entry[0] == self.next_to_play and entry[1][0] == coords[0] and entry[1][1] == coords[1]:
                        instructions = self.abstractboard.jump_to_node(self.abstractboard.curnode[existingvars.index(entry)])
                        print 'entry already exists!'
                        self.follow_instructions(instructions)
                        return True
                children_exist = self.abstractboard.do_children_exist()
                if not children_exist:
                    self.add_new_stone(coords)
                else:
                    popup = Popup(content=PickNewVarType(board=self,coord=coords),title='Do you want to...',size_hint=(0.85,0.85))
                    popup.content.popup = popup
                    popup.open()
            elif self.navmode == 'Guess':
                self.guesses[1] += 1
                nextcoords = self.abstractboard.get_next_coords()
                if nextcoords[0] is not None and nextcoords[1] is not None:
                    correct = False
                    if coords[0] == nextcoords[0] and coords[1] == nextcoords[1]:
                        self.guesses[0] += 1
                        correct = True
                        instructions = self.abstractboard.advance_position()
                        self.follow_instructions(instructions)
                    pre_text = '%.1f%% correct' % (100*float(self.guesses[0])/self.guesses[1])
                    if not correct:
                        off_by_x = abs(coords[0]-nextcoords[0])
                        off_by_y = abs(coords[1]-nextcoords[1])
                        self.set_guess_popup(coords,max(off_by_x,off_by_y))
                        pre_text = '[color=ff0000]Wrong[/color] - ' + pre_text
                    else:
                        pre_text = '[color=00ff00]Correct![/color] - ' + pre_text
                    pre_text += '\n-----\n'
                    self.comment_pre_text = pre_text
                    
    def set_guess_popup(self,centre, size):
        if self.guesspopup is not None:
            self.remove_widget(self.guesspopup)
            self.guesspopup = None
        centrecoords = self.coord_to_pos(centre)
        cx,cy = centrecoords
        lr = (cx - (size+0.25)*self.stonesize[0], cy - (size+0.25)*self.stonesize[1])
        tr = (cx + (size+1.25)*self.stonesize[0], cy + (size+1.25)*self.stonesize[1])
        markerpos = lr
        markersize = (tr[0]-lr[0],tr[1]-lr[1])
        markercolour = [0. + size/(0.5*self.gridsize), 1. - size/(0.5*self.gridsize), 0.]
        gp = GuessPopup(pos=markerpos, size=markersize, colour=markercolour,alpha=0.1)
        self.guesspopup = gp
        ani = Animation(alpha=1.0,t='in_out_quad',duration=0.2) + Animation(alpha=(0.15),t='in_out_quad', duration=0.5)
        #ani.bind(on_complete=self.remove_guess_popup)
        ani.start(gp)
        self.add_widget(gp)

    def remove_guess_popup(self,*args,**kwargs):
        if self.guesspopup is not None:
            self.remove_widget(self.guesspopup)
            self.guesspopup = None

    def toggle_background_stone(self,coords,colour='b',force='toggle'):
        instructions = self.abstractboard.toggle_background_stone(coords,colour,force)
        print 'toggle background got instructions',instructions
        self.follow_instructions(instructions)

    def add_new_stone(self,coords,newtype='newvar'):
        print 'Called add_new_stone', coords, newtype
        colour = self.next_to_play
        if newtype == 'newvar':
            instructions = self.abstractboard.add_new_node(coords,self.next_to_play)
            self.follow_instructions(instructions)
        if newtype == 'newmain':
            instructions = self.abstractboard.add_new_node(coords,self.next_to_play,newmainline=True)
            self.follow_instructions(instructions)
        if newtype == 'replacenext':
            instructions = self.abstractboard.replace_next_node(coords,self.next_to_play)
            self.follow_instructions(instructions)
        if newtype == 'insert':
            instructions = self.abstractboard.insert_before_next_node(coords,self.next_to_play)
            self.follow_instructions(instructions)
        print 'add_new_stone received instructions:',instructions

    def open_sgf_dialog(self,*args,**kwargs):
        popup = Popup(content=OpenSgfDialog(board=self),title='Open SGF',size_hint=(0.85,0.85))
        popup.content.popup = popup
        popup.open()

    def load_sgf_from_file(self,path,filen):
        print 'asked to load from',path,filen
        self.abstractboard.load_sgf_from_file(filen[0])
        self.permanent_filepath = self.abstractboard.filepath
        self.reset_abstractboard()

    def get_new_comment(self,*args,**kwargs):
        print 'get new comment called'
        if self.comment_text == '[color=444444]Long press to add comment.[/color]':
            popup = Popup(content=CommentInput(board=self,comment=''),title='Edit comment:',size_hint=(0.85,0.85))
        else:
            popup = Popup(content=CommentInput(board=self,comment=self.comment_text),title='Edit comment:',size_hint=(0.85,0.55),pos=(0.075*Window.width, 0.95*Window.height))
        popup.content.popup = popup
        if platform() == 'android':
            import android
            android.vibrate(0.1)
        popup.open()

    def set_new_comment(self,comment):
        self.comment_text = comment
        self.abstractboard.curnode.set('C',comment)

    def clear_ld_markers(self):
        for coords in self.ld_markers:
            marker = self.ld_markers[coords]
            self.remove_widget(marker)
        self.ld_markers = {}
        print 'new self.ld_markers', self.ld_markers

    def make_scoreboard(self):
        if self.scoreboard is not None:
            self.scoreboard = None
        sb = ScoreBoard(self.gridsize)
        sb.board = self.abstractboard.get_current_boardpos()
        self.scoreboard = sb

    def set_navmode(self,spinner,mode):
        self.scoreboard = None
        self.clear_ld_markers()
        if mode != 'Guess':
            self.remove_guess_popup()
        self.navmode = mode
        if mode == 'Navigate':
            self.comment_pre_text = navigate_text + '\n-----\n'
        elif mode == 'Play':
            self.comment_pre_text = play_text + '\n-----\n'
        elif mode == 'Score':
            self.make_scoreboard()
            score = self.scoreboard.get_score()
            self.comment_pre_text = score_text + '\n-----\n'
        elif mode == 'Guess':
            self.comment_pre_text = guess_text + '\n-----\n'
        elif mode == 'Zoom':
            self.comment_pre_text = zoom_text + '\n-----\n'


    def clear_transient_widgets(self):
        self.remove_playmarker()
        # self.remove_komarker()
        self.clear_markers()
        self.clear_variation_stones()

    ## Board markers
    def toggle_ld_marker(self,coord):
        if self.ld_markers.has_key(coord):
            existingmarker = self.ld_markers.pop(coord)
            self.remove_widget(existingmarker)
        else:
            newmarker = LDMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
            self.add_widget(newmarker)
            self.ld_markers[coord] = newmarker
    def add_marker(self,coord,mtype,other=[]):
        print 'adding marker:', coord, mtype
        if self.boardmarkers.has_key(coord):
            existingmarker = self.boardmarkers.pop(coord)
            self.remove_widget(existingmarker)
            
        if mtype == 'triangle':
            newmarker = TriangleMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        elif mtype == 'square':
            newmarker = SquareMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        elif mtype == 'circle':
            newmarker = CircleMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        elif mtype == 'cross':
            newmarker = CrossMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        elif mtype == 'text':
            newmarker = TextMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
            newmarker.text = other[0]
        else:
            return None
            
        self.colour_marker_for_contrast(coord,newmarker)
        self.add_widget(newmarker)
        self.boardmarkers[coord] = newmarker

    def remove_marker(self,coord):
        if self.boardmarkers.has_key(coord):
            marker = self.boardmarkers.pop(coord)
            self.remove_widget(marker)            

    def clear_markers(self):
        for coord in self.boardmarkers.keys():
            marker = self.boardmarkers.pop(coord)
            self.remove_widget(marker)

    def update_markers(self):
        for coord in self.boardmarkers.keys():
            marker = self.boardmarkers[coord]
            marker.size = self.stonesize
            marker.pos = self.coord_to_pos(coord)
            self.remove_widget(marker)
            self.add_widget(marker)
            
            

    def marker_colour(self, coord):
        if self.stones.has_key(coord):
            stone_colour = self.stones[coord].colour
            return [1-stone_colour[0],1-stone_colour[1],1-stone_colour[2]]
        else:
            return [0,0,0]

    def colour_marker_for_contrast(self, coord, marker):
        markercolour = self.marker_colour(coord)
        marker.markercolour = markercolour
                

    ## Playmarker
    def set_playmarker(self,coord):
        self.remove_widget(self.playmarker)
        marker = PlayMarker(size=self.stonesize, pos=self.coord_to_pos(coord))
        self.colour_marker_for_contrast(coord,marker)
        marker.coord = coord
        self.add_widget(marker)
        self.playmarker = marker

    def remove_playmarker(self):
        self.remove_widget(self.playmarker)
        self.playmarker = None

    def update_playmarker(self):
        if self.playmarker is not None:
            self.set_playmarker(self.playmarker.coord)
        self.set_playmarker

    def on_size(self,*args,**kwargs):
        print '%%% ON_SIZE %%%'
        self.gobanpos = self.pos
        self.gridlines = self.get_gridlines()

        self.update_starpoints()
        self.update_stones()
        self.update_playmarker()
        self.update_markers()
        self.update_coordinates()

    def on_pos(self,*args,**kwargs):
        self.on_size()

    def on_gobanpos(self,*args,**kwargs):
        self.gridlines = self.get_gridlines()

        self.update_starpoints()
        self.update_stones()
        self.update_playmarker()
        self.update_markers()

    def coord_to_pos(self, coord,dotransformations=True):
        gridspacing = self.gridspacing
        realcoord = [coord[0],coord[1]]
        if dotransformations:
            if self.flip_horiz:
                realcoord[0] = self.game.size - 1 - realcoord[0]
            if self.flip_vert:
                realcoord[1] = self.game.size - 1 - realcoord[1]
            if self.flip_forwardslash:
                realcoord = realcoord[::-1]
            if self.flip_backslash:
                realcoord = realcoord[self.game.size - 1 - realcoord[0],self.game.size - 1 - realcoord[1]][::-1]

        coord = realcoord
        
        coord = (coord[0]-0.5,coord[1]-0.5)
        return (self.gobanpos[0] + self.boardindent[0] + coord[0]*gridspacing, self.gobanpos[1] + self.boardindent[1] + coord[1]*gridspacing)

    def pos_to_coord(self,pos):
        gridspacing = self.gridspacing
        relx = (pos[0] - (self.gobanpos[0] + self.boardindent[0])) / gridspacing
        rely = (pos[1] - (self.gobanpos[1] + self.boardindent[1])) / gridspacing
        relx += self.touchoffset[0]
        rely += self.touchoffset[1]
        realcoord = (int(round(relx)),int(round(rely)))
        if self.flip_horiz:
            realcoord[0] = self.game.size - 1 - realcoord[0]
        if self.flip_vert:
            realcoord[1] = self.game.size - 1 - realcoord[1]
        if self.flip_forwardslash:
            realcoord = realcoord[::-1]
        if self.flip_backslash:
            realcoord = realcoord[self.game.size - 1 - realcoord[0],self.game.size - 1 - realcoord[1]][::-1]
        return realcoord

    def get_gridlines(self):
        startx = self.boardindent[0] + self.gobanpos[0]
        starty = self.boardindent[1] + self.gobanpos[1]
        gridspacing = self.gridspacing
        length = self.boardlength
        gridnum = self.gridsize

        gridline = []

        curx = startx
        cury = starty

        dir = 1.0
        for y in range(self.gridsize - 1):
            curx += dir*length
            gridline.append([curx,cury])
            cury += gridspacing
            gridline.append([curx,cury])
            dir *= -1
        dir *= -1
        for x in range(self.gridsize - 1):
            cury += dir*length
            gridline.append([curx,cury])
            curx += gridspacing
            gridline.append([curx,cury])
            dir *= -1

        return reduce(lambda j,k: j+k, gridline)

        
    # Stone methods
    def follow_instructions(self,instructions,*args,**kwargs):
        print '### instructions are', instructions

        t1 = time()
        
        self.clear_transient_widgets()
        self.reset_uielements()
        self.remove_guess_popup()

        t2 = time()
        
        if 'remove' in instructions:
            remove_stones = instructions['remove']
            for stone in remove_stones:
                self.remove_stone(coord=stone[0],colour=colourname_to_colour(stone[1]))
        if 'add' in instructions:
            add_stones = instructions['add']
            for stone in add_stones:
                self.add_stone(coord=stone[0],colour=colourname_to_colour(stone[1]))
        if 'empty' in instructions:
            empty_stones = instructions['empty']
            for stone in empty_stones:
                self.empty_stone(coord=stone[0])

        t3 = time()

        if 'playmarker' in instructions:
            pm = instructions['playmarker']
            print 'Asked to draw pm at', pm
            if pm is not None:
                self.set_playmarker(pm)
        if 'markers' in instructions:
            markers = instructions['markers']
            print 'received markers:', markers
            for marker in markers:
                if marker[1] == 'TR':
                    self.add_marker(marker[0],'triangle')
                elif marker[1] == 'SQ':
                    self.add_marker(marker[0],'square')
                elif marker[1] == 'CR':
                    self.add_marker(marker[0],'circle')
                elif marker[1] == 'MA':
                    self.add_marker(marker[0],'cross')
                elif marker[1] == 'LB':
                    self.add_marker(marker[0],'text',marker[2:])
        if 'variations' in instructions:
            curvar, varnum = instructions['variations']
            if varnum > 1:
                if self.uielements.has_key('varbutton'):
                    for button in self.uielements['varbutton']:
                        button.background_color = [0,1,0,1]
                        button.text = 'Next var\n  (%d / %d)' % (curvar, varnum)
        if 'varpositions' in instructions:
            vars = instructions['varpositions']
            for entry in vars:
                colour,coord,number = entry
                self.add_variation_stone(coord,colour,number)

        t4 = time()
                
        if 'comment' in instructions:
            commenttext = instructions['comment']
            self.comment_text = commenttext
        else:
            self.comment_text = '[color=444444]Long press to add comment.[/color]'

        if 'nextplayer' in instructions:
            player = instructions['nextplayer']
            if player in ['b','w']:
                print 'next_to_play from',self.next_to_play
                self.next_to_play = player
                print '-->',self.next_to_play
            elif player == 'a':
                self.next_to_play = alternate_colour(self.next_to_play)

        if 'pre_text' in instructions:
            text = instructions['pre_text']
            self.comment_pre_text = text

        if 'unsaved' in instructions:
            self.has_unsaved_data = True
        if 'saved' in instructions:
            self.has_unsaved_data = False

        t5 = time()

        tottime = t5-t1
        # print '## Follow instruction times'
        # print '## Total', t5-t1
        # print '## Reset', t2-t1, (t2-t1)/tottime
        # print '## Add remove empty', t3-t2, (t3-t2)/tottime
        # print '## Playmarker, positions etc.', t4-t3, (t4-t3)/tottime
        # print '## Comment and saved', t5-t4, (t5-t4)/tottime

    def get_player_details(self,*args,**kwargs):
        wname, bname = self.abstractboard.get_player_names()
        wrank, brank = self.abstractboard.get_player_ranks()
        self.wrank = wrank
        self.wname = wname
        self.brank = brank
        self.bname = bname
        

    def advance_one_move(self,*args,**kwargs):
        print '%% Advancing one move!', time()
        t1 = time()
        instructions = {'add': [((randint(0,18),randint(0,18)),['w','b'][randint(0,1)])]}
        self.follow_instructions(instructions)
        t3 = time()
        print '%% Total time for button function to complete', t3-t1
        # if self.navmode == 'Score':
        #     self.clear_ld_markers()
        #     self.make_scoreboard()
        # t1 = time()
        # children_exist = self.abstractboard.do_children_exist()
        # t2 = time()
        # if children_exist:
        #     instructions = self.abstractboard.advance_position()
        #     self.follow_instructions(instructions)
        # else:
        #     if platform() == 'android':
        #         import android
        #         android.vibrate(0.1)
        # t3 = time()
        # print '%% Total time for button function to complete', t3-t1
        # print '%% Children exist', t2-t1
        # print '%% Follow instructions', t3-t2
        # print '%%'

    def time_start(self):
        print 'time_start called'
        t = time()
        self.timestart = t
    def time_stop(self):
        t = time()
        t0 = self.timestart
        print '``` Time between press and release:',t-t0

    def retreat_one_move(self,*args,**kwargs):
        print '%% Advancing one move!', time()
        t1 = time()
        instructions = {'remove': [(self.stones.keys()[0],'b')]}
        print instructions
        self.follow_instructions(instructions)
        t3 = time()
        print '%% Total time for retreat button function to complete', t3-t1
        # if self.navmode == 'Score':
        #     self.clear_ld_markers()
        #     self.make_scoreboard()
        # instructions = self.abstractboard.retreat_position()
        # self.follow_instructions(instructions)

    def jump_to_start(self,*args,**kwargs):
        instructions = self.abstractboard.jump_to_node(self.abstractboard.game.root)
        self.follow_instructions(instructions)

    def jump_to_end(self,*args,**kwargs):
        instructions = self.abstractboard.jump_to_node(self.abstractboard.game.get_last_node())
        self.follow_instructions(instructions)
        
    def reset_uielements(self,*args,**kwargs):
        self.comment_pre_text = ''
        self.comment_text = ''

        #self.next_to_play = 'b'
        
        for elementtype in self.uielements:
            elements = self.uielements[elementtype]
            for element in elements:
                if elementtype == 'varbutton':
                    element.background_color = [1,0,0,1]
                    element.text = 'Next var\n  (1 / 1)'

    def add_variation_stone(self,coord=(1,1),colour='black',num=1,*args,**kwargs):
        stonesize = self.stonesize
        stone = VarStone(size=stonesize, pos=self.coord_to_pos(coord), text=str(num))
        stone.set_colour(colour)
        if self.varstones.has_key(coord):
            self.remove_stone(coord)
        self.varstones[coord] = stone
        self.add_widget(stone)

    def clear_variation_stones(self):
        for coord in self.varstones.keys():
            stone = self.varstones.pop(coord)
            self.remove_widget(stone)

    def add_coordinates(self):
        self.remove_coordinates()
        stonesize = self.stonesize
        for i in range(self.gridsize):
            label = Label(text=self.coordinate_letter[i],
                          size=stonesize,
                          pos=self.coord_to_pos((i,-0.75),dotransformations=False),
                          font_size=(0.4*stonesize[1],'px'),
                          color=(0,0,0,1))
            self.add_widget(label)
            self.coordinate_labels.append(label)
        for j in range(self.gridsize):
            label = Label(text=self.coordinate_number[j],
                          size=stonesize,
                          pos=self.coord_to_pos((-0.75,j),dotransformations=False),
                          font_size=(0.4*stonesize[1],'px'),
                          color=(0,0,0,1))
            self.add_widget(label)
            self.coordinate_labels.append(label)
    def remove_coordinates(self):
        for widget in self.coordinate_labels:
            self.remove_widget(widget)
        self.coordinate_labels = []
    def update_coordinates(self):
        self.remove_coordinates()
        if self.coordinates:
            self.add_coordinates()

    def add_stone(self,coord=(1,1),colour='black',*args,**kwargs):
        stonesize = self.stonesize
        t1 = time()
        stone = Stone(size=stonesize, pos=self.coord_to_pos(coord))
        stone.set_colour(colour)
        t2 = time()
        if self.stones.has_key(coord):
            self.remove_stone(coord)
        self.stones[coord] = stone
        t3 = time()
        self.add_widget(stone)
        t4 = time()
        # print '@@ total', t4-t1
        # print '@@ make stone', t2-t1, (t2-t1)/(t4-t1)
        # print '@@ add to dict', t3-t2, (t3-t2)/(t4-t1)
        # print '@@ add widget', t4-t3, (t4-t3)/(t4-t1)

    def remove_stone(self,coord=(1,1),*args,**kwargs):
        print coord,self.stones.keys()
        print self.stones[coord]
        if self.stones.has_key(coord):
            stone = self.stones.pop(coord)
            self.remove_widget(stone)
        else:
            print 'Tried to remove stone that doesn\'t exist'

    def empty_stone(self,coord=(1,1),*args,**kwargs):
        if self.stones.has_key(coord):
            stone = self.stones.pop(coord)
            self.remove_widget(stone)

    def update_stones(self):
        for coord in self.stones.keys():
            self.stones[coord].pos = self.coord_to_pos(coord)
            self.stones[coord].size = self.stonesize

    def redraw_stones(self):
        for coord in self.stones.keys():
            stone = self.stones[coord]
            self.remove_widget(stone)
            self.add_widget(stone)

    def clear_stones(self):
        for coord in self.stones.keys():
            stone = self.stones.pop(coord)
            self.remove_widget(stone)

            

    # Star point methods
    def draw_starpoints(self):
        self.remove_starpoints()
        if self.starpoint_positions.has_key(self.gridsize):
            coords = self.starpoint_positions[self.gridsize]
            for entry in coords:
                self.add_starpoint(entry)
    
    def add_starpoint(self,coord=(1,1),*args,**kwargs):
        stonesize = self.stonesize
        sp = StarPoint(size=stonesize, pos=self.coord_to_pos(coord))
        if self.starpoints.has_key(coord):
            self.remove_starpoint(coord)
        self.starpoints[coord] = sp
        self.add_widget(sp)
        self.redraw_stones()

    def remove_starpoint(self,coord=(1,1),*args,**kwargs):
        if self.starpoints.has_key(coord):
            sp = self.starpoints.pop(coord)
            self.remove_widget(ssp)
        else:
            print 'Tried to remove starpoint that doesn\'t exist'

    def remove_starpoints(self):
        for entry in self.starpoints:
            sp = self.starpoints[entry]
            self.remove_widget(sp)
        self.starpoints = {}

    def update_starpoints(self):
        self.remove_starpoints()
        self.draw_starpoints()

    def redraw_starpoints(self):
        for coord in self.starpoints.keys():
            sp = self.starpoints[coord]
            self.remove_widget(ssp)
            self.add_widget(sp)
        self.redraw_stones()

    # Variation handling
    def next_variation(self,*args,**kwargs):
        instructions = self.abstractboard.increment_variation()
        self.follow_instructions(instructions)

    def prev_variation(self,*args,**kwargs):
        instructions = self.abstractboard.decrement_variation()
        self.follow_instructions(instructions)

    # Syncing
    def reset_abstractboard(self):
        self.clear_transient_widgets()
        self.reset_uielements()
        self.clear_stones()
        instructions = self.abstractboard.reset_position()
        self.get_player_details()
        self.follow_instructions(instructions)
        self.gameinfo = self.abstractboard.get_gameinfo()

    def reset_gridsize(self,newsize):
        self.gridsize = newsize
        self.abstractboard = AbstractBoard(gridsize=newsize)
        print 'New gridsize is', self.gridsize
        print 'New abstractboard gridsize', self.abstractboard.game.size
Пример #8
0
 def __init__(self,*args,**kwargs):
     super(GuiBoard,self).__init__(*args,**kwargs)
     print 'GuiBoard init, making abstractboard with gridsize', self.gridsize
     self.abstractboard = AbstractBoard(gridsize=self.gridsize)
     self.reset_abstractboard()