def get_move(self, index): """Return the move with a given number as a string. :return: "UP", "DOWN", "LEFT", "RIGHT" or None. """ try: if index >= 0: last = self.points[index + 1] prev = self.points[index] else: last = self.points[index] prev = self.points[index - 1] except IndexError: return None last, prev = map(lambda pt: TronGrid.coords2index(*pt), [last, prev]) offset = last - prev r_dir = {off: dir for dir, off in TronGrid.DIRECTIONS.items()} return r_dir.get(offset, None)
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))
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))
def center(): return TronGrid.coords2index(15, 10)