genetic_alg #34

Merged
s464965 merged 18 commits from genetic_alg into master 2022-06-06 15:19:58 +02:00
4 changed files with 104 additions and 99 deletions
Showing only changes of commit c7c1feb82c - Show all commits

View File

@ -0,0 +1,7 @@
from dataclasses import dataclass
@dataclass
class Position:
row: int
col: int

View File

@ -0,0 +1,25 @@
# map config
KNIGHTS_PER_TEAM_COUNT = 4
SAND_COUNT = 21
WATER_COUNT = 21
TREE_COUNT = 37
MONSTERS_COUNT = 2
CASTLES_COUNT = 1
ROWS = 19
COLUMNS = 24
KNIGHTS_SPAWN_WIDTH = 4
KNIGHTS_SPAWN_HEIGHT = 7
LEFT_KNIGHTS_SPAWN_FIRST_ROW = 6
LEFT_KNIGHTS_SPAWN_FIRST_COL = 0
RIGHT_KNIGHTS_SPAWN_FIRST_ROW = 6
RIGHT_KNIGHTS_SPAWN_FIRST_COL = 20
# aliases
GRASS = 0
SAND = 1
WATER = 2
TREE = 3
MONSTER = 4
CASTLE = 5
KNIGHT_RED = 6
KNIGHT_BLUE = 7

View File

@ -0,0 +1,71 @@
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]
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=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=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
)
def is_empty(grid: npt.NDArray, position: Position) -> bool:
return grid[position.row, position.col] in [GRASS, 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: KNIGHT_RED | KNIGHT_BLUE | CASTLE | MONSTER,
objects_count: int = 1,
spawn_position_start: Position = Position(row=0, col=0),
width: int = 1,
height: int = 1) -> 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

View File

@ -1,102 +1,4 @@
from dataclasses import dataclass
from random import randrange
from typing import List
import numpy as np
import numpy.typing as npt
# map config
KNIGHTS_PER_TEAM_COUNT = 4
SAND_COUNT = 21
WATER_COUNT = 21
TREE_COUNT = 37
MONSTERS_COUNT = 2
CASTLES_COUNT = 1
ROWS = 19
COLUMNS = 24
KNIGHTS_SPAWN_WIDTH = 4
KNIGHTS_SPAWN_HEIGHT = 7
LEFT_KNIGHTS_SPAWN_FIRST_ROW = 6
LEFT_KNIGHTS_SPAWN_FIRST_COL = 0
RIGHT_KNIGHTS_SPAWN_FIRST_ROW = 6
RIGHT_KNIGHTS_SPAWN_FIRST_COL = 20
# aliases
GRASS = 0
SAND = 1
WATER = 2
TREE = 3
MONSTER = 4
CASTLE = 5
KNIGHT_RED = 6
KNIGHT_BLUE = 7
@dataclass
class Position:
row: int
col: int
class Genome:
grid: npt.NDArray
knights_red: List[Position]
knights_blue: List[Position]
def __init__(self):
self.grid = np.zeros((ROWS, COLUMNS), dtype=int)
self.knights_red = spawn_objects_in_given_area(
grid=self.grid,
object_alias=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=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
)
def is_empty(grid: npt.NDArray, position: Position) -> bool:
return grid[position.row, position.col] in [GRASS, 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: KNIGHT_RED | KNIGHT_BLUE | CASTLE | MONSTER,
objects_count: int = 1,
spawn_position_start: Position = Position(row=0, col=0),
width: int = 1,
height: int = 1) -> 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
from genome import Genome
def main() -> None: