Esempio n. 1
0
class Session:
    def __init__(self, w, h, owner):
        self.sid = sha1(str(time.time())).hexdigest()
        self.clients = [owner]
        owner.player = 1
        self.player_counter = 2
        self.state = STATE_JOINING
        self.board = Board(w, h)
        self.turn = owner

        owner.send(Msg('newgame', self.sid, w, h).encode())
        owner.send(Msg('turn', self.turn.player).encode())

    def __str__(self):
        return '<Session %s state=%d size=%dx%d>' % \
                (self.sid, self.state, self.board.w, self.board.h)

    def click_wall(self, client, x, y, direction):
        check(self.turn is client, 'not your turn')
        check(self.state < STATE_FINISHED, 'already finished')
        self.state = STATE_PLAYING

        occupied = self.board.click_wall(x, y, direction, client.player)
        self.bcast('clickwall', x, y, direction)

        if occupied:
            for x, y in occupied:
                self.bcast('occupy', x, y, client.player)

            if self.board.is_finished():
                scores = self.board.scores()

                for player in xrange(1, self.player_counter):
                    scores.setdefault(player, 0)

                scores = scores.items()
                scores.sort(key=lambda (player, score): score, reverse=True)

                self.state = STATE_FINISHED
                self.bcast('finish', *['%d:%d' % s for s in scores])
        else:
            index = (self.clients.index(self.turn) + 1) % len(self.clients)
            self.turn = self.clients[index]
            self.bcast('turn', self.turn.player)

    def bcast(self, mtype, *args):
        encoded = Msg(mtype, *args).encode()

        for client in self.clients:
            client.send(encoded)

    def join(self, client):
        client.player = self.player_counter
        self.player_counter += 1

        self.bcast('join', client.player)

        client.send(Msg('newgame', self.sid, self.board.w, self.board.h,
                        client.player).encode())
        client.send(Msg('turn', self.turn.player).encode())

        for other in self.clients:
            client.send(Msg('join', other.player).encode())

        self.clients.append(client)

    def leave(self, client):
        self.clients.remove(client)
        self.bcast('leave', client.player)

        if self.state == STATE_PLAYING:
            self.bcast('cancel', 'a player has quit before the game ended')
        elif client is self.turn:
            self.turn = self.clients[0]
            self.bcast('turn', self.turn.player)

    def is_dead(self):
        return not self.clients