Esempio n. 1
0
File: main.py Progetto: spillz/37.6
class GameMenu(ScreenManager):
    player_count = NumericProperty()
    players = ListProperty()
    disconnected = BooleanProperty()
    w_game = ObjectProperty()
    w_start_button = ObjectProperty()
    w_join_button = ObjectProperty()
    w_join_game_box = ObjectProperty()
    w_join_game_adapter = ObjectProperty()

    def __init__(self):
        super(GameMenu, self).__init__()
        self.w_start_button.bind(on_release = self.start_game)
        self.w_join_button.bind(on_release = self.find_network_game)

        args_converter = lambda row_index, rec: {'text': '%s on %s:%s'%(rec['game_name'],str(rec['ip_address']),str(rec['port'])) ,
            'size_hint_y': 0.1}
        adapter = ListAdapter(data = [],
            args_converter=args_converter,
            cls=ListItemButton,
            selection_mode='single',
            allow_empty_selection=True)
        self.w_join_game_list_view = ListView(size_hint = (0.6, 0.6), pos_hint = {'center_x':0.5, 'center_y':0.6},
                    adapter = adapter)
        self.w_join_game_box.add_widget(self.w_join_game_list_view)
        self.w_join_game_list_view.adapter.bind(on_selection_change = self.network_game_join)

        self.player_spec = []
        self.server = None
        self.disconnected = False

    def find_network_game(self, *args):
        print('looking for network games')
        import msocket
        self.w_join_game_list_view.adapter.data = []
        self.server = msocket.BroadcastClient(game_id, BROADCAST_PORT, callback = self.network_broadcaster_callback)
        self.current = 'join_game'

    def stop_server(self):
        if self.server is not None:
            self.server.stop()
            self.server = None

    def network_broadcaster_callback(self, *args):
        Clock.schedule_once(functools.partial(self.network_game_found, *args))

    def network_game_found(self, *args):
        (ip, bport), (game_id, game_name, gport), dt = args
        data = self.w_join_game_list_view.adapter.data[:]
        data.append({'ip_address': ip, 'game_name': game_name, 'port': gport})
        self.w_join_game_list_view.adapter.data = data
        self.w_join_game_list_view.populate()

    def network_game_join(self, adapter):
        if len(adapter.selection) == 0:
            return
        sel = adapter.selection[0]
        data = adapter.data[sel.index]
        gname = data['game_name']
        ip = data['ip_address']
        gport = data['port']
        import msocket
        self.stop_server()
        try:
            self.server = msocket.TurnBasedClient(game_id, gname, ip, gport, self.server_callback)
        except:
            #TODO: NOTIFY USER THAT CLIENT COULDN'T CONNECT
            return
        self.disconnected = False
        self.server.send('hello',None)
    
    def start_network_server(self):
        import msocket
        self.server = msocket.TurnBasedServer(game_id, game_name, BROADCAST_PORT, GAME_PORT, self.num_network_players, callback = self.server_callback)
        self.disconnected = False

    def server_callback(self, *args):
        Clock.schedule_once(functools.partial(self.server_msg, *args))
        
    def server_msg(self, *args):
        msg, data, dt = args
        board = self.w_game.children[0]
        if msg == 'players_joined': #all players have joined
            net_players = [x for x in range(self.player_count) if self.players[x]==2]
            self.server.queue.put(('player_ids',net_players))
            self.start_network_game(self.player_spec)
        elif msg == 'hello': #remote player says hello, send the initial game data
            player_id, data = data
            players_id = [x for x in range(len(board.players))]
            board.players[player_id].queue.put(('s_hello', (player_id, players_id)))
        elif msg == 's_hello': #data contains this players id and a list of player id's in turn order
            player_id, players_id = data
            spec = []
            for x in range(len(players_id)):
                ps = PlayerSpec('Player '+str(x), color_lookup[x], 0 if players_id[x] == player_id else 2)
                spec.append(ps)
            self.start_network_game(spec)
        elif msg == 'select': #player wants to select a die
            player_id, (pid, die_num) = data
            p = board.players[pid]
            die = p.dice[die_num]
            board.select_die(die)
            #self.server.send(player_id, True, die_num, die.value)
        elif msg == 's_select': #notify player whether they have selected a die and the roll result
            player_id, die_num, roll_value = data
            p = board.players[player_id]
            die = p.dice[die_num]
            board.select_die(die, roll_value)
        elif msg == 'place': #player wants to place a die
            player_id, (pid, hex_pos) = data
            t = board.tiles[hex_pos]
            board.place_die(t)
            #self.server.send(True, hex_pos)
        elif msg == 's_place': #notify player whether the die has been placed
            success, hex_pos = data
            t = board.tiles[hex_pos]
            board.place_die(t, False)
        elif msg == 's_restart': #resposne to the game restart
            #    data is success
            self.start_network_game()
        elif msg == 's_quitgame': #response to the game quit
            #    data is success
            self.server.stop()
            self.server = None
            self.current = 'main'
        elif msg == 'connection_error':
            board.w_state_label.color = white
#            board.w_state_label.bg_color = grey
            board.w_state_label.text = 'Disconnected - game over'
            board.game_over = True
            self.server = None
            self.disconnected = True

    def start_network_game(self, spec = None):
        if spec is not None:
            self.player_spec = spec
        board = self.w_game.children[0]    
        board.server = self.server
        board.setup_game(self.player_spec)
        board.start_game()
        self.current = 'game'
        try:
            net_players = [x for x in range(self.player_count) if self.players[x]==2]
            for x in range(len(net_players)):
                board.players[net_players[x]].queue = self.server.players[x].queue
        except AttributeError:
            pass

    def restart_game(self):
        if self.disconnected:
            return False
        if self.server is not None:
            try:
                self.server.notify_clients('s_restart',None)
            except AttributeError:
                return False
        board = self.w_game.children[0]    
        board.setup_game(self.player_spec)
        board.start_game()
        try:
            net_players = [x for x in range(self.player_count) if self.players[x]==2]
            for x in range(len(net_players)):
                board.players[net_players[x]].queue = self.server.players[x].queue
        except AttributeError:
            pass
        self.current = 'game'
        
    def join_game(self, *args):
        pass

    def start_game(self, *args):
        self.player_spec = []
        self.num_network_players = 0
        for x in range(self.player_count):
            ps = PlayerSpec('Player '+str(x+1), color_lookup[x], self.players[x])
            if ps.type == 2:
                self.num_network_players += 1
            self.player_spec.append(ps)
        if self.num_network_players > 0:
            self.start_network_server()
            self.current = 'host_wait'
        else:
            board = self.w_game.children[0]
            board.server = None
            board.setup_game(self.player_spec)
            board.start_game()
            self.current = 'game'
Esempio n. 2
0
class Table(BoxLayout):

    def __init__(self, data_ap, **kwargs):

        super(Table, self).__init__(**kwargs)
        self.app = App.get_running_app()

        ## first check if len data = 0 add label to alert user
        if len(data_ap) is 0:
            self.add_widget(Label(text="No Data", font_size='32dp'))
            return

        ########################
        ## HEADER
        ########################

        self.container_header = GridLayout(cols=3, size_hint_y=None, height=(self.app.row_height*0.55), spacing=10)

        listview_header_widgets = [Label(text="CHUNK"),
                                   Label(text="FOUND"),
                                   Label(text="SCORE",
                                          size_hint_x=0.2)]

        for x in range(3):
            self.container_header.add_widget(listview_header_widgets[x])

        self.add_widget(self.container_header)

        ########################
        ## GRID
        ########################

        self.container_table = GridLayout(cols=2)

        # This is quite an involved args_converter, so we should go through the
        # details. A CompositeListItem instance is made with the args
        # returned by this converter. The first three, text, size_hint_y,
        # height are arguments for CompositeListItem. The cls_dicts list contains
        # argument sets for each of the member widgets for this composite:
        # ListItemButton and ListItemLabel.
        args_converter = \
            lambda row_index, obj: \
                {'text': obj.chunk,
                 'value': obj.chunk,
                 'size_hint_y': None,
                 'height': self.app.row_height * 0.5,
                 'cls_dicts': [{'cls': Cell,
                                'kwargs': {'text': obj.chunk,
                                           'id': obj.chunk}},
                               {'cls': Cell,
                                'kwargs': {'text': obj.found,
                                           'id': obj.chunk,
                                           'is_representing_cls': True}},
                               {'cls': Cell,
                                'kwargs': {'text': str(obj.score),
                                           'id': obj.chunk,
                                           'size_hint_x': 0.2}}]}

        self.list_adapter = ListAdapter(
                                   data=self.first_fill(data_ap),
                                   args_converter=args_converter,
                                   selection_mode='single',
                                   propagate_selection_to_data=True,
                                   allow_empty_selection=False,
                                   cls=CompositeListItem)

        # Use the adapter in our ListView:
        self.list_view = ListView(adapter=self.list_adapter)

        print 'chunck selezionato: ', self.list_adapter.selection[0].children[2].text

        chunk = MarkupLabel(self.list_adapter.selection[0].children[2].text).markup

        print 'selected: ', self.list_adapter.selection[0].children[2].id
        self.detail_view = RowDetailView(chunk=self.list_adapter.selection[0].children[2].id)

        self.list_adapter.bind(on_selection_change=self.detail_view.row_changed)

        self.container_table.add_widget(self.list_view)
        self.add_widget(self.container_table)
        self.add_widget(self.detail_view)

    def update(self, rows):

        d = []
        for row in rows:
            d.append(Row(chunk=row.chunk, found=row.found, score=row.score))

        self.list_adapter.data = d
        self.list_view.populate()

    def first_fill(self, rows):

        d = []
        for row in rows:
            d.append(Row(chunk=row.chunk, found=row.found, score=row.score))

        return d