95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
from random import randrange
|
|
from typing import List
|
|
|
|
import numpy as np
|
|
import numpy.typing as npt
|
|
|
|
from common import Position
|
|
from const import *
|
|
|
|
|
|
class Genome:
|
|
grid: npt.NDArray
|
|
knights_red: List[Position]
|
|
knights_blue: List[Position]
|
|
waters: List[Position]
|
|
trees: List[Position]
|
|
sands: List[Position]
|
|
monsters: List[Position]
|
|
|
|
def __init__(self):
|
|
self.grid = np.zeros((ROWS, COLUMNS), dtype=int)
|
|
|
|
# todo: spawning castle, monsters, sand, trees in the same way as bellow
|
|
self.knights_red = spawn_objects_in_given_area(
|
|
grid=self.grid,
|
|
object_alias=MAP_ALIASES.get("KNIGHT_RED"),
|
|
objects_count=KNIGHTS_PER_TEAM_COUNT,
|
|
spawn_position_start=Position(row=LEFT_KNIGHTS_SPAWN_FIRST_ROW, col=LEFT_KNIGHTS_SPAWN_FIRST_COL),
|
|
width=KNIGHTS_SPAWN_WIDTH,
|
|
height=KNIGHTS_SPAWN_HEIGHT
|
|
)
|
|
|
|
self.knights_blue = spawn_objects_in_given_area(
|
|
grid=self.grid,
|
|
object_alias=MAP_ALIASES.get("KNIGHT_BLUE"),
|
|
objects_count=KNIGHTS_PER_TEAM_COUNT,
|
|
spawn_position_start=Position(row=RIGHT_KNIGHTS_SPAWN_FIRST_ROW, col=RIGHT_KNIGHTS_SPAWN_FIRST_COL),
|
|
width=KNIGHTS_SPAWN_WIDTH,
|
|
height=KNIGHTS_SPAWN_HEIGHT
|
|
)
|
|
|
|
spawn_objects_in_given_area(
|
|
grid=self.grid,
|
|
object_alias=MAP_ALIASES.get("CASTLE"),
|
|
objects_count=4,
|
|
spawn_position_start=Position(row=7, col=9),
|
|
width=2,
|
|
height=2
|
|
)
|
|
|
|
self.waters = spawn_objects_in_given_area(grid=self.grid, object_alias=MAP_ALIASES.get("WATER"),
|
|
objects_count=WATER_COUNT)
|
|
self.trees = spawn_objects_in_given_area(grid=self.grid, object_alias=MAP_ALIASES.get("TREE"),
|
|
objects_count=TREE_COUNT)
|
|
self.sands = spawn_objects_in_given_area(grid=self.grid, object_alias=MAP_ALIASES.get("SAND"),
|
|
objects_count=SAND_COUNT)
|
|
self.monsters = spawn_objects_in_given_area(grid=self.grid, object_alias=MAP_ALIASES.get("MONSTER"),
|
|
objects_count=MONSTERS_COUNT)
|
|
|
|
|
|
def is_empty(grid: npt.NDArray, position: Position) -> bool:
|
|
return grid[position.row, position.col] in [MAP_ALIASES.get("GRASS"), MAP_ALIASES.get("SAND")]
|
|
|
|
|
|
def is_invalid_area(spawn_position_start, height, width) -> bool:
|
|
return spawn_position_start.row + height - 1 < 0 or \
|
|
spawn_position_start.row + height - 1 >= ROWS or \
|
|
spawn_position_start.col + width - 1 < 0 or \
|
|
spawn_position_start.col + width - 1 >= COLUMNS
|
|
|
|
|
|
def spawn_objects_in_given_area(grid: npt.NDArray,
|
|
object_alias: str,
|
|
objects_count: int = 1,
|
|
spawn_position_start: Position = Position(row=0, col=0),
|
|
width: int = COLUMNS,
|
|
height: int = ROWS) -> List[Position]:
|
|
if is_invalid_area(spawn_position_start, height, width):
|
|
raise ValueError("Invalid spawn area")
|
|
|
|
objects_remaining = int(objects_count)
|
|
positions = []
|
|
|
|
while objects_remaining > 0:
|
|
row = randrange(spawn_position_start.row, spawn_position_start.row + height)
|
|
col = randrange(spawn_position_start.col, spawn_position_start.col + width)
|
|
position = Position(row=row, col=col)
|
|
|
|
if is_empty(grid=grid, position=position):
|
|
grid[position.row, position.col] = object_alias
|
|
positions.append(position)
|
|
objects_remaining -= 1
|
|
|
|
return positions
|