예제 #1
0
파일: tttgame.py 프로젝트: jpg75/TTT-kivy
    def __init__(self, *pars, **kpars):
        AnchorLayout.__init__(self, *pars, **kpars)
        self.cur_dir = dirname(abspath('file'))
        config = Configuration()
        config.purgelines()
        config.initialize()

        # do not use '-' or other chars in the name!
        self.username = ''

        self.turnables = config.getParam('turnable')
        self.cards_unturnable = bool(int(config.getParam('cards_unturnable')))

        # enables the automatic player agent, playing as NK as default. 
        self.rp = None  # Rule Parser
        self.auto_player = bool(int(config.getParam('auto_player')))
        if self.auto_player:
            self.rp = RuleParser()
            self.rp.load_rules()

        self.format = config.getParam('format')
        self.help_file = config.getParam('help_file')
        self.shoe_file = config.getParam('shoe_file')

        self.srv = config.getParam('server')
        self.srv_port = config.getParam('server_port')

        if self.format == 'circular':
            self.turnable = dict(zip(TTTGame.CIRCULAR_CARD_LAYOUT, [bool(int(x)) for x in self.turnables.split(',')]))
        else:
            self.turnable = dict(zip(TTTGame.LINEAR_CARD_LAYOUT, [bool(int(x)) for x in self.turnables.split(',')]))

        self.timer_start = int(config.getParam('timer_start'))

        # load default shoe_file:
        self.shoe_config = Configuration(config_file=self.shoe_file)
        self.shoe_config.purgelines()

        # self.turn = ''  # current player turn
        self.current_target_card = ''  # the target card stated in the shoe_file ("2H" usually)

        print self.shoe_config.content

        self.hands = []  # store all hands
        # file names are in the form: output-<dmY>-<HM>.txt
        # Here we just create a reference. The actual obj is made when the login popup is dismissed
        self.fout_handle = None
        self.fout_time_handle = None

        self.timeHistory = []  # list holding the strings: <move> <time>\n
        self.stopwatch = StopWatch()

        self.nk_history_q = deque([], 2)  # nk history of the last 2 hands. Required for automatic agent
        self.ck_history_q = deque([], 2)  # ck history of the last 2 hands. Required for automatic agent
예제 #2
0
파일: tttgame.py 프로젝트: jpg75/TTT-kivy
class TTTGame(AnchorLayout):
    bottom_bar = ObjectProperty(None)
    game_table = ObjectProperty(None)
    side_bar = ObjectProperty(None)
    console = ObjectProperty(None)
    timer = ObjectProperty(None)
    hand = ListProperty()

    total_moves = NumericProperty(0)
    moves = NumericProperty(0)
    current_player = StringProperty('ck')  # instead of self.turn!
    run = NumericProperty(1)
    total_runs = NumericProperty()

    history_record = {'move': '', 'hand': '', 'up': '', 'target': ''}

    game_card_file = StringProperty('data/card_back_blue.jpeg')

    """ Default covered cards for each position on table"""
    TTT_COVERED_CARDS_ZONES = {"Up Position": False, "DownC Position": True,
                               "DownN Position": True, "Target Position": False,
                               "Color Position": False, "Number Position": False}

    """'linear' card layout. See 'format' parameter in config file."""
    LINEAR_CARD_LAYOUT = ["DownC Position",
                          "Color Position", "Up Position", "Target Position",
                          "DownN Position", "Number Position"]

    """'circular' card layout. This is the default format. See 'format'
    parameter in config file."""
    CIRCULAR_CARD_LAYOUT = ["Number Position",
                            "DownN Position", "Up Position", "DownC Position",
                            "Color Position", "Target Position"]

    """file names for each card. The file holds the corresponding card picture.
    It follows the order in HOME_CARDS_COORDINATES"""
    cards_files = ["h2red.jpeg", "h3red.jpeg",
                   "h4red.jpeg", "c2black.jpeg", "c3black.jpeg", "c4black.jpeg"]

    """card names, they corresponds to the card agent names"""
    cards_names = ["2H", "3H", "4H", "2C", "3C", "4C"]

    """zones names here follow the order in HOME_CARDS_COORDINATES array"""
    cards_zones_names = ["Color Position", "Target Position", "Number Position",
                         "DownC Position", "Up Position", "DownN Position"]

    """Allowed zones in which players can exchange/move cards. The 'Target' zone
    is subjected to extra restrictions."""
    allowed_moving_zones = ["Up Position", "Target Position", "DownC Position",
                            "DownN Position"]

    """map zones -> moves"""
    ZONES_MOVES = {"Up Position": "U", "DownC Position": "C",
                   "DownN Position": "N", "Target Position": "T", "Pass": "******"}
    
    """map card name -> card picture file"""
    cards_names_files = {"2H": "h2red.jpeg", "3H": "h3red.jpeg", "4H": "h4red.jpeg",
                         "2C": "c2black.jpeg", "3C": "c3black.jpeg", "4C": "c4black.jpeg"}

    """map card name -> color """
    cards_colors = {"2H": "red", "3H": "red", "4H": "red",
                    "2C": "black", "3C": "black", "4C": "black"}

    """map card name -> number """
    cards_numbers = {"2H": 2, "3H": 3, "4H": 4,
                     "2C": 2, "3C": 3, "4C": 4}

    """Map zone name -> card name. Tracks the zone in which a card is located.
    It is updated according to the game moves."""
    zones_cards = dict()

    help_txt = open('data/help_eng.txt', 'r').read()

    hand_history = []  # history related to the current hand

    def __init__(self, *pars, **kpars):
        AnchorLayout.__init__(self, *pars, **kpars)
        self.cur_dir = dirname(abspath('file'))
        config = Configuration()
        config.purgelines()
        config.initialize()

        # do not use '-' or other chars in the name!
        self.username = ''

        self.turnables = config.getParam('turnable')
        self.cards_unturnable = bool(int(config.getParam('cards_unturnable')))

        # enables the automatic player agent, playing as NK as default. 
        self.rp = None  # Rule Parser
        self.auto_player = bool(int(config.getParam('auto_player')))
        if self.auto_player:
            self.rp = RuleParser()
            self.rp.load_rules()

        self.format = config.getParam('format')
        self.help_file = config.getParam('help_file')
        self.shoe_file = config.getParam('shoe_file')

        self.srv = config.getParam('server')
        self.srv_port = config.getParam('server_port')

        if self.format == 'circular':
            self.turnable = dict(zip(TTTGame.CIRCULAR_CARD_LAYOUT, [bool(int(x)) for x in self.turnables.split(',')]))
        else:
            self.turnable = dict(zip(TTTGame.LINEAR_CARD_LAYOUT, [bool(int(x)) for x in self.turnables.split(',')]))

        self.timer_start = int(config.getParam('timer_start'))

        # load default shoe_file:
        self.shoe_config = Configuration(config_file=self.shoe_file)
        self.shoe_config.purgelines()

        # self.turn = ''  # current player turn
        self.current_target_card = ''  # the target card stated in the shoe_file ("2H" usually)

        print self.shoe_config.content

        self.hands = []  # store all hands
        # file names are in the form: output-<dmY>-<HM>.txt
        # Here we just create a reference. The actual obj is made when the login popup is dismissed
        self.fout_handle = None
        self.fout_time_handle = None

        self.timeHistory = []  # list holding the strings: <move> <time>\n
        self.stopwatch = StopWatch()

        self.nk_history_q = deque([], 2)  # nk history of the last 2 hands. Required for automatic agent
        self.ck_history_q = deque([], 2)  # ck history of the last 2 hands. Required for automatic agent

    def update(self, dt):
        pass

    def post_init(self):
        self.total_runs = len(self.shoe_config.content)
        self.connection_popup = ConnectionPopup()
        self.connection_popup.open()
        
        # self.connection_popup()  
        # self.show_login_popup()
        # self.generate_hand()

    def count_down(self, seconds):
        """Manage the count down clock."""
        m, s = divmod(seconds, 60)
        h, m = divmod(m, 60)
        self.timer.text = "Timer: %d:%02d:%02d" % (h, m, s)

        if seconds > 0:
            Clock.schedule_once(lambda dt: self.count_down(seconds - 1), 1)
        else:
            self.quit_popup()  # end game

    def save_local_data(self):
        """Save data locally about moves.
        The format is the following:
        <current hand>\n
        \n
        <moves>\n
        \n
        """
        hand_s = ''
        for x in self.hand[:6]:  # only first 6 elements
            hand_s = hand_s + x + ' '
        hand_s = hand_s.strip()
        self.fout_handle.write(hand_s + '\n\n')
        self.fout_handle.flush()

        s = ''
        for x in self.hand_history:
            s = s + x
        s = s.strip()
        s = s.upper()
        self.fout_handle.write(s + '\n\n')
        self.fout_handle.flush()

        s = ''
        self.fout_time_handle.write(hand_s + '\n\n')
        for x in self.timeHistory:
            x = x.strip()
            x = x.upper()
            self.fout_time_handle.write(x + '\n')

        self.fout_time_handle.write('\n')
        self.fout_time_handle.flush()

    def save_data_remote(self):
        s = ''
        for x in self.hand[:6]:  # only first 6 elements
            s = s + x + ' '
        s = s.strip()

        s = s + '\n\n'

        h = ''
        for x in self.hand_history:
            h = h + x
        h = h.strip()
        h = h.upper()

        # print h

        # s = s + h + '\n'
        ap.App.get_running_app().log(s + h + '\n', 'MOVES')

        for x in self.timeHistory:
            x = x.strip()
            x = x.upper()
            s = s + x + '\n'

        ap.App.get_running_app().log(s, 'TIMES')

    def cover_cards(self):
        """ Cover all cards on the table. Cards show the back picture file.
        """
        print "COVER CARDS"
        for w in self.game_table.children:
            print "child"
            if isinstance(w, CardWidget):
                print "covering: %s" % w.name
                w.to_front = False

    def show_cards(self, game_rules_on=False):
        """ Show all cards on the table. Cards show the front picture file.
        if 'game_rules_on', cards are turned face up only if the game rules allows.
        """
        for w in self.game_table.children:
            if isinstance(w, CardWidget):
                if game_rules_on:
                    if not TTTGame.TTT_COVERED_CARDS_ZONES[w.zone]:
                        print "card in zone %s moved to front" % w.zone
                        w.to_front = True
                    else:
                        print "card in zone %s moved to back" % w.zone
                        w.to_front = False

                    if w.zone == 'Color Position' and self.current_player == 'nk':
                        w.to_front = False

                    if w.zone == 'Number Position' and self.current_player == 'ck':
                        w.to_front = False

                else:
                    w.to_front = True

    def score(self, current_card=None, opponent_card=None, move='Pass', no_auto_player_trigger=False):
        """Score a valid move for the current player and updates stats and the 
        current player turn.
        Moves are added to the hand's history of moves and to the short term 
        memory history as well.
        Cards in NumberKeeper and ColorKeeper positions are flip according to the
        current player.
        If the auto player is enabled, its behavior is triggered with a delay.
        If no_auto_player_trigger then the auto player is not triggered.
        """
        self.moves += 1
        self.total_moves += 1
        move_time = self.stopwatch.split()
        move_str = ''
        h_record = dict(TTTGame.history_record)  # make a new one
                
        # Search who is in the target and up positions 
        for w in self.game_table.children:
            if isinstance(w, CardWidget):
                if w.zone == 'Target Position':
                    cur_target = w.name
                    # print "cur target: ",cur_target
                elif w.zone == 'Up Position':
                    cur_up = w.name
                    # print "cur up: ",cur_up
                elif w.zone == 'Color Position' and self.current_player == 'ck':
                    cur_hand = w.name
                    # print "cur hand: ",cur_hand
                elif w.zone == 'Number Position' and self.current_player == 'nk':
                    cur_hand = w.name
                    # print "cur hand",cur_hand
                elif w.zone == 'DownC Position':
                    cur_c = w.name
                    # print "cur c ", cur_c
                elif w.zone == 'DownN Position':
                    cur_n = w.name
                    # print "cur n: ",cur_n
                else:
                    print "Unmatched card zone string: ", w.zone

        if current_card == None and opponent_card == None:
            move_str = TTTGame.ZONES_MOVES[move] + ' ' + self.stopwatch.to_string(move_time)

            TTTGame.hand_history.append(TTTGame.ZONES_MOVES[move])
            # No move, the same as before:
            h_record['move'] = TTTGame.ZONES_MOVES[move]
            h_record['up'] = cur_up
            h_record['target'] = cur_target
            h_record['hand'] = cur_hand

        else:
            move_str = TTTGame.ZONES_MOVES[current_card.zone] + ' ' + self.stopwatch.to_string(move_time)

            TTTGame.hand_history.append(TTTGame.ZONES_MOVES[current_card.zone])
            h_record['move'] = TTTGame.ZONES_MOVES[current_card.zone]
            # when the move is 't' or 'u', simply swap the card name in hand 
            # position (relative to the color or number keeper) with the respective position (target or up).
            if h_record['move'] == 'T':
                h_record['up'] = cur_up
                h_record['target'] = cur_hand
                h_record['hand'] = cur_target

            elif h_record['move'] == 'U':
                h_record['up'] = cur_hand
                h_record['target'] = cur_target
                h_record['hand'] = cur_up
                print h_record

            elif h_record['move'] == 'N':
                h_record['up'] = cur_up
                h_record['target'] = cur_target
                h_record['hand'] = cur_n

            elif h_record['move'] == 'C':
                h_record['up'] = cur_up
                h_record['target'] = cur_target
                h_record['hand'] = cur_c

            else:
                print "Unmatched move when extracting history situation."

        self.timeHistory.append(move_str)

        # swap players for the next round:            
        if self.current_player == 'ck':
            self.ck_history_q.appendleft(h_record)
            self.current_player = 'nk'
            # when auto player enabled trigger its behavior in [1:3] seconds delay
            if self.auto_player and not no_auto_player_trigger:
                Clock.schedule_once(lambda dt: self.auto_player_behavior(), random.randint(1, 3))
                
        else:
            self.nk_history_q.appendleft(h_record)
            self.current_player = 'ck'
    
        self.adjust_keeper_cards()  # flip the opponent card
        self.adjust_cards_border()  # highlight the player card

    def adjust_cards_border(self):
        """ Highlight the player card's.
        """
        # resets for sure: not nice programming! :-(
        for w in [x for x in self.game_table.children if isinstance(x, CardWidget)]:
            w.show_border(off=True)  # resets

        for w in [x for x in self.game_table.children if isinstance(x, CardWidget)]:
            if w.zone == 'Color Position' and self.current_player == 'ck':
                w.show_border()

            elif w.zone == 'Number Position' and self.current_player == 'nk':
                w.show_border()

            else:
                # pass
                w.show_border(off=True)

    def adjust_keeper_cards(self):
        """Flip a keeper card according to the current player.
        """
        for w in [x for x in self.game_table.children if isinstance(x, CardWidget)
        and (x.zone == 'Color Position' or x.zone == 'Number Position')]:

            if w.zone == 'Color Position':
                if self.current_player == 'nk':
                    w.to_front = False
                else:
                    w.to_front = True

            if w.zone == 'Number Position':
                if self.current_player == 'ck':
                    w.to_front = False
                else:
                    w.to_front = True

    def relocate(self, card, other_card):
        """Set the new zone for the current and companion card and set up the
        animations for both cards.
        """
        card_temp_x = card.old_x
        card_temp_y = card.old_y
        other_card_temp_x = other_card.x
        other_card_temp_y = other_card.y

        # print "selfzone: ", self.zone
        temp_zone = card.zone
        # print "tempzone: ", temp_zone

        # print "w zone: ", other_card.zone
        anim1 = Animation(pos=(other_card_temp_x, other_card_temp_y), t='in_quad', d=0.5)
        anim2 = Animation(pos=(card_temp_x, card_temp_y), t='in_quad', d=0.5)
        anim1.start(card)
        anim2.start(other_card)
        card.zone = other_card.zone
        other_card.zone = temp_zone

    def is_goal(self, card, other_card):
        """ Check whether the move accomplish the hand goal or not"""
        if other_card.zone == 'Target Position':
            if card.zone == 'Color Position' and card.color == other_card.color:
                print "card zone: %s , color: %s, other color: %s" % (card.zone, card.color, other_card.color)
                return True
            if card.zone == 'Number Position' and card.number == other_card.number:
                print "card zone: %s , color: %s, other color: %s" % (card.zone, card.number, other_card.number)
                return True

        return False

    def check_cards_collision(self, touch, card, other_card):
        """Check if the move is correct and if the hand is complete.

        :param touch: a touch object
        :param card: moved card
        :param other_card: card over which has been moved the other
        :return: wether or not the other_card must be relocated
        """
        relocated = False
        if other_card.collide_point(touch.x, touch.y) and other_card.zone in TTTGame.allowed_moving_zones:  # collision!
            if other_card.zone == 'Target Position':
                if self.is_goal(card, other_card):
                    # check if its is the current target
                    print "NAME: %s - target: %s" % (card.name, self.current_target_card)
                    if card.name == self.current_target_card:
                        # ended current run!
                        self.run += 1
                        self.console.text += 'Hand successful!\n'
                        Clock.schedule_once(lambda dt: self.generate_hand())
                        self.relocate(card, other_card)
                        relocated = True
                        self.score(card, other_card, no_auto_player_trigger=True)

                    else:
                        self.relocate(card, other_card)
                        relocated = True
                        self.score(card, other_card)

            else:
                self.relocate(card, other_card)
                relocated = True
                self.score(card, other_card)

        return relocated

    def generate_hand(self):
        """Generate a new handle from the description found in the shoe file.
        the hand is injected in the hand property.
        Before generating the handle:
        - manage the count-down clock.
        - save local and remote data
        - generate the popup to signal the new hand to the user
        """
        # self.cover_cards() 
        run_index = self.run - 1
        self.total_runs = len(self.shoe_config.content)

        if not self.stopwatch.running:
            self.stopwatch.start()

        if run_index < len(self.shoe_config.content):  # hand available
            if run_index >= 1:
                if self.stopwatch.running:
                    self.stopwatch.stop()

                self.save_local_data()
                self.save_data_remote()

                self.stopwatch.reset()
                self.stopwatch.start()

            self.hand = self.shoe_config.content[run_index].split()
            cards = [x for x in self.game_table.children if isinstance(x, CardWidget)]

            # self.console.text += 'New hand: ' + str(self.hand[:6]) + '\n\n'

            print "New hand: ", self.hand
            nk = dn = up = dc = ck = t = gc = cur_player = ''

            if len(self.hand) != 8:
                print "Invalid line in shoe file '%s' : %s" % (self.shoe_file, self.hand)
            elif self.format == 'circular':
                nk, dn, up, dc, ck, t, gc, cur_player = self.hand
            else:  # linear layout
                dn, ck, up, t, dn, t, gc, cur_player = self.hand

            # self.turn = cur_player
            self.current_player = cur_player
            self.hand_history[:] = []  # resets the history for the next hand
            self.timeHistory[:] = []  # resets the time history of each move

            for c in cards:
                if c.zone == 'Color Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[ck]
                    c.color = TTTGame.cards_colors[ck]
                    c.name = ck
                    c.number = TTTGame.cards_numbers[ck]
                elif c.zone == 'Target Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[t]
                    c.color = TTTGame.cards_colors[t]
                    c.name = t
                    c.number = TTTGame.cards_numbers[t]
                    c.to_front = True
                elif c.zone == 'Number Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[nk]
                    c.color = TTTGame.cards_colors[nk]
                    c.name = nk
                    c.number = TTTGame.cards_numbers[nk]
                elif c.zone == 'DownC Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[dc]
                    c.color = TTTGame.cards_colors[dc]
                    c.name = dc
                    c.number = TTTGame.cards_numbers[dc]
                elif c.zone == 'Up Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[up]
                    c.color = TTTGame.cards_colors[up]
                    c.name = up
                    c.number = TTTGame.cards_numbers[up]
                    c.to_front = True
                elif c.zone == 'DownN Position':
                    c.front_pic_file = 'data/' + TTTGame.cards_names_files[dn]
                    c.color = TTTGame.cards_colors[dn]
                    c.name = dn
                    c.number = TTTGame.cards_numbers[dn]

                else:
                    print "Warning: unknown position '%s'!" % c.zone

            # check if the card has changed before the popup
            if run_index >= 1:
                callback = None
                if self.auto_player and self.current_player == 'nk':
                    callback = self.intra_hand_popup_dismiss
                                    
                if self.current_target_card != self.hand[6]:
                    self.intra_hand_popup(goal_changed=True, dismiss=callback)
                else:
                    self.intra_hand_popup(dismiss=callback)

            self.game_card_file = 'data/' + TTTGame.cards_names_files[gc]
            self.current_target_card = gc
            self.show_cards(game_rules_on=True)
            self.adjust_cards_border()
            self.moves = 0  # reset current hand moves

        else:  # run out of runs!
            self.save_local_data()
            self.save_data_remote()

            self.quit_popup()

    def auto_player_behavior(self):
        current_table = dict(TTTGame.history_record.items())
        
        for w in self.game_table.children:
            if isinstance(w, CardWidget):
                if w.zone == 'Target Position':
                    current_table['target'] = w.name
                elif w.zone == 'Up Position':
                    current_table['up'] = w.name
                elif w.zone == 'Color Position' and self.current_player == 'ck':
                    current_table['hand'] = w.name
                elif w.zone == 'Number Position' and self.current_player == 'nk':
                    current_table['hand'] = w.name
                else:
                    print "Unmatched card zone string: ", w.zone
        
        #=======================================================================
        # print "current table: ", current_table
        # print "ck history: ", self.ck_history_q
        # print "nk history: ", self.nk_history_q
        #=======================================================================
               
        rule = self.rp.match(current_table['hand'], current_table['up'],
                              current_table['target'], self.ck_history_q,
                              self.nk_history_q, self.history_record)
        
        self.console.text += "rule selected: %s\n" % rule[0]
        self.apply_move(rule[0], current_table['hand'])
        
    
    def apply_move(self, move, hand):
        """Used by the auto player: actually performs the move dictated by the 
        rules.
        """
        if move == 'p':
            self.score(None, None)
            
        else:
            card = None
            to_card = None
            for w in self.game_table.children:
                if isinstance(w, CardWidget):
                    if w.name == hand:
                        card = w
                    if (w.zone != 'Color Position' and w.zone != 'Number Position') \
                        and TTTGame.ZONES_MOVES[w.zone] == move:
                        to_card = w
            
            if to_card.zone == 'Target Position':
                if self.is_goal(card, to_card):
                    if card.name == self.current_target_card:
                        self.run += 1
                        self.console.text += 'Hand successful!\n'
                        Clock.schedule_once(lambda dt: self.generate_hand())
            
            card.select()
            self.relocate(card, to_card)
            card.selected = None
            self.score(card, to_card)
            
        
    def show_login_popup(self):
        l_popup = LoginPopup()
        l_popup.open()

    def intra_hand_popup(self, goal_changed=False, dismiss=None):
        """Generate a popup to emphasize the start of a new hand.
        By clicking over the button, it disappears.
        When 
        """
        popup = Popup(title='Next Hand Window', size_hint=(0.3, 0.3))
        if dismiss == None:
            dismiss = popup.dismiss
        
        l = BoxLayout(orientation='vertical')
        if goal_changed:
            l.add_widget(Label(text='Your Goal card has changed', font_size='30sp'))

        l.add_widget(Button(text='Next hand', font_size='40sp', on_press=dismiss))
        popup.add_widget(l)
        popup.open()
    
    def intra_hand_popup_dismiss(self, widget):
        Clock.schedule_once(lambda dt: self.auto_player_behavior(), random.randint(1, 3))
        widget.parent.parent.parent.parent.dismiss()
        
    def quit_popup(self):
        popup = Popup(title='Score Summary Window', size_hint=(0.7, 0.7))
        l = BoxLayout(orientation='vertical')
        l.add_widget(Label(text='Game Over', font_size='40sp'))
        l.add_widget(Label(text='Total moves played: %d' % self.total_moves, font_size='25sp'))
        popup.add_widget(l)
        popup.bind(on_dismiss=self.summary_popup_dismiss)
        popup.open()

    def summary_popup_dismiss(self, *pars):
        sys.exit()

    def help_on_press_callback(self):
        """Callback for 'help' button.
        """
        popup = Popup(title='Help Window',
                      content=TextInput(text=unicode(TTTGame.help_txt, errors='replace'),
                                        readonly=True, auto_indent=True, cursor=(1, 1)),
                      size_hint=(None, None), size=(400, 400))
        popup.open()

    def pass_on_press_callback(self):
        """Callback for 'pass' button.
        """
        self.score(None, None)

    def connect_on_press_callback(self):
        """Tries to connect to the server using first the network discovery service.
        If it fails, try the address in config.txt. 
        If it fails again: no connection.
        The exit status is displayed on the right console widget.
        """
        s = ap.App.get_running_app().mp.servers
        if s != None and len(s) >= 1:
            print "server found: %s" % s[0]
            self.srv = s[0]
            # ap.App.get_running_app().connect_to_server(self.srv, 8080)
        # else:
        ap.App.get_running_app().connect_to_server(self.srv, 8080)