def draw_state(self): self.window.fill(BACKGROUND) for x in xrange(self.flatland.w): x1 = x * CELL_SIZE - 1 pygame.draw.line(self.window, FOREGROUND, (x1, 0), (x1, self.window_h), 2) for y in xrange(self.flatland.h): y1 = y * CELL_SIZE - 1 pygame.draw.line(self.window, FOREGROUND, (0, y1), (self.window_w, y1), 2) for y, row in enumerate(self.flatland.grid): for x, cell in enumerate(row): if (x, y) == self.flatland.agent_position: self.draw_circle_in_cell(x, y, (0, 0, 125), radius=CELL_SIZE // 4) offset = CELL_SIZE // 2 coord = x * CELL_SIZE + offset, y * CELL_SIZE + offset coord = tuple_add(coord, map(lambda x: 20 * x, DELTAS[self.flatland.agent_heading])) pygame.draw.circle(self.window, (255, 255, 0), coord, CELL_SIZE // 10) elif cell == FOOD: self.draw_circle_in_cell(x, y, FOOD_COLOR) elif cell == POISON: self.draw_circle_in_cell(x, y, POISON_COLOR) pygame.display.flip()
def walk(self, tmap, d=None): if not d: d = self.direction_with_smoothing_fuzz() d = round(d) % 4 npos = utils.tuple_add(self.pos, ([1, 0, -1, 0][d], [0, 1, 0, -1][d])) if tmap.on_map_bordered(npos): self.pos = npos return self
def box_dimensions(self): # Get min values for each axis if self.num_blocks() == 0: return (0, 0, 0) minx = min(block.posx for block in self.blocks) miny = min(block.posy for block in self.blocks) minz = min(block.posz for block in self.blocks) mins = (minx, miny, minz) # Get max values for each axis maxx = max(block.posx for block in self.blocks) maxy = max(block.posy for block in self.blocks) maxz = max(block.posz for block in self.blocks) maxs = (maxx, maxy, maxz) dif = tuple_sub(maxs, mins) return tuple_add(dif, (1, 1, 1))
def move_randomly(self): ''' moves one delta in the random direction (not going into walls) ''' if not self.dungeon_map.in_bounds(self.position): ValueError( 'enemie\'s position is out of bounds of argument DungeonMap') while True: rand_move_dt = move_directions[randrange(len(move_directions))] new_pos = tuple_add(self.position, rand_move_dt) if self.dungeon_map.in_bounds(new_pos): self.position = new_pos dlog.debug(f'enemy moved to {self.position}') break
def add_node(self, char, nodes): new_pos = utils.tuple_add(self.pos, directionToOffset[char]) if new_pos in nodes: new_node = nodes[new_pos] else: new_node = Node(new_pos) if char == "N": self.north = new_node new_node.south = self elif char == "E": self.east = new_node new_node.west = self elif char == "S": self.south = new_node new_node.north = self elif char == "W": self.west = new_node new_node.east = self new_node.add_to(nodes) return new_node
def down_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[SOUTH]))
def right_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[EAST]))
def left_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[WEST]))
def up_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[NORTH]))
def move(self, event, GS): if self.poisoned > 0 and GS['turns'] % 2: self.poisoned -= 1 self.health -= 1 for item in self.dequips: item.lasts -= 1 if item.lasts <= 0: item.dequip(self) GS['messages'].append('yellow: Your ' + item.name + ' flickers out.') self.dequips.remove(item) if self.health < self.max_health and GS['turns'] % 3 == 0: self.health += 1 if GS['turns'] % 4 == 0: self.hunger += 1 if self.hunger > 20 and GS['turns'] % 3 == 0: descriptor = 'hungry' if self.hunger > 40: descriptor = 'Ravinous' elif self.hunger > 60: descriptor = 'Starving' GS['messages'].append('red: You feel ' + descriptor + '.') self.health -= int(self.hunger / 20) elif self.hunger >= 80: self.health = 0 delta = consts.GAME_KEYS['M'][event.keychar] new_pos = utils.tuple_add(self.pos, delta) n_x, n_y = new_pos if new_pos == GS['terrain_map'].dungeon['down_stairs'] and\ GS['terrain_map'].is_dungeons(): GS['messages'].append("light_blue: You decend.") self.pos = GS['terrain_map'].generate_new_map() if new_pos == GS['terrain_map'].dungeon['up_stairs'] and\ len(GS['terrain_map'].dungeons) > 1: if GS['terrain_map'].restore_dungeon( GS['terrain_map'].dungeon_level - 1): GS['messages'].append("light_blue: You ascend.") self.pos = GS['terrain_map'].dungeon['player_starting_pos'] if new_pos in GS['terrain_map'].dungeon['doors'] and\ not GS['terrain_map'].is_walkable(new_pos): GS['terrain_map'].dungeon['doors'][new_pos] = False GS['terrain_map'].dungeon['lighted'].walkable[new_pos] = True GS['terrain_map'].dungeon['lighted'].transparent[new_pos] = True new_pos = self.pos n_x, n_y = new_pos w, h = GS['terrain_map'].width, GS['terrain_map'].height self.frozen -= 1 if GS['terrain_map'].is_walkable(new_pos) and self.frozen <= 0: self.prev_pos = self.pos self.pos = new_pos di = GS['terrain_map'].dungeon['items'] if self.pos in di: i = di[self.pos] for e in i: GS['messages'].append("You find a " + e.name + ".") if isinstance(e, items.Light) or isinstance(e, items.Food)\ or isinstance(e, items.Missle): if self.add_inventory_item(e): GS['messages'].append("You pick up a " + e.name + ".") else: GS['messages'].append("Your inventory is full.") for k, v in GS['terrain_map'].dungeon['items'].items(): if e in v: GS['terrain_map'].dungeon['items'][k].remove(e) break if new_pos in GS['terrain_map'].dungeon['water']: GS['messages'].append( "blue: You slosh through the cold water.") else: if GS['terrain_map'].in_area(new_pos) == 'Cave': GS['terrain_map'].place_cell(new_pos) self.pos = new_pos elif self.frozen > 0: GS['messages'].append('You are frozen for ' + str(self.frozen) + ' more turns.') else: new_pos = self.pos n_x, n_y = new_pos m = GS['terrain_map'].monster_at(new_pos) speed = self.speed if utils.adjacent(self.prev_pos, new_pos) and self.light() and m: GS['messages'].append("green: You gallantly charge the monster!") self.speed = 0 if m != None: (self_dead, monster_dead) = self.attack_monster(GS, m) GS['messages'].append("green: You attack the " + m.name) if not monster_dead: GS['messages'].append("red: The " + m.name + " attacks you") GS['messages'].append("red: It's health is now " + str(m.health)) else: GS['messages'].append("green: You vanquish the " + m.name) GS['terrain_map'].dungeon['monsters'].remove(m) if m.pos in GS['terrain_map'].dungeon['items']: GS['terrain_map'].dungeon['items'][m.pos].append( random.choice(m.drops)) else: GS['terrain_map'].dungeon['items'][m.pos] = [ random.choice(m.drops) ] self.speed = speed decor = GS['terrain_map'].dungeon['decor'] if new_pos in decor: if decor[new_pos] == 'FR' or decor[new_pos] == 'FL': decor[new_pos] = None player.health -= 1 GS['messages'].append('The fire burns you.') elif decor[new_pos] == 'TTRAP': self.pos = random.choice( GS['terrain_map'].dungeon['rooms']).center GS['messages'].append('red: You stumble apon a teleport trap.') decor[new_pos] = 'TTRAPD' elif decor[new_pos] == 'DTRAP': if GS['terrain_map'].is_dungeons(): GS['messages'].append("light_blue: You decend.") self.pos = GS['terrain_map'].generate_new_map() GS['messages'].append('red: You fall down a trap door.') decor[new_pos] = 'DTRAPD' elif decor[new_pos] == 'ITRAP': GS['messages'].append( 'light_blue: Ice creeps up your legs. You are frozen!') self.pos = self.prev_pos self.frozen = 4 decor[new_pos] = 'ITRAPD'
def right_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[self.left_direction]))
def forward_coordinate(self): return self.absolute_coordinates( *tuple_add(self.agent_position, DELTAS[self.agent_heading]))
def right_coordinate(self): return self.absolute_coordinates(*tuple_add(self.agent_position, DELTAS[self.left_direction]))
def forward_coordinate(self): return self.absolute_coordinates(*tuple_add(self.agent_position, DELTAS[self.agent_heading]))
def move(self, GS): self.player_spotted = False if GS['turns'] % 20 == 0: GS['terrain_map'].dungeon['monsters_alerted'] = False sight = self.sight if GS['player'].light(): self.sight = 3 if utils.dist(GS['player'].pos, self.pos) == 1: self.player_spotted = False GS['messages'].append('red: The ' + self.name + ' attacks you.') (player_dead, monster_dead) = GS['player'].attack_monster(GS, self) if monster_dead: GS['messages'].append('yellow: You destroy the ' + self.name) GS['terrain_map'].dungeon['monsters'].remove(self) if self.pos in GS['terrain_map'].dungeon['items']: GS['terrain_map'].dungeon['items'][self.pos].append( random.choice(self.drops)) elif utils.LOS(GS['terrain_map'], self.pos, GS['player'].pos, self.sight)\ or GS['terrain_map'].dungeon['monsters_alerted']: self.player_spotted = True if self.ranged: p = GS['player'] m = self ox = max(0, GS['player'].pos[0] - math.floor(WIDTH / 4)) oy = max(0, GS['player'].pos[1] - math.floor(HEIGHT / 2)) start = (m.pos[0] - ox, m.pos[1] - oy) end = (p.pos[0] - ox, p.pos[1] - oy) animation.FireMissleAnimation().run( GS, [items.WOOD_ARROW, start, end]) p.health -= self.speed elif self.agressive: print('aggress') if len(self.path) == 0 or self.path[-1] != GS['player'].pos: # Reset the path (A* algorithm) self.path = GS['terrain_map'].dungeon[ 'visited'].compute_path(self.pos[0], self.pos[1], GS['player'].pos[0], GS['player'].pos[1], diagonal_cost=0) self.path.reverse() if len(self.path) > 0: npos = self.path.pop() if npos in GS['terrain_map'].dungeon['doors']: GS['terrain_map'].dungeon['doors'] = False GS['terrain_map'].dungeon['lighted'].transparent[ npos] = True GS['terrain_map'].dungeon['lighted'].walkable[ npos] = True if GS['terrain_map'].is_walkable(npos): self.pos = npos else: npos = utils.tuple_add( self.pos, (random.randint(-1, 1), random.randint(-1, 1))) if GS['terrain_map'].is_walkable(npos): self.pos = npos else: npos = utils.tuple_add( self.pos, (random.randint(-1, 1), random.randint(-1, 1))) if GS['terrain_map'].is_walkable(npos): self.pos = npos self.sight = sight