genetic_alg #34
7
algorithms/genetic/common.py
Normal file
7
algorithms/genetic/common.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Position:
|
||||||
|
row: int
|
||||||
|
col: int
|
25
algorithms/genetic/const.py
Normal file
25
algorithms/genetic/const.py
Normal 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
|
71
algorithms/genetic/genome.py
Normal file
71
algorithms/genetic/genome.py
Normal 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
|
@ -1,102 +1,4 @@
|
|||||||
from dataclasses import dataclass
|
from genome import Genome
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user