Exemplo n.º 1
0
 def __init__(self):
     self.players = Players()
     self.curr_player = 0
     self.curr_card = None
     self.curr_roles = []
     self.server = GameServer(handler=self.msg_handler)
     self.init_state_machine()
     # Option : consider using name to distinguish multiple server instances
     t = threading.Thread(target=self.server.serve())
     t.start()
Exemplo n.º 2
0
class GameManager(object):
    def __init__(self):
        self.players = Players()
        self.curr_player = 0
        self.curr_card = None
        self.curr_roles = []
        self.server = GameServer(handler=self.msg_handler)
        self.init_state_machine()
        # Option : consider using name to distinguish multiple server instances
        t = threading.Thread(target=self.server.serve())
        t.start()

    def init_state_machine(self):
        _fsm = {
            "initial": "round_begin",
            "events": [
                {
                    "action": "think",
                    "src": [
                        "round_begin",
                        "round_middle"
                    ],
                    "dst": [
                        "round_begin",
                        "round_middle",
                        "actions_begin"
                    ],
                    "callbacks": dict(on_event=self.handle_thinker),
                },
                {
                    "action": "declare_card",
                    "src": [
                        "round_begin",
                        "round_middle"
                    ],
                    "dst": [
                        "round_middle",
                        "actions_begin"
                    ],
                    "callbacks": dict(on_event=self.handle_card_declare),
                },
                {
                    "action": "perform_act",
                    "src": [
                        "actions_begin",
                        "actions_middle"
                    ],
                    "dst": [
                        "actions_middle",
                        "round_begin"
                    ],
                    "callbacks": dict(on_event=self.handle_action),
                }
            ],
        }
        self.sm = Machine(_fsm)

    def msg_handler(self, msg):
        ''' Modify the player/game state based on inputs received.
            Always return the players current state so that the client always
            has the latest state
        :param msg: see communications.game_protocol for the type of messages
                    that can be exchanged
        :return:    state representing the player's hand
        '''
        if is_pkt_announce(msg):
            name = decode(msg)
            self.add_player(name)
            state = self.get_current_state(name)
            return make_pkt_announce_ack(state)
        elif is_pkt_declare(msg):
            name, card = decode(msg)
            self.sm.declare_card(name=name, card=card)
            state = self.get_current_state(name)
            return make_pkt_declare_ack(state)
        elif is_pkt_act(msg):
            name, card = decode(msg)
            self.sm.perform_act(name=name, card=card)
            state = self.get_current_state(name)
            return make_pkt_act_ack(state)

    def get_current_state(self, name):
        state = self.players.get_current_state(name)
        leader_name = self.players.get_current_leader() == name
        state["is_current_leader"] = 1 if leader_name else 0
        state["current_role"] = self.curr_card
        return state

    def add_player(self, name):
        assert isinstance(name, str)
        self.players.add_player(name)
        self.curr_player += 1

    def choose_next_leader(self):
        self.players.choose_next_leader()
        self.curr_player = 0

    def is_end_of_round(self):
        return self.curr_player == self.players.get_num_players() - 1

    def go_to_next_player(self):
        if not self.is_end_of_round():
            self.curr_player += 1
        else:
            self.curr_player = 0

    def validate_think(self, e):
        msg1 = '{} has decided to think with a {}. {} will lead the next round'
        msg2 = '{} has decided to think with a {}. Waiting for {}'
        msg3 = '{} has decided to think with a {}. Will start actions'
        if self.curr_player == 0 and self.can_get_requested_card(e):
            curr_player = self.players.get_player(0)
            next_player = self.players.get_player(1)
            print msg1.format(curr_player, e.card, next_player)
        elif not self.is_end_of_round() and self.can_get_requested_card(e):
            curr_player = self.players.get_player(self.curr_player)
            next_player = self.players.get_player(self.curr_player + 1)
            self.curr_roles.append("Think_" + e.card)
            print msg2.format(curr_player, e.card, next_player)
        elif self.can_get_requested_card(e):
            curr_player = self.players.get_player(self.curr_player)
            self.curr_roles.append("Think_" + e.card)
            print msg3.format(curr_player, e.card)

    def handle_thinker(self, e):
        if e.src == "round_begin":
            self.validate_think(e)
            self.choose_next_leader()
            e.dst = "round_begin"
        elif e.src == "round_middle" and not self.is_end_of_round():
            self.validate_think(e)
            self.go_to_next_player()
            e.dst = "round_middle"
        else:
            self.validate_think(e)
            self.go_to_next_player()
            print "Actions expected in this round : {}".format(self.curr_roles)
            e.dst = "actions_begin"
        return e.dst

    def validate_declare(self, e):
        print "{} has declared the card {}".format(
            e.name, e.card)
        if not self.can_accept(e.card):
            print "Invalid declaration"
        self.players.bring_card_to_play(e.name, e.card)

    def handle_card_declare(self, e):
        if e.src == "round_begin":
            self.validate_declare(e)
            e.dst = "round_middle"
        elif e.src == "round_middle" and not self.is_end_of_round():
            self.validate_declare(e)
            e.dst = "round_middle"
        else:
            self.validate_declare(e)
            print "Actions expected in this round : {}".format(self.curr_roles)
            e.dst = "actions_begin"
        return e.dst

    def handle_action(self, e):
        if e.src == "actions_begin":
            self.go_to_next_player()
            e.dst = "actions_middle"
        elif e.src == "actions_middle" and not self.is_end_of_round():
            self.go_to_next_player()
            e.dst = "actions_middle"
        else:
            self.choose_next_leader()
            e.dst = "round_begin"
        return e.dst

    def can_accept(self, card):
        # TODO: Modify this method so that we check if e.name is current_leader or not
        if self.curr_player == 0:
            self.curr_card = card['role']
            self.curr_roles.append(card)
            self.go_to_next_player()
            return True
        elif self.curr_card == card['role']:
            self.curr_roles.append(card)
            self.go_to_next_player()
            return True
        return False

    @staticmethod
    def can_get_requested_card(e):
        return True