2022-04-30 23:29:52 -07:00
|
|
|
# Eryn Wells <eryn@erynwells.me>
|
|
|
|
|
2022-05-01 18:03:47 -07:00
|
|
|
import random
|
2022-05-07 11:22:54 -07:00
|
|
|
|
|
|
|
import numpy as np
|
2023-02-09 20:54:40 -08:00
|
|
|
import numpy.typing as npt
|
2022-04-30 23:29:52 -07:00
|
|
|
import tcod
|
2022-05-07 11:22:54 -07:00
|
|
|
|
2023-02-09 16:07:29 -08:00
|
|
|
from ..geometry import Point, Size
|
|
|
|
from .generator import MapGenerator
|
|
|
|
from .tile import Empty, Shroud
|
2022-04-30 23:29:52 -07:00
|
|
|
|
2023-02-08 08:36:00 -08:00
|
|
|
|
2022-04-30 23:29:52 -07:00
|
|
|
class Map:
|
2023-02-09 16:07:29 -08:00
|
|
|
def __init__(self, size: Size, generator: MapGenerator):
|
2022-04-30 23:29:52 -07:00
|
|
|
self.size = size
|
|
|
|
|
2023-02-09 16:07:29 -08:00
|
|
|
self.generator = generator
|
|
|
|
self.tiles = np.full(tuple(size), fill_value=Empty, order='F')
|
2023-02-10 21:06:34 -08:00
|
|
|
generator.generate(self.tiles)
|
|
|
|
|
|
|
|
self.up_stairs = generator.up_stairs
|
|
|
|
self.down_stairs = generator.down_stairs
|
2022-04-30 23:29:52 -07:00
|
|
|
|
2022-05-04 09:22:40 -07:00
|
|
|
# Map tiles that are currently visible to the player
|
2023-02-08 08:36:00 -08:00
|
|
|
self.visible = np.full(tuple(self.size), fill_value=True, order='F')
|
2022-05-04 09:22:40 -07:00
|
|
|
# Map tiles that the player has explored
|
2023-02-08 08:36:00 -08:00
|
|
|
self.explored = np.full(tuple(self.size), fill_value=True, order='F')
|
2022-05-04 09:22:40 -07:00
|
|
|
|
2023-02-09 16:07:29 -08:00
|
|
|
self.__walkable_points = None
|
2022-05-06 21:14:42 -07:00
|
|
|
|
2022-05-03 19:00:45 -07:00
|
|
|
def random_walkable_position(self) -> Point:
|
2023-02-09 16:07:29 -08:00
|
|
|
'''Return a random walkable point on the map.'''
|
|
|
|
if not self.__walkable_points:
|
|
|
|
self.__walkable_points = [Point(x, y) for x, y in np.ndindex(
|
|
|
|
self.tiles.shape) if self.tiles[x, y]['walkable']]
|
|
|
|
return random.choice(self.__walkable_points)
|
2022-05-03 19:00:45 -07:00
|
|
|
|
2022-05-01 00:09:12 -07:00
|
|
|
def tile_is_in_bounds(self, point: Point) -> bool:
|
2022-05-15 16:50:24 -07:00
|
|
|
'''Return True if the given point is inside the bounds of the map'''
|
2022-05-01 00:09:12 -07:00
|
|
|
return 0 <= point.x < self.size.width and 0 <= point.y < self.size.height
|
|
|
|
|
|
|
|
def tile_is_walkable(self, point: Point) -> bool:
|
2022-05-15 16:50:24 -07:00
|
|
|
'''Return True if the tile at the given point is walkable'''
|
2022-05-01 00:09:12 -07:00
|
|
|
return self.tiles[point.x, point.y]['walkable']
|
2022-04-30 23:29:52 -07:00
|
|
|
|
2022-05-01 10:46:30 -07:00
|
|
|
def print_to_console(self, console: tcod.Console) -> None:
|
2022-05-04 09:22:40 -07:00
|
|
|
'''Render the map to the console.'''
|
2022-05-01 10:46:30 -07:00
|
|
|
size = self.size
|
2022-05-04 09:22:40 -07:00
|
|
|
|
|
|
|
# If a tile is in the visible array, draw it with the "light" color. If it's not, but it's in the explored
|
|
|
|
# array, draw it with the "dark" color. Otherwise, draw it as Empty.
|
|
|
|
console.tiles_rgb[0:size.width, 0:size.height] = np.select(
|
|
|
|
condlist=[self.visible, self.explored],
|
|
|
|
choicelist=[self.tiles['light'], self.tiles['dark']],
|
|
|
|
default=Shroud)
|