def __init__(self): self.maps = [] self.maps.append( Map(f"{self.hibikase_path}/bg.png", f"{self.hibikase_path}/miku.mp3", f"{self.hibikase_path}/normal-hitclap.wav", 140, (174, 124, 64), [])) self.maps.append( Map(f"{self.modoki_path}/ss.jpg", f"{self.modoki_path}/Harumodoki.mp3", f"{self.modoki_path}/soft-hitclap.wav", 174, (174, 124, 64), [(0, 4), (6, 2), (15, 4), (50, 2)])) self.maps.append( Map(f"{self.dora_path}/doradura.jpg", f"{self.dora_path}/audio.mp3", f"{self.dora_path}/drum-hitclap.wav", 120, (174, 124, 64), []))
def load_state(self): state = read(sys.stdin.buffer) if self.map: # update map from the passed log-formatted state self.map.update_from_log(state["m"]) else: # or create map if needed self.map = Map.create_from_log(state["m"], len(state["r"])) # parse my resources out self.me["resources"] = state["r"][self.myId]
def playGame(): _map = Map(70, 50) _map.generate_Dungeon(70, 50) playerx, playery = _map.findPlayerLoc() player = Player(playerx, playery, False, 100, '@', "Tom") terminal.clear() _map.do_fov(player.x, player.y, constants.FOV_RADIUS) while True: ex = gameTick(_map, player) if ex == 2: terminal.bkcolor(black) break
def __init__(self, bots, uniform=False): self.map = Map(len(bots), uniform) self.initialize_players(bots, self.map) self.logger = Logger(self.map) self.debug_fp = open(DEBUG_LOG_FN, "w") self.rules = Rules(self.map, self.players) self.iter = 0 self.winner = None self.bots = bots for b in self.bots: b.prep() for b in self.bots: b.run() super().__init__()
class GameServer(Server): channelClass = ClientChannel def __init__(self, *args, **kwargs): Server.__init__(self, *args, **kwargs) print("Launched") self.players = WeakKeyDictionary() self.gmap = Map(70, 50) self.gmap.generate_Dungeon(70, 50) def Connected(self, channel): print("Connection from:" + str(channel.addr)) self.AddPlayer(channel) channel.Send({'action': 'connected'}) def AddPlayer(self, channel): self.players[channel] = True def DelPlayer(self, channel): del self.players[channel] print("Deleting Player") def SendALL(self, data): for p in self.players: print(p.name) p.Send(data) def sendMap(self, player): player.Send({'action': 'gameMap', 'gameMap': self.gmap.mapTo()}) logging.info("(Server) Sent game map to " + player.name) def Launch(self): logging.info("(Server) Launched Server") while True: self.Pump() time.sleep(0.0001)
class Game(ABC): def __init__(self, bots, uniform=False): self.map = Map(len(bots), uniform) self.initialize_players(bots, self.map) self.logger = Logger(self.map) self.debug_fp = open(DEBUG_LOG_FN, "w") self.rules = Rules(self.map, self.players) self.iter = 0 self.winner = None self.bots = bots for b in self.bots: b.prep() for b in self.bots: b.run() super().__init__() # -------------------------------------------------------------------------- # MAIN METHODS # initalizes players def initialize_players(self, bots, map): self.players = [] positions = STARTING_POSITIONS[len(bots) - 1] # create a player object for each bot for count, bot in enumerate(bots): pos = Coordinate(x=positions[count][0], y=positions[count][1]) self.players.append(Player(count, self.map, bots[count], pos)) # create a starting hive for each player for player in self.players: self.map.get_cell(player.starting_pos).create_hive(player.playerId) # runs a game and returns when it is over def start(self): for p in self.players: p.send_init_data() # loop until somebody wins, or we time out! while not self.is_game_over(): # reset log for this turn self.logger.new_turn(self.map, self.players) self.send_state() self.read_moves() # log that the turn is over self.logger.end_turn() self.iter += 1 # once game ends, log one more turn, # so that viz has a final state to work with self.logger.new_turn(self.map, self.players) self.logger.end_turn() self.rank_players() self.log_winner() # send all players the updated game state so they can make decisions def send_state(self): # use the logger's representation of the map cur_state = self.logger.get_current_turn() # and send that to everyone for p in self.players: p.send_state(cur_state) # read all moves from the players and update state accordingly def read_moves(self): moves_by_player = [] # will be nested list [ [commands for player1], [commands for player2], ... ] for p in self.players: m = p.get_move() moves_by_player.append(m) # check moves for combat, and sort by type of command # run both players moves through combat phase, return updated list of moves moves_by_player = self.rules.update_combat_phase(moves_by_player) moves_by_player = sort_moves(moves_by_player) moves_by_player = self.add_implicit_commands(moves_by_player) for player_moves in moves_by_player: self.execute_moves(player_moves) # update statuses / unit numbers, etc. for col in self.map.cells: for cell in col: cell.update_cell(self.players) # returns true if at least one player in the game is still "alive" # in terms of valid code execution def has_running_player(self): for p in self.players: # if any player is alive, return true if not (p.crashed or p.timed_out): return True return False def is_game_over(self): return self.has_combat_winner() or self.time_limit_reached() or ( not self.has_running_player()) def rank_players(self): crashed_players = [] # bots that crashed valid_players = [] # bots that did not crash # partition players by whether they crashed for p in self.players: (crashed_players if p.crashed else valid_players).append(p) # first we order by # of units, then by # of hives # effectively, this uses units as tiebreaker, since the sort is stable ranked_players = sorted(valid_players, key=lambda p: p.total_units(), reverse=True) ranked_players = sorted(ranked_players, key=lambda p: len(p.get_hives()), reverse=True) for i, p in enumerate(ranked_players): p.rank = i + 1 # we'll say that all crashed players tied rank_crashed = len(valid_players) + 1 for p in crashed_players: p.rank = rank_crashed # put them all together self.ranked_players = ranked_players + crashed_players # returns true if only one player has hives left def has_combat_winner(self): return sum([1 for p in self.players if p.has_hive()]) <= 1 # returns true if the game is over due to time def time_limit_reached(self): return self.iter >= MAX_ITERS # -------------------------------------------------------------------------- # PLAYER MOVEMENT METHODS def execute_moves(self, moves): for move in moves: self.execute_move(move) def execute_move(self, move): if self.rules.verify_move(move): self.rules.update_by_move(move) self.logger.add_move(move) def count_units_sent(self, moves): cells = {} for move in moves: if move.position not in cells: cells[move.position] = move.num_units else: cells[move.position] += move.num_units return cells def add_implicit_commands(self, moves): new_moves = copy(moves) counts = [] for player_moves in moves: counts.append(self.count_units_sent(player_moves)) for i, command_count in enumerate(counts): for cell_position in command_count: cell = self.map.get_cell(cell_position) if command_count[cell_position] < cell.units[i]: remaining_units = cell.units[i] - command_count[ cell_position] new_moves[i].append( Command(i, cell_position, MINE_COMMAND, remaining_units, direction=None)) return new_moves # -------------------------------------------------------------------------- # LOGGING METHODS def log_winner(self): self.logger.add_ranked_players(self.ranked_players) def write_log(self, fn): self.logger.write(fn) def get_log(self): return self.logger.get_log() def get_raw_log(self): return self.logger.get_raw_log() def get_ranked_players(self): return self.ranked_players # log to the debug file def write_debug_log(self, out): self.debug_fp.write(str(out) + "\n") self.debug_fp.flush()
def __init__(self, *args, **kwargs): Server.__init__(self, *args, **kwargs) print("Launched") self.players = WeakKeyDictionary() self.gmap = Map(70, 50) self.gmap.generate_Dungeon(70, 50)
def mpGameLoop(client): _map = Map(70, 50) player = client.players[client.name] mapReady = False while True: client.Loop() if client.msgQ.qsize() > 0: msg = client.msgQ.get() if msg['action'] == 'gameMap': _map.mapFrom(msg['gameMap']) mapReady = True playerx, playery = _map.findPlayerLoc() player.x = playerx player.y = playery terminal.clear() _map.do_fov(player.x, player.y, constants.FOV_RADIUS) if mapReady: _map.render_map() terminal.layer(1) for k, v in client.players.items(): v.draw() terminal.refresh() terminal.layer(1) for k, v in client.players.items(): v.clear() ex = handle_keys(player, _map.game_map) if ex == 1: _map.do_fov(player.x, player.y, constants.FOV_RADIUS) client.Send({ 'action': 'posUpdate', 'posUpdate': [player.x, player.y] }) if ex == 2: terminal.bkcolor(black) break
def mapFromYaml( self, dotsName: str, yaml: dict[str, dict[str, Union[str, dict[str, Union[str, int]]]]] ) -> None: flavor = yaml.get("flavor", {}) map = Map(flavor) zones = yaml.get("zones") if not isinstance(zones, dict): raise LoadException( f"`zones` value in Map was not a dict (got: {zones})") for locName in zones: map.addZone(locName) for locName in zones: data = zones[locName] if not data: continue if data and not isinstance(data, str): raise LoadException( f"`{locName}` value in map was not a str (got: {data})") connections = data.split(", ") for connection in connections: if not map.getZone(connection): LoadException( f"Found invalid connection `{connection}` in `{locName}` in Map" ) map.connectZone(locName, connections) troves = yaml.get("troves", {}) if not isinstance(troves, dict): raise LoadException( f"`troves` value in Map was not a dict (got: {troves})") for troveName in troves: data = troves[troveName] pool = data.get("pool", []) count = data.get("count", 0) if pool and not count: raise LoadException( f"Trove had `pool` value but no `count` value, `count` must be at least 1" ) if (not pool) and count: raise LoadException( f"Trove had `count` value but no `pool` value, `pool` must exist to randomly choose Items" ) has = data.get("has", []) if not (pool or has): raise LoadException( f"Trove requires either `pool` or `has` values, neither were found in Trove `{troveName}`" ) if pool: pool = commas.split(pool) pool = [spaces.split(tags) for tags in pool] for tags in pool: if tags[0] == "": raise LoadException( f"Got an empty `pool` tag list entry") if has: has = commas.split(has) trove = Trove(troveName, count, pool, has) map.addTrove(trove) self.maps[dotsName] = map
def __init__(self): self.map = Map(Map.MEDIUM) self.world = World(self.map) self.window = Window(self.world) self.inputHandler = InputHandler(self.world, self.window)