def updateMap(self, m: Map) -> Map: if len(m.id) != 24: return m result = mapCol.update_one({'_id': ObjectId(m.id)}, {'$set': m.toDBMap()}, upsert=True) if result.upserted_id: m.id = str(result.upserted_id) return m
def __init__(self): self.direction = 'down' self.hero_stat_statusbar = None self.level = 1 self.view = View(self.level) self.map = Map() self.hero = Hero(self.map.occupied_tile_position) self.game_start(self.level) self.view.master.mainloop()
def add_map_to_database(user_id, map_name, map_description): """Add map to database""" url_hash = uuid.uuid4() #generate random uuid (universal unique identifier) for map map_hex = url_hash.hex new_map = Map(user_id=user_id, map_name=map_name, map_description=map_description, map_url_hash=map_hex) db.session.add(new_map) db.session.commit()
def runTest(self): size = [10, 5] self.assertEqual(5, len(Map.generate_map(size))) ocean_test = Map('config.json') self.assertEqual(False, ocean_test.check_prey(0, 0)) self.assertEqual(False, ocean_test.check_predator(1, 1)) self.assertEqual(True, ocean_test.check_move(ocean_test.predators[0], 0))
def _map_init(self, map_msg): row_num = map_msg["rows"] col_num = map_msg["cols"] input_cells = [[Cell(row=row, col=col) for col in range(col_num)] for row in range(row_num)] paths = [Path(id=path["id"], cells=[input_cells[cell["row"]][cell["col"]] for cell in path["cells"]] ) for path in map_msg["paths"]] kings = [King(player_id=king["playerId"], center=input_cells[king["center"]["row"]][king["center"]["col"]], hp=king["hp"], attack=king["attack"], range=king["range"], target=None, target_cell=None, is_alive=True) for king in map_msg["kings"]] self.players = [Player(player_id=map_msg["kings"][i]["playerId"], king=kings[i], deck=[], hand=[], ap=self.game_constants.max_ap, paths_from_player=self._get_paths_starting_with(kings[i].center, paths), path_to_friend=self._find_path_starting_and_ending_with(kings[i].center, kings[i ^ 1].center, paths), units=[], cast_area_spell=None, cast_unit_spell=None, duplicate_units=[], hasted_units=[], played_units=[], died_units=[], range_upgraded_unit=None, damage_upgraded_unit=None, spells=[]) for i in range(4)] for player in self.players: player.paths_from_player.remove(player.path_to_friend) self.player = self.players[0] self.player_friend = self.players[1] self.player_first_enemy = self.players[2] self.player_second_enemy = self.players[3] self.map = Map(row_num=row_num, col_num=col_num, paths=paths, kings=kings, cells=input_cells, units=[])
def get(self): global is_generated if is_generated: self.response.out.write("Fake database already generated") return #generate maps rand_maps = [] for i in range(1, 50): rand_maps.append(Map.random()) index = search.Index(maps.MAP_INDEX) index.put(rand_maps) #base_stations put_base_stations() for i in range(1, 300): put_random_scan() is_generated = True self.response.out.write("Database generated, fire away ;-)")
def saveMap(self, m: Map) -> Map: result = mapCol.insert_one(m.toDBMap()) m.id = str(result.inserted_id) return m
def assembleMap(self, item: dict) -> Map: m = Map(item) m.id = str(item['_id']) return m
def post(self): name = self.get_body_argument('name') planSize = self.get_body_arguments('planSize') planUnix = self.get_body_argument('planUnit') actualSize = self.get_body_arguments('actualSize') actualUnit = self.get_body_argument('actualUnit') originInPlan = self.get_body_arguments('originInPlan') rotationAngle = self.get_body_arguments('rotationAngle') originInActual = self.get_body_arguments('originInActual') isClockwise = bool(int(self.get_body_argument('isClockwise', False))) standardVector = self.get_body_argument('standardVector', '0,1') standardVector = [float(item) for item in standardVector.split(',')] if len(planSize) > 1: actualSize = [float(item) for item in actualSize] else: actualSize = [float(item) for item in actualSize[0].split(',')] if len(planSize) > 1: planSize = [float(item) for item in planSize] else: planSize = [float(item) for item in planSize[0].split(',')] if len(originInPlan) > 1: originInPlan = [float(item) for item in originInPlan] else: originInPlan = [float(item) for item in originInPlan[0].split(',')] if len(rotationAngle) > 1: rotationAngle = [float(item) for item in rotationAngle] else: rotationAngle = [ float(item) for item in rotationAngle[0].split(',') ] if len(originInActual) > 1: originInActual = [float(item) for item in originInActual] else: originInActual = [ float(item) for item in originInActual[0].split(',') ] planImage = self.request.files['planImage'] originName = planImage[0]['filename'] filename = name + os.path.splitext(originName)[-1] fileBody = planImage[0]['body'] planPath = localFileAdapter.save(filename, fileBody) mapDict = { 'name': name, 'planSize': planSize, 'planUnix': planUnix, 'actualSize': actualSize, 'actualUnit': actualUnit, 'originInPlan': originInPlan, 'planPath': planPath, 'originInActual': originInActual, 'rotationAngle': rotationAngle, 'isClockwise': isClockwise, 'standardVector': standardVector } logging.info(mapDict) m = Map(mapDict) m = mapService.saveMap(m) self.write({'code': 0, 'data': m.toJsonMap()})
def __init__(self): self.m = Map() self.service = Service() self.d = Drone(0, 0)
class UI: def __init__(self): self.m = Map() self.service = Service() self.d = Drone(0, 0) def prinMenu(self): print("1. AStar") print("2. Greedy") choice = int(input("Option: ")) return choice def main(self): astar_or_greedy = self.prinMenu() # we create the map self.m.randomMap() #m.saveMap("test2.map") #self.m.loadMap("test1.map") # initialize the pygame module pygame.init() # load and set the logo logo = pygame.image.load("logo32x32.png") pygame.display.set_icon(logo) pygame.display.set_caption("Path in simple environment") # we position the drone somewhere in the area x = randint(0, 19) y = randint(0, 19) #random_ending destination_x = randint(0, 19) destination_y = randint(0, 19) while self.m.surface[destination_x][destination_y] != 0: destination_x = randint(0, 19) destination_y = randint(0, 19) print("Final " + str(destination_x) + " " + str(destination_y)) #create drona self.d = Drone(x, y) # create a surface on screen that has the size of 400 x 480 screen = pygame.display.set_mode((400, 400)) screen.fill(WHITE) # define a variable to control the main loop running = True # main loop while running: # event handling, gets all event from the event queue for event in pygame.event.get(): # only do something if the event is of type QUIT if event.type == pygame.QUIT: # change the value to False, to exit the main loop running = False if event.type == KEYDOWN: self.d.move(self.m) #this call will be erased screen.blit(self.d.mapWithDrone(self.m.image()), (0, 0)) pygame.display.flip() if astar_or_greedy == 1: path = self.service.searchAStar(self.m, x, y, destination_x, destination_y) else: path = self.service.searchGreedy(self.m, x, y, destination_x, destination_y) if path: screen.blit(self.service.displayWithPath(self.m.image(), path), (0, 0)) pygame.display.flip() time.sleep(5) pygame.quit()
class World: DEBUGGING_MODE = False LOG_FILE_POINTER = None _shortest_path = dict() def __init__(self, world=None, queue=None): self._start_time = 0 self._init_message = None self._game_constants = None self._turn_updates = None self._map = None self._base_units = None self._current_turn = 0 self._players = [] self._player = None self._player_friend = None self._player_first_enemy = None self._player_second_enemy = None self._spells = [] self._cast_spells = [] if world is not None: self._init_message = world._init_message self._game_constants = world._game_constants self._turn_updates = TurnUpdates(turn_updates=world._turn_updates) self._map = world._map self._base_units = world._base_units self._spells = world._spells self._current_turn = world._current_turn self._players = world._players self._player = world._player self._player_friend = world._player_friend self._player_first_enemy = world._player_first_enemy self._player_second_enemy = world._player_second_enemy self._cast_spells = world._cast_spells self._queue = world._queue else: self._queue = queue if len(World._shortest_path) == 0: self._pre_process_shortest_path() def _pre_process_shortest_path(self): def path_count(paths_from_player, paths_from_friend, path_to_friend): shortest_path = [[None for i in range(self._map.col_num)] for j in range(self._map.row_num)] shortest_dist = [[0 for i in range(self._map.col_num)] for j in range(self._map.row_num)] for p in paths_from_player: num = 0 for c in p.cells: row = c.row col = c.col if shortest_path[row][col] is None: shortest_path[row][col] = p shortest_dist[row][col] = num elif shortest_dist[row][col] > num: shortest_dist[row][col] = num shortest_path[row][col] = p num += 1 l = len(path_to_friend.cells) for p in paths_from_friend: num = l - 1 for c in p.cells: row = c.row col = c.col if shortest_path[row][col] is None: shortest_path[row][col] = p shortest_dist[row][col] = num elif shortest_dist[row][col] > num: shortest_dist[row][col] = num shortest_path[row][col] = p num += 1 return shortest_path for player in self._players: World._shortest_path.update({ player.player_id: path_count( player.paths_from_player, self._get_friend_by_id(player.player_id).paths_from_player, player.path_to_friend) }) def _get_current_time_millis(self): return int(round(time.time() * 1000)) def _get_time_past(self): return self._get_current_time_millis() - self._start_time def _game_constant_init(self, game_constants_msg): self._game_constants = GameConstants( max_ap=game_constants_msg["maxAP"], max_turns=game_constants_msg["maxTurns"], turn_timeout=game_constants_msg["turnTimeout"], pick_timeout=game_constants_msg["pickTimeout"], turns_to_upgrade=game_constants_msg["turnsToUpgrade"], turns_to_spell=game_constants_msg["turnsToSpell"], damage_upgrade_addition=game_constants_msg[ "damageUpgradeAddition"], range_upgrade_addition=game_constants_msg["rangeUpgradeAddition"], hand_size=game_constants_msg["handSize"], deck_size=game_constants_msg["deckSize"], ap_addition=game_constants_msg["apAddition"]) def _find_path_starting_and_ending_with(self, first, last, paths): for path in paths: c_path = Path(path=path) if c_path.cells[0] == first and c_path.cells[-1] == last: return c_path c_path.cells.reverse() if c_path.cells[0] == first and c_path.cells[-1] == last: return c_path return None def _map_init(self, map_msg): row_num = map_msg["rows"] col_num = map_msg["cols"] input_cells = [[Cell(row=row, col=col) for col in range(col_num)] for row in range(row_num)] paths = [ Path(id=path["id"], cells=[ input_cells[cell["row"]][cell["col"]] for cell in path["cells"] ]) for path in map_msg["paths"] ] kings = [ King(player_id=king["playerId"], center=input_cells[king["center"]["row"]][king["center"] ["col"]], hp=king["hp"], attack=king["attack"], range=king["range"], target=None, target_cell=None, is_alive=True) for king in map_msg["kings"] ] self._players = [ Player(player_id=map_msg["kings"][i]["playerId"], king=kings[i], deck=[], hand=[], ap=self._game_constants.max_ap, paths_from_player=self._get_paths_starting_with( kings[i].center, paths), path_to_friend=self._find_path_starting_and_ending_with( kings[i].center, kings[i ^ 1].center, paths), units=[], cast_area_spell=None, cast_unit_spell=None, duplicate_units=[], hasted_units=[], played_units=[], died_units=[], range_upgraded_unit=None, damage_upgraded_unit=None, spells=[]) for i in range(4) ] for player in self._players: player.paths_from_player.remove(player.path_to_friend) self._player = self._players[0] self._player_friend = self._players[1] self._player_first_enemy = self._players[2] self._player_second_enemy = self._players[3] self._map = Map(row_num=row_num, col_num=col_num, paths=paths, kings=kings, cells=input_cells, units=[]) def _base_unit_init(self, msg): self._base_units = [ BaseUnit(type_id=b_unit["typeId"], max_hp=b_unit["maxHP"], base_attack=b_unit["baseAttack"], base_range=b_unit["baseRange"], target_type=UnitTarget.get_value(b_unit["target"]), is_flying=b_unit["isFlying"], is_multiple=b_unit["isMultiple"], ap=b_unit["ap"]) for b_unit in msg ] def _get_base_unit_by_id(self, type_id): for base_unit in self._base_units: if base_unit.type_id == type_id: return base_unit return None def _spells_init(self, msg): self._spells = [ Spell(type=SpellType.get_value(spell["type"]), type_id=spell["typeId"], duration=spell["duration"], priority=spell["priority"], range=spell["range"], power=spell["power"], target=SpellTarget.get_value(spell["target"]), is_damaging=spell["power"] < 0) for spell in msg ] def _handle_init_message(self, msg): self._init_message = msg self._start_time = self._get_current_time_millis() self._game_constant_init(msg['gameConstants']) self._map_init(msg["map"]) self._base_unit_init(msg["baseUnits"]) self._spells_init(msg["spells"]) self._current_turn = 0 def _handle_turn_kings(self, msg): for king_msg in msg: self.get_player_by_id( king_msg["playerId"]).king.is_alive = king_msg["isAlive"] self.get_player_by_id( king_msg["playerId"]).king.hp = king_msg["hp"] if king_msg["target"] != -1: self.get_player_by_id( king_msg["playerId"]).king.target = self.get_unit_by_id( king_msg["target"]) self.get_player_by_id(king_msg["playerId"] ).king.target_cell = self.get_unit_by_id( king_msg["target"]).cell else: self.get_player_by_id(king_msg["playerId"]).king.target = None self.get_player_by_id( king_msg["playerId"]).king.target_cell = None def _handle_turn_units(self, msg, is_dead_unit=False): if not is_dead_unit: self._map._clear_units() for player in self._players: player.units.clear() player.played_units.clear() player.hasted_units.clear() player.duplicate_units.clear() player.range_upgraded_unit = None player.damage_upgraded_unit = None else: for player in self._players: player.died_units.clear() unit_input_list = [] for unit_msg in msg: unit_id = unit_msg["unitId"] player = self.get_player_by_id(player_id=unit_msg["playerId"]) base_unit = self._base_units[unit_msg["typeId"]] if not unit_msg['target'] == -1: target_cell = Cell(row=unit_msg["targetCell"]["row"], col=unit_msg["targetCell"]["col"]) else: target_cell = None unit = Unit( unit_id=unit_id, base_unit=base_unit, cell=self._map.get_cell(unit_msg["cell"]["row"], unit_msg["cell"]["col"]), path=self._map.get_path_by_id(unit_msg["pathId"]), hp=unit_msg["hp"], damage_level=unit_msg["damageLevel"], range_level=unit_msg["rangeLevel"], is_duplicate=unit_msg["isDuplicate"], is_hasted=unit_msg["isHasted"], range=unit_msg["range"], attack=unit_msg["attack"], target=None, # will be set later when all units are in set target_cell=target_cell, affected_spells=[ self.get_cast_spell_by_id(cast_spell_id) for cast_spell_id in unit_msg["affectedSpells"] ], target_if_king=None if self.get_player_by_id(unit_msg["target"]) is None else self.get_player_by_id(unit_msg["target"]).king, player_id=unit_msg["playerId"]) unit_input_list.append(unit) if unit.path is not None: if self.get_player_by_id( unit.player_id ).king.center in unit.path.cells and unit.path.cells[ 0] != self.get_player_by_id( unit.player_id).king.center: unit.path = Path(path=unit.path) unit.path.cells.reverse() if self._get_friend_by_id( unit.player_id ).king.center in unit.path.cells and unit.path.cells[ 0] != self._get_friend_by_id( unit.player_id).king.center: unit.path = Path(path=unit.path) unit.path.cells.reverse() if not is_dead_unit: self._map._add_unit_in_cell(unit.cell.row, unit.cell.col, unit) player.units.append(unit) if unit_msg["wasDamageUpgraded"]: player.damage_upgraded_unit = unit if unit_msg["wasRangeUpgraded"]: player.range_upgraded_unit = unit if unit_msg["wasPlayedThisTurn"]: player.played_units.append(unit) if unit.is_hasted: player.hasted_units.append(unit) if unit.is_duplicate: player.duplicate_units.append(unit) else: player.died_units.append(unit) for i in range(len(unit_input_list)): unit = unit_input_list[i] if unit.target_if_king is not None: unit.target = None else: unit.target = self.get_unit_by_id(msg[i]["target"]) def _handle_turn_cast_spells(self, msg): self._cast_spells = [] for cast_spell_msg in msg: spell = self.get_spell_by_id(cast_spell_msg["typeId"]) cell = self._map.get_cell(cast_spell_msg["cell"]["row"], cast_spell_msg["cell"]["col"]) affected_units = [ self.get_unit_by_id(affected_unit_id) for affected_unit_id in cast_spell_msg["affectedUnits"] ] if spell.is_area_spell(): cast_area_spell = CastAreaSpell( spell=spell, id=cast_spell_msg["id"], caster_id=cast_spell_msg["casterId"], cell=cell, remaining_turns=cast_spell_msg["remainingTurns"], affected_units=affected_units) self._cast_spells.append(cast_area_spell) if cast_spell_msg["wasCastThisTurn"]: self.get_player_by_id(cast_spell_msg["casterId"] ).cast_area_spell = cast_area_spell elif spell.is_unit_spell(): cast_unit_spell = CastUnitSpell( spell=spell, id=cast_spell_msg["id"], caster_id=cast_spell_msg["casterId"], cell=cell, unit=self.get_unit_by_id(cast_spell_msg["unitId"]), path=self._map.get_path_by_id(cast_spell_msg["pathId"]), affected_units=affected_units) self._cast_spells.append(cast_unit_spell) if cast_spell_msg["wasCastThisTurn"]: self.get_player_by_id(cast_spell_msg["casterId"] ).cast_unit_spell = cast_unit_spell def get_cast_spell_by_id(self, id: int) -> Optional["CastSpell"]: for cast_spell in self._cast_spells: if cast_spell.id == id: return cast_spell return None def _handle_turn_message(self, msg): self._start_time = self._get_current_time_millis() self._handle_init_message(self._init_message) self._current_turn = msg['currTurn'] self._player.deck = [ self._get_base_unit_by_id(deck_type_id) for deck_type_id in msg["deck"] ] self._player.hand = [ self._get_base_unit_by_id(hand_type_id) for hand_type_id in msg["hand"] ] self._handle_turn_units(msg=msg["diedUnits"], is_dead_unit=True) self._handle_turn_cast_spells(msg["castSpells"]) self._handle_turn_units(msg["units"]) self._handle_turn_kings(msg["kings"]) self._turn_updates = TurnUpdates( received_spell=msg["receivedSpell"], friend_received_spell=msg["friendReceivedSpell"], got_range_upgrade=msg["gotRangeUpgrade"], got_damage_upgrade=msg["gotDamageUpgrade"], available_range_upgrades=msg["availableRangeUpgrades"], available_damage_upgrades=msg["availableDamageUpgrades"]) self._player.set_spells( [self.get_spell_by_id(spell_id) for spell_id in msg["mySpells"]]) self._player_friend.set_spells([ self.get_spell_by_id(spell_id) for spell_id in msg["friendSpells"] ]) self._player.ap = msg["remainingAP"] def choose_hand_by_id(self, type_ids: List[int]) -> None: message = Message(type="pick", turn=self.get_current_turn(), info=None) if type_ids is not None: for type_id in type_ids: if type(type_id) is not int: Logs.show_log("type_ids are not int") return message.info = {"units": type_ids} self._queue.put(message) else: Logs.show_log( "choose_hand_by_id function called with None type_eds") # in the first turn 'deck picking' give unit_ids or list of unit names to pick in that turn def choose_hand(self, base_units: List[BaseUnit]) -> None: message = Message(type="pick", turn=self.get_current_turn(), info=None) if base_units is not None: for base_unit in base_units: if type(base_unit) is not BaseUnit: Logs.show_log("base_units is not an array of BaseUnits") return message.info = {"units": [unit.type_id for unit in base_units]} self._queue.put(message) else: Logs.show_log("choose_hand function called with None base_units") def get_me(self) -> Player: return self._player def get_friend(self) -> Player: return self._player_friend def _get_friend_by_id(self, player_id): if self._player.player_id == player_id: return self._player_friend elif self._player_friend.player_id == player_id: return self._player elif self._player_first_enemy.player_id == player_id: return self._player_second_enemy elif self._player_second_enemy.player_id == player_id: return self._player_first_enemy else: Logs.show_log( "get_friend_by_id function no player with given player_id") return None def get_first_enemy(self) -> Player: return self._player_first_enemy def get_second_enemy(self) -> Player: return self._player_second_enemy def get_map(self) -> Map: return self._map # return a list of paths crossing one cell def get_paths_crossing_cell(self, cell: Cell = None, row: int = None, col: int = None) -> List[Path]: if cell is None: if row is None or col is None: Logs.show_log( "get_paths_crossing cell function called with no valid argument" ) return [] cell = self._map.get_cell(row, col) if not isinstance(cell, Cell): Logs.show_log("Given cell is invalid!") return [] paths = [] for p in self._map.paths: if cell in p.cells: paths.append(p) return paths # return a list of units in a cell def get_cell_units(self, cell: Cell = None, row: int = None, col: int = None) -> List[Unit]: if cell is None: if row is None and col is None: Logs.show_log( "get_paths_crossing cell function called with no valid argument" ) return [] cell = self._map.get_cell(row, col) if not isinstance(cell, Cell): Logs.show_log("Given cell is invalid!") return [] return cell.units # return the shortest path from player_id fortress to cell # this path is in the available path list # path may cross from friend def get_shortest_path_to_cell(self, from_player_id: int = None, from_player: Player = None, cell: Cell = None, row: int = None, col: int = None) -> Optional["Path"]: if from_player is not None: from_player_id = from_player.player_id elif from_player_id is None: return None if self.get_player_by_id(from_player_id) is None: return None if cell is None: if row is None or col is None: return None cell = self._map.get_cell(row, col) shortest_path_from_player = World._shortest_path.get( from_player_id, None) if shortest_path_from_player is None: return None return shortest_path_from_player[cell.row][cell.col] # place unit with type_id in path_id def put_unit(self, type_id: int = None, path_id: int = None, base_unit: BaseUnit = None, path: Path = None) -> None: fail = False if type_id is not None and type(type_id) is not int: Logs.show_log( "put_unit function called with invalid type_id argument!") fail = True if path_id is not None and type(path_id) is not int: Logs.show_log( "put_unit function called with invalid path_id argument!") fail = True if base_unit is not None and type(base_unit) is not BaseUnit: Logs.show_log( "put_unit function called with invalid base_unit argument") fail = True if path is not None and type(path) is not Path: Logs.show_log( "put_unit function called with invalid path argument") fail = True if fail is True: return if base_unit is not None: type_id = base_unit.type_id if path is not None: path_id = path.id if path_id is None or type_id is None: return None if type_id is None: Logs.show_log("type_id is None in cast_area spell function call!") return message = Message(turn=self.get_current_turn(), type="putUnit", info={ "typeId": type_id, "pathId": path_id }) self._queue.put(message) # return the number of turns passed def get_current_turn(self) -> int: return self._current_turn def get_remaining_time(self) -> int: if self.get_current_turn() > 0: return self._game_constants.turn_timeout - self._get_time_past() else: return self._game_constants.pick_timeout - self._get_time_past() # put unit_id in path_id in position 'index' all spells of one kind have the same id def cast_unit_spell(self, unit: Unit = None, unit_id: int = None, path: Path = None, path_id: int = None, cell: Cell = None, row: int = None, col: int = None, spell: Spell = None, spell_id: int = None) -> None: if spell is None and spell_id is None: Logs.show_log( "cast_unit_spell function called with no spell input!") return None if spell is None: if type(spell_id) is not int: Logs.show_log( "spell_id is not an integer in cast_unit_spell function call!" ) return spell = self.get_spell_by_id(spell_id) if row is not None and col is not None: if type(row) is not int or type(col) is not int: Logs.show_log( "row and column arguments are invalid in cast_unit_spell function call" ) return cell = Cell(row, col) if unit is not None: if type(unit) is not Unit: Logs.show_log( "unit argument is invalid in cast_unit_spell function call" ) return unit_id = unit.unit_id if path is not None: if type(path) is not Path: Logs.show_log( "path argument is invalid in cast_unit_spell function call" ) return path_id = path.id if type(unit_id) is not int: Logs.show_log( "unit_id argument is invalid in cast_unit_spell function call") return if type(path_id) is not int: Logs.show_log( "path_id argument is invalid in cast_unit_spell function call") return message = Message(type="castSpell", turn=self.get_current_turn(), info={ "typeId": spell.type_id, "cell": { "row": cell.row, "col": cell.col }, "unitId": unit_id, "pathId": path_id }) self._queue.put(message) # cast spell in the cell 'center' def cast_area_spell(self, center: Cell = None, row: int = None, col: int = None, spell: Spell = None, spell_id: int = None) -> None: if spell is None: if spell_id is None or type(spell_id) is not int: Logs.show_log("no valid spell selected in cast_area_spell!") return spell = self.get_spell_by_id(spell_id) if type(spell) is not Spell: Logs.show_log("no valid spell selected in cast_area_spell!") return if row is not None and col is not None: center = self._map.get_cell(row, col) if center is not None: message = Message(type="castSpell", turn=self.get_current_turn(), info={ "typeId": spell.type_id, "cell": { "row": center.row, "col": center.col }, "unitId": -1, "pathId": -1 }) self._queue.put(message) else: Logs.show_log("invalid cell selected in cast_area_spell") # returns a list of units the spell casts effects on def get_area_spell_targets(self, center: Cell = None, row: int = None, col: int = None, spell: Spell = None, type_id: int = None) -> List["Unit"]: if spell is None: if type_id is not None: spell = self.get_cast_spell_by_id(type_id) else: return [] if type(spell) is not Spell: Logs.show_log("invalid spell chosen in get_area_spell_targets") return [] if not spell.is_area_spell(): return [] if center is None: center = Cell(row, col) ls = [] for i in range(max(0, center.row - spell.range), min(center.row + spell.range + 1, self._map.row_num)): for j in range( max(0, center.col - spell.range), min(center.col + spell.range + 1, self._map.col_num)): cell = self._map.get_cell(i, j) for u in cell.units: if self._is_unit_targeted(u, spell.target): ls.append(u) return ls def _is_unit_targeted(self, unit, spell_target): if spell_target == SpellTarget.SELF: if unit in self._player.units: return True elif spell_target == SpellTarget.ALLIED: if unit in self._player_friend.units or unit in self._player.units: return True elif spell_target == SpellTarget.ENEMY: if unit in self._player_first_enemy.units or unit in self._player_second_enemy.units: return True return False # every once in a while you can upgrade, this returns the remaining time for upgrade def get_remaining_turns_to_upgrade(self) -> int: rem_turn = (self._game_constants.turns_to_upgrade - self._current_turn) % self._game_constants.turns_to_upgrade if rem_turn == 0: return self._game_constants.turns_to_upgrade return rem_turn # every once in a while a spell is given this remains the remaining time to get new spell def get_remaining_turns_to_get_spell(self) -> int: rem_turn = (self._game_constants.turns_to_spell - self._current_turn) % self._game_constants.turns_to_spell if rem_turn == 0: return self._game_constants.turns_to_spell return rem_turn # returns a list of spells casted on a cell def get_range_upgrade_number(self) -> int: return self._turn_updates.available_range_upgrade def get_damage_upgrade_number(self) -> int: return self._turn_updates.available_damage_upgrade # returns the spell given in that turn def get_received_spell(self) -> Optional["Spell"]: spell_id = self._turn_updates.received_spell spell = self.get_spell_by_id(spell_id) return spell # returns the spell given in that turn to friend def get_friend_received_spell(self) -> Optional["Spell"]: spell_id = self._turn_updates.friend_received_spell spell = self.get_spell_by_id(spell_id) return spell def upgrade_unit_range(self, unit: Unit = None, unit_id: int = None) -> None: if unit is not None: unit_id = unit.unit_id if unit_id is not None and type(unit_id) is int: self._queue.put( Message(type="rangeUpgrade", turn=self.get_current_turn(), info={"unitId": unit_id})) else: Logs.show_log("invalid unit or unit_id in upgrade_unit_range") def upgrade_unit_damage(self, unit: Unit = None, unit_id: int = None) -> None: if unit is not None: unit_id = unit.unit_id if unit_id is not None and type(unit_id) is int: self._queue.put( Message(type="damageUpgrade", turn=self.get_current_turn(), info={"unitId": unit_id})) else: Logs.show_log("invalid unit or unit_id in upgrade_unit_damage") def get_all_base_units(self) -> List[BaseUnit]: return copy.deepcopy(self._base_units) def get_all_spells(self) -> List[Spell]: return copy.deepcopy(self._spells) def get_king_by_id(self, player_id: int) -> Optional["King"]: for p in self._players: if p.player_id == player_id: return p.king return None def get_base_unit_by_id(self, type_id: int) -> Optional["BaseUnit"]: for bu in self._base_units: if bu.type_id == type_id: return bu return None # returns unit in map with a unit_id def get_unit_by_id(self, unit_id: int) -> Optional["Unit"]: for unit in self._map.units: if unit.unit_id == unit_id: return unit return None def get_player_by_id(self, player_id: int) -> Optional["Player"]: for player in self._players: if player.player_id == player_id: return player return None def get_spell_by_id(self, type_id: int) -> Optional["Spell"]: for spell in self._spells: if spell.type_id == type_id: return spell return None def get_game_constants(self) -> GameConstants: return self._game_constants def _get_paths_starting_with(self, first, paths): ret = [] for path in paths: c_path = Path(path=path) if c_path.cells[-1] == first: c_path.cells.reverse() if c_path.cells[0] == first: ret.append(c_path) return ret def _handle_end_message(self, scores_list_msg): return dict([(score["playerId"], score["score"]) for score in scores_list_msg])
class Game(): def __init__(self): self.direction = 'down' self.hero_stat_statusbar = None self.level = 1 self.view = View(self.level) self.map = Map() self.hero = Hero(self.map.occupied_tile_position) self.game_start(self.level) self.view.master.mainloop() def game_start(self, level): self.hero_move_number = 0 self.map.next_level_map() self.view.display_map(self.map.occupied_tile_position) self.view.statusbar_text(self.level, self.hero_stat_statusbar) self.hero.position = self.hero.randomize_position( self.map.occupied_tile_position) self.view.display_intro(self.level) self.generate_enemies(level) self.hero.restore_health() self.enemy_stat_statusbar = None self.input_event() # *********************Events********************** def input_event(self): self.view.master.bind('<s>', self.set_move) self.view.master.bind('<w>', self.set_move) self.view.master.bind('<a>', self.set_move) self.view.master.bind('<d>', self.set_move) self.view.master.bind('<space>', self.battle) self.view.master.bind('<Escape>', self.quit) def set_move(self, event): if event.char == 'w': self.hero.position, self.map.occupied_tile_position = self.hero.move( self.hero.moves['up'], self.map.occupied_tile_position) self.direction = 'up' elif event.char == 's': self.hero.position, self.map.occupied_tile_position = self.hero.move( self.hero.moves['down'], self.map.occupied_tile_position) self.direction = 'down' elif event.char == 'a': self.hero.position, self.map.occupied_tile_position = self.hero.move( self.hero.moves['left'], self.map.occupied_tile_position) self.direction = 'left' elif event.char == 'd': self.hero.position, self.map.occupied_tile_position = self.hero.move( self.hero.moves['right'], self.map.occupied_tile_position) self.direction = 'right' self.hero_move_number += 1 self.view.display_hero(self.hero.position, self.direction, self.hero.isDead) self.generate_enemy_moves() self.view.display_enemies(self.enemy_list) self.update_hero_status() self.enemy_stat_statusbar = None self.view.statusbar_text(self.level, self.hero_stat_statusbar) if self.hero_move_number > 0: self.start() def generate_enemy_moves(self): if self.hero_move_number % 2: for enemy in self.enemy_list: enemy.position, self.map.occupied_tile_position = enemy.move( choice(list(enemy.moves.values())), self.map.occupied_tile_position) def battle(self, event): x_coord = self.hero.position[0] + self.hero.moves[self.direction][0] y_coord = self.hero.position[1] + self.hero.moves[self.direction][1] attack_coords = [x_coord, y_coord] attacked_enemy = self.check_attacked_enemy(attack_coords) if attacked_enemy == None: return attacked_enemy.current_HP -= max( self.hero.stats[2] + randint(1, 6) - attacked_enemy.stats[1], 0) self.hero.current_HP -= max( attacked_enemy.stats[2] + randint(1, 6) - self.hero.stats[1], 0) self.view.display_attack(self.hero.position, attacked_enemy.position) self.update_hero_status() self.update_enemy_stats(attacked_enemy) self.view.statusbar_text(self.level, self.hero_stat_statusbar, self.enemy_stat_statusbar) if attacked_enemy.current_HP <= 0: self.kill_enemy(attacked_enemy) if self.hero.current_HP <= 0: self.game_over() def check_attacked_enemy(self, attack_coords): attacked_enemy = None if len(self.enemy_list) != 0: for enemy in self.enemy_list: if enemy.position == attack_coords: attacked_enemy = enemy return attacked_enemy def kill_enemy(self, attacked_enemy): self.map.occupied_tile_position[attacked_enemy.position[1]][ attacked_enemy.position[0]] = 0 self.enemy_list.remove(attacked_enemy) self.view.display_enemies(self.enemy_list) self.view.display_kill(attacked_enemy.position) self.hero.level_up() if attacked_enemy.has_key == True: self.hero.has_key = True if type(attacked_enemy) == Boss: self.hero.has_killed_boss = True if self.hero.has_key == True and self.hero.has_killed_boss == True: self.new_game() def game_over(self): self.enemy_list = [] self.hero.isDead = True self.view.display_enemies(self.enemy_list) self.view.display_hero(self.hero.position, self.direction, self.hero.isDead) self.view.display_game_over() def new_game(self): self.level += 1 self.game_start(self.level) self.hero.has_killed_boss = False self.hero.has_key = False def quit(self, event): self.view.master.destroy() def start(self): self.view.delete_pictures() self.view.display_hero(self.hero.position, self.direction, self.hero.isDead) self.view.display_enemies(self.enemy_list) def update_hero_status(self): self.hero_stat_statusbar = self.hero.stats[:] self.hero_stat_statusbar.append(self.hero.current_HP) self.hero_stat_statusbar.append(self.hero.has_key) def update_enemy_stats(self, attacked_enemy): self.enemy_stat_statusbar = attacked_enemy.stats[:] self.enemy_stat_statusbar.append(attacked_enemy.current_HP) if type(attacked_enemy) == Boss: self.enemy_stat_statusbar.append('boss') else: self.enemy_stat_statusbar.append('skeleton') # *****************Generate enemies******************* def generate_enemies(self, level): self.boss = Boss(self.map.wall_position, level) self.enemy_list = [self.boss] for i in range(self.map.number_of_skeletons): skeleton_name = 'skeleton' + str(i) self.skeleton_name = Skeleton(self.map.wall_position, level) if skeleton_name[-1:] == '0': self.skeleton_name.has_key = True self.enemy_list.append(self.skeleton_name)
def play_game(level, life_num): ''' Here is the play_game function''' # -------- SET LEVEL DIFFICULTY ----------- # level = input("How many ennemies (0 to 10) ? ") # while int(level) not in range(11): # level = input("Ennemies must be between 0 and 10 : ") Sprite.LEVEL = int(level) # from 0 to 10 # -------- INITIALIZE ----------- # DEFINE MAP map_game = Map('structures/Structure' + str(level) + '.csv') # OPEN A NEW WINDOW size = (15 * map_game.SPRITE_WIDTH, 15 * map_game.SPRITE_WIDTH) screen = py.display.set_mode(size) py.display.set_caption("Mac Gyver escapes") # CLEAR THE SCREEN TO black. black = (0, 0, 0) white = (255, 255, 255) screen.fill(black) # DRAW MAP WITH TILES tiles = Sprite('floor-tiles-20x20', map_game, (5, 0), 20) map_game.draw(tiles, screen) font = py.font.Font('ressource/ARCADECLASSIC.ttf', 25) level_text = font.render('L ' + str(level), 0, white) level_text_rect = level_text.get_rect() # INITIALIZE PERSONS ON THE MAP macgyver = Person('macgyver', map_game) guardian = Person('guardian', map_game) ennemies = [] ennemies_images = Sprite('personnages', map_game, (0, 0), 32).surfs for i in range(len(ennemies_images)): ennemy = Person('ennemy', map_game) while ennemy.distance( macgyver) <= 1: # NOT TO LOOSE AT THE BEGINNING OF GAME ennemy = Person('ennemy', map_game) ennemy.image = ennemies_images[i] ennemies.append(ennemy) # INITIALIZE OBJECTS ON THE MAP objects = Objects(map_game) objects_pos = [object.position for object in objects.list] # THE LOOP WILL CARRY ON UNTIL THE USER EXIT THE GAME. carry_on = True # WHILE NOT QUIT playing = True # WHILE NOT WIN AND NOT LOOSE update = True # WHEN KEY PRESSED win = False loose = False # THE CLOCK WILL BE USED TO CONTROL HOW FAST THE SCREEN UPDATES clock = py.time.Clock() py.key.set_repeat(400, 30) # ----------------------------------- MAIN PROGRAM LOOP ----------- while carry_on: key_pressed = 0 for event in py.event.get(): # USER DID SOMETHING if event.type == py.QUIT or py.key.get_pressed()[ py.K_ESCAPE]: # IF USER CLICKED CLOSE carry_on = False # FLAG THAT WE ARE DONE SO WE EXIT THIS LOOP return 'quit' # LISTEN FOR PRESSED KEY if event.type == py.KEYDOWN: key_pressed = event.key update = True if win: return 'win' if loose: return 'loose' # ------------------------------- EVENTS ----- if update: # MOVE ENNEMIES ON THE MAP for ennemy in ennemies: (x_en, y_en) = ennemy.position seed(datetime.now()) ennemy_move = choice( [py.K_UP, py.K_DOWN, py.K_RIGHT, py.K_LEFT]) ennemy.move(ennemy_move, map_game) # UPDATE LAST POSITION tiles.draw_sprite(map_game.decoration[(x_en, y_en)], screen, x_en * map_game.SPRITE_WIDTH, y_en * map_game.SPRITE_WIDTH) # MOVE MACGYVER ON THE MAP (x_mac1, y_mac1) = macgyver.position if playing: macgyver.move(key_pressed, map_game) # UPDATE LAST POSITION tiles.draw_sprite(map_game.decoration[(x_mac1, y_mac1)], screen, x_mac1 * map_game.SPRITE_WIDTH, y_mac1 * map_game.SPRITE_WIDTH) # ----------------------------- DRAWING CODE GOES HERE ----- # DRAW OBJECT ON THE MAP for stuff in objects.list: stuff.draw_object(screen, stuff.position[0] * map_game.SPRITE_WIDTH, stuff.position[1] * map_game.SPRITE_WIDTH) # REDRAW PERSONS guardian.draw_person(screen, guardian.position[0] * map_game.SPRITE_WIDTH, guardian.position[1] * map_game.SPRITE_WIDTH) macgyver.draw_person(screen, macgyver.position[0] * map_game.SPRITE_WIDTH, macgyver.position[1] * map_game.SPRITE_WIDTH) for ennemy in ennemies: ennemy.draw_person(screen, ennemy.position[0] * map_game.SPRITE_WIDTH, ennemy.position[1] * map_game.SPRITE_WIDTH) # REDRAW LIVES & LEVEL heart = py.transform.scale(py.image.load('ressource/heart.png'), (int(map_game.SPRITE_WIDTH / 2), int(map_game.SPRITE_WIDTH / 2))) for i in range(life_num): screen.blit(heart, (20 * i + 10, 5)) screen.blit(level_text, (screen.get_width() - level_text_rect.width - 10, 5)) # MAC GYVER TAKE AN OBJECT ON THE MAP if macgyver.position in objects_pos: # GET INDEX OF OBJECT object_found_ind = objects_pos.index(macgyver.position) # CLEAR POSITION ON THE MAP del objects_pos[object_found_ind] # CLEAR OBJECT FROM OBJECTS LIST del objects.list[object_found_ind] # COMPUTE DISTANCE FROM ENNEMIES dist_from_ennemies = [ macgyver.distance(ennemy) for ennemy in ennemies ] dist_from_ennemies.append(macgyver.distance(guardian)) # MAC GYVER WIN OR DIE if min(dist_from_ennemies) <= 1.0: playing = False if objects.list == [] and macgyver.distance(guardian) == 1: py.display.set_caption("IT'S A WIN!") end_print('you_win', 'Press any key to continue', screen) win = True else: if life_num == 1: message = 'GAME OVER' else: message = 'Press any key to continue' py.display.set_caption("YOU DIE!") end_print('you_lose', message, screen) loose = True # --- GO AHEAD AND UPDATE THE SCREEN WITH WHAT WE'VE DRAWN. --- py.display.flip() update = False # --- LIMIT TO 60 FRAMES PER SECOND --- clock.tick(60)
class World(ABC): DEBUGGING_MODE = False LOG_FILE_POINTER = None def __init__(self, world=None, queue=None): self.game_constants = None self.turn_updates = None self.map = None self.base_units = None self.current_turn = 0 self.players = [] self.player = None self.player_friend = None self.player_first_enemy = None self.player_second_enemy = None self.spells = [] self.cast_spells = [] if world is not None: self.game_constants = world.game_constants self.turn_updates = TurnUpdates(turn_updates=world.turn_updates) self.map = world.map self.base_units = world.base_units self.spells = world.spells self.current_turn = world.current_turn self.players = world.players self.player = world.player self.player_friend = world.player_friend self.player_first_enemy = world.player_first_enemy self.player_second_enemy = world.player_second_enemy self.cast_spells = world.cast_spells self.queue = world.queue else: self.queue = queue def get_current_time_millis(self): return int(round(time.time() * 1000)) def get_time_past(self): return self.get_current_time_millis() - self.start_time def get_player_by_id(self, player_id): for player in self.players: if player.player_id == player_id: return player return None def get_spell_by_id(self, type_id): for spell in self.spells: if spell.type_id == type_id: return spell return None def _game_constant_init(self, game_constants_msg): self.game_constants = GameConstants( max_ap=game_constants_msg["maxAP"], max_turns=game_constants_msg["maxTurns"], turn_timeout=game_constants_msg["turnTimeout"], pick_timeout=game_constants_msg["pickTimeout"], turns_to_upgrade=game_constants_msg["turnsToUpgrade"], turns_to_spell=game_constants_msg["turnsToSpell"], damage_upgrade_addition=game_constants_msg[ "damageUpgradeAddition"], range_upgrade_addition=game_constants_msg["rangeUpgradeAddition"], hand_size=game_constants_msg["handSize"], deck_size=game_constants_msg["deckSize"]) def _find_path_starting_and_ending_with(self, first, last, paths): for path in paths: c_path = Path(path=path) if c_path.cells[0] == first and c_path.cells[-1] == last: return c_path c_path.cells.reverse() if c_path.cells[0] == first and c_path.cells[-1] == last: return c_path return None def _map_init(self, map_msg): row_num = map_msg["rows"] col_num = map_msg["cols"] input_cells = [[Cell(row=row, col=col) for col in range(col_num)] for row in range(row_num)] paths = [ Path(id=path["id"], cells=[ input_cells[cell["row"]][cell["col"]] for cell in path["cells"] ]) for path in map_msg["paths"] ] kings = [ King(player_id=king["playerId"], center=input_cells[king["center"]["row"]][king["center"] ["col"]], hp=king["hp"], attack=king["attack"], range=king["range"], target=None, target_cell=None, is_alive=True) for king in map_msg["kings"] ] self.players = [ Player(player_id=map_msg["kings"][i]["playerId"], king=kings[i], deck=[], hand=[], ap=self.game_constants.max_ap, paths_from_player=self._get_paths_starting_with( kings[i].center, paths), path_to_friend=self._find_path_starting_and_ending_with( kings[i].center, kings[i ^ 1].center, paths), units=[], cast_area_spell=None, cast_unit_spell=None, duplicate_units=[], hasted_units=[], played_units=[], died_units=[], range_upgraded_unit=None, damage_upgraded_unit=None, spells=[]) for i in range(4) ] for player in self.players: player.paths_from_player.remove(player.path_to_friend) self.player = self.players[0] self.player_friend = self.players[1] self.player_first_enemy = self.players[2] self.player_second_enemy = self.players[3] self.map = Map(row_num=row_num, column_num=col_num, paths=paths, kings=kings, cells=input_cells, units=[]) # returns unit in map with a unit_id def get_unit_by_id(self, unit_id): for unit in self.map.units: if unit.unit_id == unit_id: return unit return None def _base_unit_init(self, msg): self.base_units = [ BaseUnit(type_id=b_unit["typeId"], max_hp=b_unit["maxHP"], base_attack=b_unit["baseAttack"], base_range=b_unit["baseRange"], target_type=UnitTarget.get_value(b_unit["target"]), is_flying=b_unit["isFlying"], is_multiple=b_unit["isMultiple"], ap=b_unit["ap"]) for b_unit in msg ] def _get_base_unit_by_id(self, type_id): for base_unit in self.base_units: if base_unit.type_id == type_id: return base_unit return None def _spells_init(self, msg): self.spells = [ Spell(type=SpellType.get_value(spell["type"]), type_id=spell["typeId"], duration=spell["duration"], priority=spell["priority"], range=spell["range"], power=spell["power"], target=SpellTarget.get_value(spell["target"]), is_damaging=False) for spell in msg ] def _handle_init_message(self, msg): self._game_constant_init(msg['gameConstants']) self._map_init(msg["map"]) self._base_unit_init(msg["baseUnits"]) self._spells_init(msg["spells"]) def _handle_turn_kings(self, msg): for king_msg in msg: hp = king_msg["hp"] if (king_msg["hp"] > 0 and king_msg["isAlive"]) else -1 self.get_player_by_id(king_msg["playerId"]).king.hp = hp self.get_player_by_id(king_msg["playerId"]).king.target = king_msg[ "target"] if king_msg["target"] != -1 else None def _handle_turn_units(self, msg, is_dead_unit=False): if not is_dead_unit: self.map.clear_units() for player in self.players: player.units.clear() player.played_units.clear() player.hasted_units.clear() player.duplicate_units.clear() player.range_upgraded_unit = None player.damage_upgraded_unit = None else: for player in self.players: player.died_units.clear() for unit_msg in msg: unit_id = unit_msg["unitId"] player = self.get_player_by_id(player_id=unit_msg["playerId"]) base_unit = self.base_units[unit_msg["typeId"]] if not unit_msg['target'] == -1: target_cell = Cell(row=unit_msg["targetCell"]["row"], col=unit_msg["targetCell"]["col"]) else: target_cell = None unit = Unit(unit_id=unit_id, base_unit=base_unit, cell=self.map.get_cell(unit_msg["cell"]["row"], unit_msg["cell"]["col"]), path=self.map.get_path_by_id(unit_msg["pathId"]), hp=unit_msg["hp"], damage_level=unit_msg["damageLevel"], range_level=unit_msg["rangeLevel"], is_duplicate=unit_msg["isDuplicate"], is_hasted=unit_msg["isHasted"], range=unit_msg["range"], attack=unit_msg["attack"], target=unit_msg["target"], target_cell=target_cell, affected_spells=[ self.get_cast_spell_by_id(cast_spell_id) for cast_spell_id in unit_msg["affectedSpells"] ], target_if_king=None if self.get_player_by_id(unit_msg["target"]) == None else self.get_player_by_id(unit_msg["target"]).king, player_id=unit_msg["playerId"]) if not is_dead_unit: self.map.add_unit_in_cell(unit.cell.row, unit.cell.col, unit) player.units.append(unit) if unit_msg["wasDamageUpgraded"]: player.damage_upgraded_unit = unit if unit_msg["wasRangeUpgraded"]: player.range_upgraded_unit = unit if unit_msg["wasPlayedThisTurn"]: player.played_units.append(unit) if unit.is_hasted: player.hasted_units.append(unit) if unit.is_duplicate: player.duplicate_units.append(unit) else: player.died_units.append(unit) for unit in self.map.units: if unit.target == -1 or unit.target_if_king != None: unit.target = None else: unit.target = self.map.get_unit_by_id(unit.target) def _handle_turn_cast_spells(self, msg): self.cast_spells = [] for cast_spell_msg in msg: spell = self.get_spell_by_id(cast_spell_msg["typeId"]) cell = self.map.get_cell(cast_spell_msg["cell"]["row"], cast_spell_msg["cell"]["col"]) affected_units = [ self.get_unit_by_id(affected_unit_id) for affected_unit_id in cast_spell_msg["affectedUnits"] ] if spell.is_area_spell(): self.cast_spells.append( CastAreaSpell( spell=spell, id=cast_spell_msg["id"], caster_id=cast_spell_msg["casterId"], cell=cell, remaining_turns=cast_spell_msg["remainingTurns"], affected_units=affected_units)) elif spell.is_unit_spell(): self.cast_spells.append( CastUnitSpell( spell=spell, id=cast_spell_msg["id"], caster_id=cast_spell_msg["casterId"], cell=cell, unit=self.get_unit_by_id(cast_spell_msg["unitId"]), path=self.map.get_path_by_id(cast_spell_msg["pathId"]), affected_units=affected_units)) def get_cast_spell_by_id(self, id): for cast_spell in self.cast_spells: if cast_spell.id == id: return cast_spell return None def _handle_turn_message(self, msg): self.current_turn = msg['currTurn'] self.player.deck = [ self._get_base_unit_by_id(deck_type_id) for deck_type_id in msg["deck"] ] self.player.hand = [ self._get_base_unit_by_id(hand_type_id) for hand_type_id in msg["hand"] ] self._handle_turn_kings(msg["kings"]) self._handle_turn_units(msg["units"]) self._handle_turn_units(msg=msg["diedUnits"], is_dead_unit=True) self._handle_turn_cast_spells(msg["castSpells"]) self.turn_updates = TurnUpdates( received_spell=msg["receivedSpell"], friend_received_spell=msg["friendReceivedSpell"], got_range_upgrade=msg["gotRangeUpgrade"], got_damage_upgrade=msg["gotDamageUpgrade"], available_range_upgrades=msg["availableRangeUpgrades"], available_damage_upgrades=msg["availableDamageUpgrades"]) self.player.set_spells( [self.get_spell_by_id(spell_id) for spell_id in msg["mySpells"]]) self.player_friend.set_spells([ self.get_spell_by_id(spell_id) for spell_id in msg["friendSpells"] ]) self.player.ap = msg["remainingAP"] self.start_time = self.get_current_time_millis() # in the first turn 'deck picking' give unit_ids or list of unit names to pick in that turn def choose_deck(self, type_ids=None, base_units=None): message = Message(type="pick", turn=self.get_current_turn(), info=None) if type_ids is not None: message.info = {"units": type_ids} elif base_units is not None: message.info = {"units": [unit.type_id for unit in base_units]} self.queue.put(message) def get_me(self): return self.player def get_friend(self): return self.player_friend def get_friend_by_id(self, player_id): if self.player.player_id == player_id: return self.player_friend elif self.player_friend.player_id == player_id: return self.player elif self.player_first_enemy.player_id == player_id: return self.player_second_enemy elif self.player_second_enemy.player_id == player_id: return self.player_first_enemy else: return None def get_first_enemy(self): return self.player_first_enemy def get_second_enemy(self): return self.player_second_enemy def get_map(self): return self.map # return a list of paths crossing one cell def get_paths_crossing_cell(self, cell=None, row=None, col=None): if cell is None: if row is None or col is None: return cell = self.map.get_cell(row, col) paths = [] for p in self.map.paths: if cell in p.cells: paths.append(p) return paths # return a list of units in a cell def get_cell_units(self, cell=None, row=None, col=None): if cell is None: if row is None and col is None: return None cell = self.map.get_cell(row, col) return cell.units # return the shortest path from player_id fortress to cell # this path is in the available path list # path may cross from friend def get_shortest_path_to_cell(self, from_player_id=None, from_player=None, cell=None, row=None, col=None): def path_count(paths): shortest_path = None count = 0 for p in paths: count_num = 0 for c in p.cells: if c == cell: if shortest_path is None: count = count_num shortest_path = p elif count_num < count: count = count_num shortest_path = p count_num += 1 return shortest_path if from_player is not None: from_player_id = from_player.player_id if cell is None: if row is None or col is None: return cell = self.map.get_cell(row, col) p = path_count(self.get_player_by_id(from_player_id).paths_from_player) if p is None: ls = [self.get_player_by_id(from_player_id).path_to_friend] ptf = path_count(ls) if ptf is None: pff = path_count( self.get_friend_by_id(from_player_id).paths_from_player) if pff is None: return None return pff return ptf return p # place unit with type_id in path_id def put_unit(self, type_id=None, path_id=None, base_unit=None, path=None): if base_unit is not None: type_id = base_unit.type_id if path is not None: path_id = path.id if path_id is None or type_id is None: return None message = Message(turn=self.get_current_turn(), type="putUnit", info={ "typeId": type_id, "pathId": path_id }) self.queue.put(message) # return the number of turns passed def get_current_turn(self): return self.current_turn # put unit_id in path_id in position 'index' all spells of one kind have the same id def cast_unit_spell(self, unit=None, unit_id=None, path=None, path_id=None, cell=None, row=None, col=None, spell=None, spell_id=None): if spell is None and spell_id is None: return None if spell is None: spell = self.get_spell_by_id(spell_id) if row is not None and col is not None: cell = Cell(row, col) if unit is not None: unit_id = unit.unit_id if path is not None: path_id = path.id message = Message(type="castSpell", turn=self.get_current_turn(), info={ "typeId": spell.type_id, "cell": { "row": cell.row, "col": cell.col }, "unitId": unit_id, "pathId": path_id }) self.queue.put(message) # cast spell in the cell 'center' def cast_area_spell(self, center=None, row=None, col=None, spell=None, spell_id=None): if spell is None: spell = self.get_spell_by_id(spell_id) if row is not None and col is not None: center = self.map.get_cell(row, col) if center is not None: message = Message(type="castSpell", turn=self.get_current_turn(), info={ "typeId": spell.type_id, "cell": { "row": center.row, "col": center.col }, "unitId": -1, "pathId": -1 }) self.queue.put(message) # returns a list of units the spell casts effects on # NOT CORRECT!!! # def get_area_spell_targets(self, center, row=None, col=None, spell=None, type_id=None): if spell is None: if type_id is not None: spell = self.get_cast_spell_by_id(type_id) else: return [] if not spell.is_area_spell(): return [] if center is None: center = Cell(row, col) ls = [] for i in range(max(0, center.row - spell.range), min(center.row + spell.range, self.map.row_num)): for j in range(max(0, center.col - spell.range), min(center.col + spell.range, self.map.column_num)): cell = self.map.get_cell(i, j) for u in cell.units: if self._is_unit_targeted(u, spell.target): ls.append(u) def _is_unit_targeted(self, unit, spell_target): if spell_target == 1: if unit in self.player.units: return True elif spell_target == 2: if unit in self.player_friend or unit in self.player.units: return True elif spell_target == 3: if unit in self.player_first_enemy or unit in self.player_second_enemy: return True return False # every once in a while you can upgrade, this returns the remaining time for upgrade def get_remaining_turns_to_upgrade(self): rem_turn = (self.game_constants.turns_to_upgrade - self.current_turn) % self.game_constants.turns_to_upgrade if rem_turn == 0: return self.game_constants.turns_to_upgrade return rem_turn # every once in a while a spell is given this remains the remaining time to get new spell def get_remaining_turns_to_get_spell(self): rem_turn = (self.game_constants.turns_to_spell - self.current_turn) % self.game_constants.turns_to_spell if rem_turn == 0: return self.game_constants.turns_to_spell return rem_turn # returns a list of spells casted on a cell def get_range_upgrade_number(self): return self.turn_updates.available_range_upgrade def get_damage_upgrade_number(self): return self.turn_updates.available_damage_upgrade # returns the spell given in that turn def get_received_spell(self): spell_id = self.turn_updates.received_spell spell = self.get_spell_by_id(spell_id) return spell # returns the spell given in that turn to friend def get_friend_received_spell(self): spell_id = self.turn_updates.friend_received_spell spell = self.get_spell_by_id(spell_id) return spell def upgrade_unit_range(self, unit=None, unit_id=None): if unit is not None: unit_id = unit.unit_id if unit_id is not None: self.queue.put( Message(type="rangeUpgrade", turn=self.get_current_turn(), info={"unitId": unit_id})) def upgrade_unit_damage(self, unit=None, unit_id=None): if unit is not None: unit_id = unit.unit_id if unit_id is not None: self.queue.put( Message(type="damageUpgrade", turn=self.get_current_turn(), info={"unitId": unit_id})) def get_player_hasted_units(self, player_id): return [ unit for unit in self.get_player_by_id(player_id=player_id).units if unit.is_hasted > 0 ] def get_player_played_units(self, player_id): return [ unit for unit in self.get_player_by_id(player_id=player_id).units if unit.was_played_this_turn ] def get_all_base_unit(self): return copy.deepcopy(self.base_units) def get_all_spells(self): return copy.deepcopy(self.spells) def get_king_by_id(self, player_id): for p in self.players: if p.player_id == player_id: return p.king return None def get_base_unit_by_id(self, type_id): for bu in self.base_units: if bu.type_id == type_id: return bu return None def get_game_constants(self): return self.game_constants def _get_paths_starting_with(self, first, paths): ret = [] for path in paths: c_path = Path(path=path) if c_path.cells[-1] == first: c_path.cells.reverse() if c_path.cells[0] == first: ret.append(c_path) return ret def _handle_end_message(self, scores_list_msg): return dict([(score["playerId"], score["score"]) for score in scores_list_msg])