Example #1
0
class TronServer(object):

    def __init__(self):
        self.players = {}
        self.open_log_file()
        self.reset()
        random.seed(time.time())

    def open_log_file(self):
        """Open the log file."""
        self.log_filename = os.path.join(os.getcwd(),
                time.strftime('tron-log-%Y%m%d%H%M%S'))
        self.log_fp = open(self.log_filename, 'at')
        self.log('Opened log')

    def reset(self):
        """Reset the game."""
        if self.players:
            for player in self.alive_players:
                player.die('Game finished.')
        self.grid = TronGrid()
        self.player_count = 0
        self.turn_count = 0
        self.players = {}
        self.log('Initialized battle field.')

    def log(self, msg):
        """Write the message to the log."""
        timestamp = datetime.datetime.now().time().isoformat()
        self.log_fp.write('[{}] {}\n'.format(timestamp, msg))
        # processing of special commands
        if '@DUMP' in msg:
            self.dump_grid()

    def find_empty_spot(self):
        """Find an empty point in the field."""
        while 1:
            x = random.randrange(30)
            y = random.randrange(20)
            if self.grid.get(x, y) == 0:
                return x, y

    def add_player(self, title, command):
        """Launch a player and add to the game."""
        index = self.player_count
        self.player_count += 1

        player = self.players[index] = \
                PlayerProgram(index, title, command, self.log)
        self.log('Added player {} as {} ({})'.format(title, index, command))

        x, y = self.find_empty_spot()
        player.move(x, y, x, y)

    def dump_grid(self):
        """Dump the playing field to the log file."""
        self.log('Dumping the grid')
        for line in str(self.grid).split('\n'):
            self.log(line)

    def kill_player(self, player, msg):
        """Declare the player dead and remove from the field."""
        player.die(msg)
        self.dump_grid()
        self.grid.replace(self.grid.body_of(player.number), 0)
        self.grid.replace(self.grid.head_of(player.number), 0)

    def play_player_turn(self, player):
        """Play the turn of one player."""
        player.send_game_info(self.player_count)
        map(player.send_player_coords, self.players.values())

        cmd = player.receive_command()
        pos = self.grid.coords2index(*player.head)
        move = self.grid.DIRECTIONS.get(cmd, None)

        if move:
            new_pos = pos + move
            if self.grid[new_pos] != 0:
                self.kill_player(player, '{} is an illegal move.'.format(cmd))
            else:
                self.grid[pos] = self.grid.body_of(player.number)
                self.grid[new_pos] = self.grid.head_of(player.number)
                player.move(*(player.tail + self.grid.index2coords(new_pos)))
        else:
            self.kill_player(player, 'Invalid command: {}.'.format(cmd))

    @property
    def alive_players(self):
        """Return the list of alive players."""
        return filter(lambda p: p.is_alive, self.players.values())

    @property
    def players_list(self):
        """Return the players as a list."""
        return [self.players[i] for i in xrange(len(self.players))]

    def play_turn(self):
        """Play one turn for all alive players."""
        self.turn_count += 1
        self.log('Starting turn {}'.format(self.turn_count))
        for player in self.alive_players:
            self.play_player_turn(player)
        for player in self.players_list:
            player.check_stderr()
        self.log('Completed turn {}'.format(self.turn_count))
Example #2
0
class TronServer(object):
    def __init__(self):
        self.players = {}
        self.open_log_file()
        self.reset()
        random.seed(time.time())

    def open_log_file(self):
        """Open the log file."""
        self.log_filename = os.path.join(
            os.getcwd(), time.strftime('tron-log-%Y%m%d%H%M%S'))
        self.log_fp = open(self.log_filename, 'at')
        self.log('Opened log')

    def reset(self):
        """Reset the game."""
        if self.players:
            for player in self.alive_players:
                player.die('Game finished.')
        self.grid = TronGrid()
        self.player_count = 0
        self.turn_count = 0
        self.players = {}
        self.log('Initialized battle field.')

    def log(self, msg):
        """Write the message to the log."""
        timestamp = datetime.datetime.now().time().isoformat()
        self.log_fp.write('[{}] {}\n'.format(timestamp, msg))
        # processing of special commands
        if '@DUMP' in msg:
            self.dump_grid()

    def find_empty_spot(self):
        """Find an empty point in the field."""
        while 1:
            x = random.randrange(30)
            y = random.randrange(20)
            if self.grid.get(x, y) == 0:
                return x, y

    def add_player(self, title, command):
        """Launch a player and add to the game."""
        index = self.player_count
        self.player_count += 1

        player = self.players[index] = \
                PlayerProgram(index, title, command, self.log)
        self.log('Added player {} as {} ({})'.format(title, index, command))

        x, y = self.find_empty_spot()
        player.move(x, y, x, y)

    def dump_grid(self):
        """Dump the playing field to the log file."""
        self.log('Dumping the grid')
        for line in str(self.grid).split('\n'):
            self.log(line)

    def kill_player(self, player, msg):
        """Declare the player dead and remove from the field."""
        player.die(msg)
        self.dump_grid()
        self.grid.replace(self.grid.body_of(player.number), 0)
        self.grid.replace(self.grid.head_of(player.number), 0)

    def play_player_turn(self, player):
        """Play the turn of one player."""
        player.send_game_info(self.player_count)
        map(player.send_player_coords, self.players.values())

        cmd = player.receive_command()
        pos = self.grid.coords2index(*player.head)
        move = self.grid.DIRECTIONS.get(cmd, None)

        if move:
            new_pos = pos + move
            if self.grid[new_pos] != 0:
                self.kill_player(player, '{} is an illegal move.'.format(cmd))
            else:
                self.grid[pos] = self.grid.body_of(player.number)
                self.grid[new_pos] = self.grid.head_of(player.number)
                player.move(*(player.tail + self.grid.index2coords(new_pos)))
        else:
            self.kill_player(player, 'Invalid command: {}.'.format(cmd))

    @property
    def alive_players(self):
        """Return the list of alive players."""
        return filter(lambda p: p.is_alive, self.players.values())

    @property
    def players_list(self):
        """Return the players as a list."""
        return [self.players[i] for i in xrange(len(self.players))]

    def play_turn(self):
        """Play one turn for all alive players."""
        self.turn_count += 1
        self.log('Starting turn {}'.format(self.turn_count))
        for player in self.alive_players:
            self.play_player_turn(player)
        for player in self.players_list:
            player.check_stderr()
        self.log('Completed turn {}'.format(self.turn_count))