From c06624d79c1e2951bf4b65eb4f265dbc2251522d Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Sun, 29 May 2022 23:13:45 +0200 Subject: [PATCH 01/14] example genome generation --- algorithms/genetic/map_generator.py | 107 ++++++++++++++++++++++++++++ requirements.txt | Bin 148 -> 216 bytes 2 files changed, 107 insertions(+) create mode 100644 algorithms/genetic/map_generator.py diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py new file mode 100644 index 0000000..2e917c7 --- /dev/null +++ b/algorithms/genetic/map_generator.py @@ -0,0 +1,107 @@ +from dataclasses import dataclass +from random import randrange + +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 + + +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) -> None: + if is_invalid_area(spawn_position_start, height, width): + raise ValueError("Invalid spawn area") + + if objects_count > 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) + objects_remaining = int(objects_count) + + if is_empty(grid=grid, position=position): + grid[position.row, position.col] = object_alias + objects_remaining -= 1 + + spawn_objects_in_given_area( + grid=grid, + object_alias=object_alias, + objects_count=objects_remaining, + spawn_position_start=spawn_position_start, + width=width, + height=height + ) + + +def genome() -> npt.NDArray: + grid = np.zeros((ROWS, COLUMNS), dtype=int) + spawn_objects_in_given_area( + grid=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 + ) + + spawn_objects_in_given_area( + grid=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 + ) + return grid + + +def main() -> None: + example_genome = genome() + print(example_genome) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt index 82236198bdcfb899947d2ff58bc2acc8136e458a..973091af59ddbb4f1c65c30352b79a189f087cbd 100644 GIT binary patch delta 75 zcmbQjc!P1m6c=6wE`~gYQifcH0)|S4ItE(?Lk2wtBOugcFlGSB<}xHQlmKOO81jL1 T4nrnG5?GxvP=zTF8!`X@F2@Z8 delta 6 Ncmcb?IE8V-6aWb#0+Rp$ From 7a9d685701574d71e5ea816b11a3a4743d673397 Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Mon, 30 May 2022 23:27:31 +0200 Subject: [PATCH 02/14] Genome class responsible for keeping grid and lists of positions --- algorithms/genetic/map_generator.py | 73 +++++++++++++++-------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 2e917c7..751096b 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from random import randrange +from typing import List import numpy as np import numpy.typing as npt @@ -37,6 +38,32 @@ class Position: 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] @@ -52,55 +79,31 @@ def spawn_objects_in_given_area(grid: npt.NDArray, object_alias: KNIGHT_RED | KN objects_count: int = 1, spawn_position_start: Position = Position(row=0, col=0), width: int = 1, - height: int = 1) -> None: + height: int = 1) -> List[Position]: if is_invalid_area(spawn_position_start, height, width): raise ValueError("Invalid spawn area") - if objects_count > 0: + 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) - objects_remaining = int(objects_count) if is_empty(grid=grid, position=position): grid[position.row, position.col] = object_alias + positions.append(position) objects_remaining -= 1 - spawn_objects_in_given_area( - grid=grid, - object_alias=object_alias, - objects_count=objects_remaining, - spawn_position_start=spawn_position_start, - width=width, - height=height - ) - - -def genome() -> npt.NDArray: - grid = np.zeros((ROWS, COLUMNS), dtype=int) - spawn_objects_in_given_area( - grid=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 - ) - - spawn_objects_in_given_area( - grid=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 - ) - return grid + return positions def main() -> None: - example_genome = genome() - print(example_genome) + example_genome = Genome() + print(example_genome.knights_red) + print(example_genome.knights_blue) + print(example_genome.grid) if __name__ == '__main__': From c7c1feb82c8473bd7d6f4898e2d2d6e5150c86a0 Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Mon, 30 May 2022 23:34:28 +0200 Subject: [PATCH 03/14] separated code --- algorithms/genetic/common.py | 7 ++ algorithms/genetic/const.py | 25 +++++++ algorithms/genetic/genome.py | 71 ++++++++++++++++++++ algorithms/genetic/map_generator.py | 100 +--------------------------- 4 files changed, 104 insertions(+), 99 deletions(-) create mode 100644 algorithms/genetic/common.py create mode 100644 algorithms/genetic/const.py create mode 100644 algorithms/genetic/genome.py diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py new file mode 100644 index 0000000..9a4ed11 --- /dev/null +++ b/algorithms/genetic/common.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + + +@dataclass +class Position: + row: int + col: int diff --git a/algorithms/genetic/const.py b/algorithms/genetic/const.py new file mode 100644 index 0000000..91398c7 --- /dev/null +++ b/algorithms/genetic/const.py @@ -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 diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py new file mode 100644 index 0000000..81ee497 --- /dev/null +++ b/algorithms/genetic/genome.py @@ -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 diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 751096b..0165783 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -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: From e9ef300dde21cefc9160a046ae101e79d0e11539 Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Tue, 31 May 2022 01:03:00 +0200 Subject: [PATCH 04/14] import and export map; --- algorithms/a_star.py | 3 +- algorithms/genetic/const.py | 20 +++++----- algorithms/genetic/genome.py | 37 ++++++++++++++++-- algorithms/genetic/map_generator.py | 2 + algorithms/genetic/map_importer_exporter.py | 40 +++++++++++++++++++ common/constants.py | 2 +- common/helpers.py | 6 ++- logic/level.py | 43 +++++++-------------- resources/maps/map_2022_05_31_00_41_36.json | 1 + resources/maps/map_2022_05_31_00_41_47.json | 1 + resources/maps/map_2022_05_31_00_41_51.json | 1 + 11 files changed, 110 insertions(+), 46 deletions(-) create mode 100644 algorithms/genetic/map_importer_exporter.py create mode 100644 resources/maps/map_2022_05_31_00_41_36.json create mode 100644 resources/maps/map_2022_05_31_00_41_47.json create mode 100644 resources/maps/map_2022_05_31_00_41_51.json diff --git a/algorithms/a_star.py b/algorithms/a_star.py index d615ad9..5e95098 100644 --- a/algorithms/a_star.py +++ b/algorithms/a_star.py @@ -4,10 +4,11 @@ import heapq from dataclasses import dataclass, field from typing import Tuple, Optional, List +from algorithms.genetic.const import MAP_ALIASES from common.constants import ROWS, COLUMNS, LEFT, RIGHT, UP, DOWN from common.helpers import directions -EMPTY_FIELDS = ['s', 'g', ' '] +EMPTY_FIELDS = [MAP_ALIASES.get("SAND"), MAP_ALIASES.get("GRASS"), ' '] TURN_LEFT = 'TURN_LEFT' TURN_RIGHT = 'TURN_RIGHT' diff --git a/algorithms/genetic/const.py b/algorithms/genetic/const.py index 91398c7..ac7d37a 100644 --- a/algorithms/genetic/const.py +++ b/algorithms/genetic/const.py @@ -14,12 +14,14 @@ 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 +# map aliases +MAP_ALIASES = { + "GRASS": 0, + "SAND": 1, + "WATER": 2, + "TREE": 3, + "MONSTER": 4, + "CASTLE": 5, + "KNIGHT_RED": 6, + "KNIGHT_BLUE": 7, +} diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index 81ee497..41c94ea 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -1,3 +1,4 @@ +import string from random import randrange from typing import List @@ -19,7 +20,7 @@ class Genome: # 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, + 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, @@ -28,16 +29,30 @@ class Genome: self.knights_blue = spawn_objects_in_given_area( grid=self.grid, - object_alias=KNIGHT_BLUE, + 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 + ) + + spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("WATER"), objects_count=WATER_COUNT) + spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("TREE"), objects_count=TREE_COUNT) + spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("SAND"), objects_count=SAND_COUNT) + spawn_where_possible(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 [GRASS, SAND] + 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: @@ -47,7 +62,8 @@ def is_invalid_area(spawn_position_start, height, width) -> bool: spawn_position_start.col + width - 1 >= COLUMNS -def spawn_objects_in_given_area(grid: npt.NDArray, object_alias: KNIGHT_RED | KNIGHT_BLUE | CASTLE | MONSTER, +def spawn_objects_in_given_area(grid: npt.NDArray, + object_alias: MAP_ALIASES.get("KNIGHT_RED") | MAP_ALIASES.get("KNIGHT_BLUE") | MAP_ALIASES.get("CASTLE") | MAP_ALIASES.get("MONSTER"), objects_count: int = 1, spawn_position_start: Position = Position(row=0, col=0), width: int = 1, @@ -69,3 +85,16 @@ def spawn_objects_in_given_area(grid: npt.NDArray, object_alias: KNIGHT_RED | KN objects_remaining -= 1 return positions + + +# temporary function to spawn castle, monsters, sand, trees +def spawn_where_possible(grid: npt.NDArray, object_alias: string, objects_count: int = 1): + objects_remaining = int(objects_count) + while objects_remaining > 0: + row = randrange(0, ROWS - 1) + col = randrange(0, COLUMNS - 1) + position = Position(row=row, col=col) + + if is_empty(grid, position): + grid[position.row, position.col] = object_alias + objects_remaining -= 1 diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 0165783..8708e29 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -1,3 +1,4 @@ +from map_importer_exporter import export_map from genome import Genome @@ -6,6 +7,7 @@ def main() -> None: print(example_genome.knights_red) print(example_genome.knights_blue) print(example_genome.grid) + export_map(example_genome.grid) if __name__ == '__main__': diff --git a/algorithms/genetic/map_importer_exporter.py b/algorithms/genetic/map_importer_exporter.py new file mode 100644 index 0000000..9293f75 --- /dev/null +++ b/algorithms/genetic/map_importer_exporter.py @@ -0,0 +1,40 @@ +import json +import random +import string +from datetime import datetime + +import numpy +import numpy.typing as npt +from os import listdir +from os.path import isfile, join + + + +# Save map to file +def export_map(grid: npt.NDArray): + json_data = {"map": grid.tolist()} + + now = datetime.now() + file_name = "map_" + now.strftime("%Y_%m_%d_%H_%M_%S") + ".json" + + with open("resources/maps/" + file_name, "w") as write_file: + json.dump(json_data, write_file) + print("Saved map to file " + file_name) + + +def import_random_map() -> object: + path = "resources/maps" + files = [f for f in listdir(path) if isfile(join(path, f))] + random_map_name = random.choice(files) + return import_map(random_map_name) + + +# Read map from file +def import_map(file: string) -> object: + with open("resources/maps/" + file, "r") as read_file: + print("Reading map from file " + file) + decoded_json = json.load(read_file) + + decoded_grid = numpy.asarray(decoded_json["map"]) + print(decoded_grid) + return decoded_grid.tolist() diff --git a/common/constants.py b/common/constants.py index 29ffa0c..ca7f43d 100644 --- a/common/constants.py +++ b/common/constants.py @@ -6,7 +6,7 @@ GAME_TITLE = 'WMICraft' WINDOW_HEIGHT = 800 WINDOW_WIDTH = 1360 FPS_COUNT = 60 -TURN_INTERVAL = 300 +TURN_INTERVAL = 500 GRID_CELL_PADDING = 5 GRID_CELL_SIZE = 36 diff --git a/common/helpers.py b/common/helpers.py index 3b0aa8c..86dcae6 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -1,6 +1,8 @@ from typing import Tuple, List import pygame + +from algorithms.genetic.const import MAP_ALIASES from common.constants import GRID_CELL_PADDING, GRID_CELL_SIZE, COLUMNS, ROWS, CLASSES, CLASS_TO_ID import csv import os @@ -99,7 +101,7 @@ def castle_neighbors(map, castle_bottom_right_row, castle_bottom_right_col): return neighbors -def find_neighbours(grid: List[List[str]], col: int, row: int) -> List[Tuple[int, int]]: +def find_neighbours(grid: List[List[int]], col: int, row: int) -> List[Tuple[int, int]]: dr = [-1, 1, 0, 0] dc = [0, 0, -1, 1] @@ -111,7 +113,7 @@ def find_neighbours(grid: List[List[str]], col: int, row: int) -> List[Tuple[int if rr < 0 or cc < 0: continue if rr >= ROWS or cc >= COLUMNS: continue - if grid[rr][cc] not in ['g', 's', '.']: continue + if grid[rr][cc] not in [MAP_ALIASES.get("GRASS"), MAP_ALIASES.get("SAND"), '.']: continue neighbours.append((rr, cc)) return neighbours diff --git a/logic/level.py b/logic/level.py index 73dcd8e..0ea19a8 100644 --- a/logic/level.py +++ b/logic/level.py @@ -3,10 +3,11 @@ import random import pygame from algorithms.a_star import a_star, State, TURN_RIGHT, TURN_LEFT, FORWARD +from algorithms.genetic.const import MAP_ALIASES +from algorithms.genetic.map_importer_exporter import import_random_map from common.constants import * from learning.decision_tree import DecisionTree from logic.knights_queue import KnightsQueue -from logic.spawner import Spawner from models.castle import Castle from models.knight import Knight from models.monster import Monster @@ -21,7 +22,7 @@ class Level: # sprite group setup self.sprites = pygame.sprite.LayeredUpdates() - self.map = [['g' for _ in range(COLUMNS)] for y in range(ROWS)] + self.map = [] self.list_knights_blue = [] self.list_knights_red = [] @@ -31,27 +32,11 @@ class Level: self.knights_queue = None def create_map(self): - self.generate_map() + self.map = import_random_map() self.setup_base_tiles() self.setup_objects() self.knights_queue = KnightsQueue(self.list_knights_blue, self.list_knights_red) - def generate_map(self): - spawner = Spawner(self.map) - spawner.spawn_where_possible(['w' for _ in range(NBR_OF_WATER)]) - spawner.spawn_where_possible(['t' for _ in range(NBR_OF_TREES)]) - spawner.spawn_where_possible(['s' for _ in range(NBR_OF_SANDS)]) - - spawner.spawn_in_area(['k_b' for _ in range(4)], LEFT_KNIGHTS_SPAWN_FIRST_ROW, LEFT_KNIGHTS_SPAWN_FIRST_COL, - KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT) - spawner.spawn_in_area(['k_r' for _ in range(4)], RIGHT_KNIGHTS_SPAWN_FIRST_ROW, RIGHT_KNIGHTS_SPAWN_FIRST_COL, - KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT) - - spawner.spawn_in_area(['c'], CASTLE_SPAWN_FIRST_ROW, CASTLE_SPAWN_FIRST_COL, CASTLE_SPAWN_WIDTH, - CASTLE_SPAWN_HEIGHT, 2) - - spawner.spawn_where_possible(['m' for _ in range(NBR_OF_MONSTERS)]) - def setup_base_tiles(self): textures = [] for texture_path in TILES: @@ -63,15 +48,15 @@ class Level: for col_index, col in enumerate(row): # add base tiles, e.g. water, tree, grass - if col == "w": + if col == MAP_ALIASES.get('WATER'): texture_index = 5 texture_surface = textures[texture_index][1] Tile((col_index, row_index), texture_surface, self.sprites, 'w') - elif col == "t": + elif col == MAP_ALIASES.get('TREE'): texture_index = 6 texture_surface = textures[texture_index][1] Tile((col_index, row_index), texture_surface, self.sprites, 't') - elif col == "s": + elif col == MAP_ALIASES.get('SAND'): texture_index = 4 texture_surface = textures[texture_index][1] Tile((col_index, row_index), texture_surface, self.sprites) @@ -88,19 +73,19 @@ class Level: for col_index, col in enumerate(row): # add objects, e.g. knights, monsters, castle - if col == "k_b": + if col == MAP_ALIASES.get('KNIGHT_BLUE'): knight = Knight(self.screen, (col_index, row_index), self.sprites, "blue") self.map[row_index][col_index] = knight self.list_knights_blue.append(knight) - elif col == "k_r": + elif col == MAP_ALIASES.get('KNIGHT_RED'): knight = Knight(self.screen, (col_index, row_index), self.sprites, "red") self.map[row_index][col_index] = knight self.list_knights_red.append(knight) - elif col == "m": + elif col == MAP_ALIASES.get('MONSTER'): monster = Monster(self.screen, (col_index, row_index), self.sprites) self.map[row_index][col_index] = monster self.list_monsters.append(monster) - elif col == "c": + elif col == MAP_ALIASES.get('CASTLE'): castle_count += 1 if castle_count == 4: castle = Castle(self.screen, (col_index, row_index), self.sprites) @@ -108,15 +93,15 @@ class Level: self.list_castles.append(castle) def handle_turn(self): - print("next turn") current_knight = self.knights_queue.dequeue_knight() + print("next turn " + current_knight.team) knight_pos_x = current_knight.position[0] knight_pos_y = current_knight.position[1] goal_list = self.decision_tree.predict_move(grid=self.map, current_knight=current_knight, monsters=self.list_monsters, opponents=self.list_knights_red - if current_knight.team_alias == 'k_r' else self.list_knights_blue, + if current_knight.team_alias() == 'k_r' else self.list_knights_blue, castle=self.list_castles[0]) if len(goal_list) == 0: @@ -139,7 +124,7 @@ class Level: current_knight.rotate_right() elif next_action == FORWARD: current_knight.step_forward() - self.map[knight_pos_y][knight_pos_x] = 'g' + self.map[knight_pos_y][knight_pos_x] = MAP_ALIASES.get("GRASS") # update knight on map if current_knight.direction.name == UP: diff --git a/resources/maps/map_2022_05_31_00_41_36.json b/resources/maps/map_2022_05_31_00_41_36.json new file mode 100644 index 0000000..9e72315 --- /dev/null +++ b/resources/maps/map_2022_05_31_00_41_36.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 4, 2, 3, 0, 0, 3, 3, 0, 3, 4, 0, 0], [0, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 1, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 3, 5, 5, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 7, 0, 0], [2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], [6, 6, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 2, 2, 0, 2, 0, 3, 0, 0, 7, 0], [0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0], [1, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0], [0, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_05_31_00_41_47.json b/resources/maps/map_2022_05_31_00_41_47.json new file mode 100644 index 0000000..f9c80cd --- /dev/null +++ b/resources/maps/map_2022_05_31_00_41_47.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 3, 0, 0, 3, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 2, 1, 2, 3, 0, 3, 0, 0, 0, 0], [3, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0], [0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 3, 0, 0, 7, 7], [0, 0, 3, 2, 0, 0, 0, 0, 0, 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 1, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0], [0, 0, 6, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 3, 0, 7, 0], [0, 6, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 1, 0, 0, 0], [0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 3, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 3, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_05_31_00_41_51.json b/resources/maps/map_2022_05_31_00_41_51.json new file mode 100644 index 0000000..879f5fd --- /dev/null +++ b/resources/maps/map_2022_05_31_00_41_51.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0], [2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0], [0, 1, 0, 0, 3, 0, 0, 1, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], [6, 0, 0, 0, 1, 2, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 5, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 7, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0], [6, 2, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 7, 0, 7], [0, 3, 6, 2, 0, 3, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 3, 3, 0, 0, 0, 4, 0, 0, 0, 3, 1, 0, 0, 0], [0, 3, 2, 3, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file From e89f564dd66cf6bf4121d5181df5ed0d795e70ba Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Tue, 31 May 2022 15:50:42 +0200 Subject: [PATCH 05/14] saving sands, trees, monsters etc positions --- algorithms/genetic/genome.py | 36 ++++++++++++----------------- algorithms/genetic/map_generator.py | 2 +- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index 41c94ea..f060352 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -1,4 +1,3 @@ -import string from random import randrange from typing import List @@ -13,6 +12,10 @@ 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) @@ -45,10 +48,14 @@ class Genome: height=2 ) - spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("WATER"), objects_count=WATER_COUNT) - spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("TREE"), objects_count=TREE_COUNT) - spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("SAND"), objects_count=SAND_COUNT) - spawn_where_possible(grid=self.grid, object_alias=MAP_ALIASES.get("MONSTER"), objects_count=MONSTERS_COUNT) + 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: @@ -63,11 +70,11 @@ def is_invalid_area(spawn_position_start, height, width) -> bool: def spawn_objects_in_given_area(grid: npt.NDArray, - object_alias: MAP_ALIASES.get("KNIGHT_RED") | MAP_ALIASES.get("KNIGHT_BLUE") | MAP_ALIASES.get("CASTLE") | MAP_ALIASES.get("MONSTER"), + object_alias: str, objects_count: int = 1, spawn_position_start: Position = Position(row=0, col=0), - width: int = 1, - height: int = 1) -> List[Position]: + width: int = COLUMNS, + height: int = ROWS) -> List[Position]: if is_invalid_area(spawn_position_start, height, width): raise ValueError("Invalid spawn area") @@ -85,16 +92,3 @@ def spawn_objects_in_given_area(grid: npt.NDArray, objects_remaining -= 1 return positions - - -# temporary function to spawn castle, monsters, sand, trees -def spawn_where_possible(grid: npt.NDArray, object_alias: string, objects_count: int = 1): - objects_remaining = int(objects_count) - while objects_remaining > 0: - row = randrange(0, ROWS - 1) - col = randrange(0, COLUMNS - 1) - position = Position(row=row, col=col) - - if is_empty(grid, position): - grid[position.row, position.col] = object_alias - objects_remaining -= 1 diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 8708e29..3148352 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -7,7 +7,7 @@ def main() -> None: print(example_genome.knights_red) print(example_genome.knights_blue) print(example_genome.grid) - export_map(example_genome.grid) + # export_map(example_genome.grid) fixme: FileNotFoundError if __name__ == '__main__': From f1f2302acdfb4150c425269a5a4a48920c2be642 Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Tue, 31 May 2022 21:34:31 +0200 Subject: [PATCH 06/14] counting islands with dfs --- algorithms/genetic/common.py | 44 +++++++++++++++++++++++++++++ algorithms/genetic/map_generator.py | 2 ++ 2 files changed, 46 insertions(+) diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py index 9a4ed11..3f79021 100644 --- a/algorithms/genetic/common.py +++ b/algorithms/genetic/common.py @@ -1,7 +1,51 @@ from dataclasses import dataclass +from const import * +from typing import List, Dict, Tuple + +import numpy.typing as npt @dataclass class Position: row: int col: int + + +def dfs(grid: npt.NDArray, visited: Dict[Tuple[int, int], bool], position: Position, rows: int, cols: int) -> None: + visited[(position.row, position.col)] = True + + row_vector = [0, 0, 1, -1] + col_vector = [-1, 1, 0, 0] + + neighbours = [] + for i in range(4): + rr = position.row + row_vector[i] + cc = position.col + col_vector[i] + if rr < 0 or rr >= ROWS: + continue + elif cc < 0 or cc >= COLUMNS: + continue + else: + p = Position(rr, cc) + if (p.row, p.col) in visited: + neighbours.append(p) + + for neighbour in neighbours: + if not visited[(neighbour.row, neighbour.col)]: + dfs(grid, visited, neighbour, rows, cols) + + +def count_islands(grid: npt.NDArray, positions: List[Position], rows: int = ROWS, cols: int = COLUMNS) -> int: + visited = {} + + for position in positions: + visited[(position.row, position.col)] = False + + islands = 0 + + for position in positions: + if not visited[(position.row, position.col)]: + dfs(grid, visited, position, rows, cols) + islands += 1 + + return islands diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 3148352..060ebff 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -1,5 +1,6 @@ from map_importer_exporter import export_map from genome import Genome +from common import count_islands def main() -> None: @@ -7,6 +8,7 @@ def main() -> None: print(example_genome.knights_red) print(example_genome.knights_blue) print(example_genome.grid) + print(count_islands(example_genome.grid, example_genome.sands + example_genome.waters)) # export_map(example_genome.grid) fixme: FileNotFoundError From ea105ad1404202d9fa532000a488abce74cf941c Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Tue, 31 May 2022 22:13:16 +0200 Subject: [PATCH 07/14] fixed return type --- algorithms/genetic/common.py | 8 +++++--- algorithms/genetic/map_generator.py | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py index 3f79021..e3f4cc5 100644 --- a/algorithms/genetic/common.py +++ b/algorithms/genetic/common.py @@ -35,17 +35,19 @@ def dfs(grid: npt.NDArray, visited: Dict[Tuple[int, int], bool], position: Posit dfs(grid, visited, neighbour, rows, cols) -def count_islands(grid: npt.NDArray, positions: List[Position], rows: int = ROWS, cols: int = COLUMNS) -> int: +def get_islands(grid: npt.NDArray, positions: List[Position], rows: int = ROWS, cols: int = COLUMNS) -> List[Position]: + """it returns list of all islands roots""" visited = {} for position in positions: visited[(position.row, position.col)] = False islands = 0 - + roots = [] for position in positions: if not visited[(position.row, position.col)]: dfs(grid, visited, position, rows, cols) + roots.append(position) islands += 1 - return islands + return roots diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 060ebff..e90488f 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -1,6 +1,6 @@ from map_importer_exporter import export_map from genome import Genome -from common import count_islands +from common import get_islands def main() -> None: @@ -8,7 +8,8 @@ def main() -> None: print(example_genome.knights_red) print(example_genome.knights_blue) print(example_genome.grid) - print(count_islands(example_genome.grid, example_genome.sands + example_genome.waters)) + islands = get_islands(example_genome.grid, example_genome.knights_red) + print(f'Roots {islands} and islands count {len(islands)}') # export_map(example_genome.grid) fixme: FileNotFoundError From f2551781624af97fe7016deab09336c125351953 Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Wed, 1 Jun 2022 19:52:16 +0200 Subject: [PATCH 08/14] fix file not found error; --- algorithms/genetic/map_generator.py | 2 +- algorithms/genetic/map_importer_exporter.py | 13 ++++++++----- algorithms/genetic/population.py | 0 3 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 algorithms/genetic/population.py diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index e90488f..abe85b9 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -10,7 +10,7 @@ def main() -> None: print(example_genome.grid) islands = get_islands(example_genome.grid, example_genome.knights_red) print(f'Roots {islands} and islands count {len(islands)}') - # export_map(example_genome.grid) fixme: FileNotFoundError + export_map(example_genome.grid) if __name__ == '__main__': diff --git a/algorithms/genetic/map_importer_exporter.py b/algorithms/genetic/map_importer_exporter.py index 9293f75..a3b5034 100644 --- a/algorithms/genetic/map_importer_exporter.py +++ b/algorithms/genetic/map_importer_exporter.py @@ -2,12 +2,13 @@ import json import random import string from datetime import datetime - +from pathlib import Path import numpy import numpy.typing as npt from os import listdir from os.path import isfile, join +MAPS_FOLDER = Path("resources/maps/") # Save map to file @@ -16,8 +17,9 @@ def export_map(grid: npt.NDArray): now = datetime.now() file_name = "map_" + now.strftime("%Y_%m_%d_%H_%M_%S") + ".json" + file_to_open = MAPS_FOLDER / file_name - with open("resources/maps/" + file_name, "w") as write_file: + with open(file_to_open, "w") as write_file: json.dump(json_data, write_file) print("Saved map to file " + file_name) @@ -30,9 +32,10 @@ def import_random_map() -> object: # Read map from file -def import_map(file: string) -> object: - with open("resources/maps/" + file, "r") as read_file: - print("Reading map from file " + file) +def import_map(file_name: string) -> object: + file_to_open = MAPS_FOLDER / file_name + with open(file_to_open, "r") as read_file: + print("Reading map from file " + file_name) decoded_json = json.load(read_file) decoded_grid = numpy.asarray(decoded_json["map"]) diff --git a/algorithms/genetic/population.py b/algorithms/genetic/population.py new file mode 100644 index 0000000..e69de29 From 10e61e724ca013f60a359d7afcbe5e246267df9e Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Thu, 2 Jun 2022 00:52:16 +0200 Subject: [PATCH 09/14] setup genetic alg; --- algorithms/genetic/common.py | 69 ++++++++++++++++++ algorithms/genetic/const.py | 4 +- algorithms/genetic/genome.py | 69 +++++++++++++++++- algorithms/genetic/map_generator.py | 29 +++++--- algorithms/genetic/map_importer_exporter.py | 10 +-- algorithms/genetic/population.py | 81 +++++++++++++++++++++ algorithms/neural_network/__init__.py | 0 resources/maps/map_2022_05_31_00_41_36.json | 1 - resources/maps/map_2022_05_31_00_41_47.json | 1 - resources/maps/map_2022_05_31_00_41_51.json | 1 - resources/maps/map_2022_06_02_00_36_19.json | 1 + resources/maps/map_2022_06_02_00_38_31.json | 1 + resources/maps/map_2022_06_02_00_42_44.json | 1 + 13 files changed, 246 insertions(+), 22 deletions(-) create mode 100644 algorithms/neural_network/__init__.py delete mode 100644 resources/maps/map_2022_05_31_00_41_36.json delete mode 100644 resources/maps/map_2022_05_31_00_41_47.json delete mode 100644 resources/maps/map_2022_05_31_00_41_51.json create mode 100644 resources/maps/map_2022_06_02_00_36_19.json create mode 100644 resources/maps/map_2022_06_02_00_38_31.json create mode 100644 resources/maps/map_2022_06_02_00_42_44.json diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py index e3f4cc5..49b0412 100644 --- a/algorithms/genetic/common.py +++ b/algorithms/genetic/common.py @@ -1,4 +1,7 @@ from dataclasses import dataclass + +import numpy as np + from const import * from typing import List, Dict, Tuple @@ -11,6 +14,56 @@ class Position: col: int +@dataclass +class Area: + position: Position + width: int + height: int + + +AREAS_TO_CROSS = [ + # up above left knights spawn + Area(position=Position(row=0, col=0), + width=KNIGHTS_SPAWN_WIDTH, + height=LEFT_KNIGHTS_SPAWN_FIRST_ROW), + + # down below left knights spawn + Area(position=Position(row=LEFT_KNIGHTS_SPAWN_FIRST_ROW + KNIGHTS_SPAWN_HEIGHT, col=0), + width=KNIGHTS_SPAWN_WIDTH, + height=ROWS - LEFT_KNIGHTS_SPAWN_FIRST_ROW - KNIGHTS_SPAWN_HEIGHT), + + # between left knights spawn and castle + Area(position=Position(row=0, col=KNIGHTS_SPAWN_WIDTH), + width=CASTLE_SPAWN_FIRST_COL - KNIGHTS_SPAWN_WIDTH, + height=ROWS), + + # up above castle + Area(position=Position(row=0, col=CASTLE_SPAWN_FIRST_COL), + width=2, + height=CASTLE_SPAWN_FIRST_ROW), + + # down below castle + Area(position=Position(row=CASTLE_SPAWN_FIRST_ROW + 2, col=CASTLE_SPAWN_FIRST_COL), + width=2, + height=ROWS - CASTLE_SPAWN_FIRST_ROW - 2), + + # between castle and right knights spawn + Area(position=Position(row=0, col=CASTLE_SPAWN_FIRST_COL + 2), + width=RIGHT_KNIGHTS_SPAWN_FIRST_COL - CASTLE_SPAWN_FIRST_COL - 2, + height=ROWS), + + # up above right knights spawn + Area(position=Position(row=0, col=RIGHT_KNIGHTS_SPAWN_FIRST_COL), + width=KNIGHTS_SPAWN_WIDTH, + height=RIGHT_KNIGHTS_SPAWN_FIRST_ROW), + + # down below right knights spawn + Area(position=Position(row=RIGHT_KNIGHTS_SPAWN_FIRST_ROW + KNIGHTS_SPAWN_HEIGHT, col=RIGHT_KNIGHTS_SPAWN_FIRST_COL), + width=KNIGHTS_SPAWN_WIDTH, + height=ROWS - RIGHT_KNIGHTS_SPAWN_FIRST_ROW - KNIGHTS_SPAWN_HEIGHT), +] + + def dfs(grid: npt.NDArray, visited: Dict[Tuple[int, int], bool], position: Position, rows: int, cols: int) -> None: visited[(position.row, position.col)] = True @@ -51,3 +104,19 @@ def get_islands(grid: npt.NDArray, positions: List[Position], rows: int = ROWS, islands += 1 return roots + + +def find_neighbours(grid: npt.NDArray, col: int, row: int) -> List[Position]: + dr = [-1, 1, 0, 0] + dc = [0, 0, -1, 1] + + neighbours = [] + + for i in range(4): + rr = row + dr[i] + cc = col + dc[i] + + if 0 <= rr < ROWS and 0 <= cc < COLUMNS and grid[rr][cc] == MAP_ALIASES.get('GRASS'): + neighbours.append(Position(row=rr, col=cc)) + + return neighbours diff --git a/algorithms/genetic/const.py b/algorithms/genetic/const.py index ac7d37a..61ff403 100644 --- a/algorithms/genetic/const.py +++ b/algorithms/genetic/const.py @@ -13,6 +13,8 @@ LEFT_KNIGHTS_SPAWN_FIRST_ROW = 6 LEFT_KNIGHTS_SPAWN_FIRST_COL = 0 RIGHT_KNIGHTS_SPAWN_FIRST_ROW = 6 RIGHT_KNIGHTS_SPAWN_FIRST_COL = 20 +CASTLE_SPAWN_FIRST_ROW = 7 +CASTLE_SPAWN_FIRST_COL = 11 # map aliases MAP_ALIASES = { @@ -24,4 +26,4 @@ MAP_ALIASES = { "CASTLE": 5, "KNIGHT_RED": 6, "KNIGHT_BLUE": 7, -} +} \ No newline at end of file diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index f060352..982b394 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -1,10 +1,13 @@ +import math +import random +from copy import deepcopy from random import randrange from typing import List import numpy as np import numpy.typing as npt -from common import Position +from common import Position, get_islands, AREAS_TO_CROSS, find_neighbours from const import * @@ -16,11 +19,15 @@ class Genome: trees: List[Position] sands: List[Position] monsters: List[Position] + fitness: int + sand_islands: List[Position] + tree_islands: List[Position] + water_islands: List[Position] def __init__(self): self.grid = np.zeros((ROWS, COLUMNS), dtype=int) + self.fitness = 0 - # 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"), @@ -43,7 +50,7 @@ class Genome: grid=self.grid, object_alias=MAP_ALIASES.get("CASTLE"), objects_count=4, - spawn_position_start=Position(row=7, col=9), + spawn_position_start=Position(row=CASTLE_SPAWN_FIRST_ROW, col=CASTLE_SPAWN_FIRST_COL), width=2, height=2 ) @@ -57,6 +64,62 @@ class Genome: self.monsters = spawn_objects_in_given_area(grid=self.grid, object_alias=MAP_ALIASES.get("MONSTER"), objects_count=MONSTERS_COUNT) + self.sand_islands = get_islands(self.grid, self.sands) + self.tree_islands = get_islands(self.grid, self.trees) + self.water_islands = get_islands(self.grid, self.waters) + + def calc_fitness(self): + score = SAND_COUNT + TREE_COUNT + WATER_COUNT + score = score - len(self.sand_islands) - len(self.tree_islands) - len(self.water_islands) + + # todo: odległość manhattan od każdej wyspy + + self.fitness = score + + def crossover(self, partner): + # replace a randomly selected part of the grid with partner's part + child = Genome() + child.grid = deepcopy(self.grid) + area_to_cross = random.choice(AREAS_TO_CROSS) + + for row in range(area_to_cross.position.row, area_to_cross.position.row + area_to_cross.height): + for col in range(area_to_cross.position.col, area_to_cross.position.col + area_to_cross.width): + child.grid[row][col] = partner.grid[row][col] + + child.sand_islands = get_islands(self.grid, self.sands) + child.tree_islands = get_islands(self.grid, self.trees) + child.water_islands = get_islands(self.grid, self.waters) + + return child + + def mutate(self, mutation_rate: float): + # remove 1 item from a random island and add a neighbor to another island + if random.random() < mutation_rate: + + # select islands of the same, random type + islands_of_same_type = random.choice([self.sand_islands, self.tree_islands, self.water_islands]) + random_index = random.randint(0, len(islands_of_same_type) - 1) + island = islands_of_same_type[random_index] + next_island = islands_of_same_type[(random_index + 1) % len(islands_of_same_type)] + + free_tiles_nearby = find_neighbours(self.grid, next_island.col, next_island.row) + + tile_type = self.grid[island.row][island.col] + + self.grid[island.row][island.col] = MAP_ALIASES.get('GRASS') + islands_of_same_type.remove(island) + + # todo: if there are no free tiles around then randomize another next_island + if len(free_tiles_nearby) > 0: + random_free_tile = random.choice(free_tiles_nearby) + island.row = random_free_tile.row + island.col = random_free_tile.col + self.grid[island.row][island.col] = tile_type + + self.sand_islands = get_islands(self.grid, self.sands) + self.tree_islands = get_islands(self.grid, self.trees) + self.water_islands = get_islands(self.grid, self.waters) + def is_empty(grid: npt.NDArray, position: Position) -> bool: return grid[position.row, position.col] in [MAP_ALIASES.get("GRASS"), MAP_ALIASES.get("SAND")] diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index abe85b9..0fe333a 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -1,16 +1,25 @@ -from map_importer_exporter import export_map -from genome import Genome -from common import get_islands +from algorithms.genetic.genome import Genome +from algorithms.genetic.map_importer_exporter import export_map +from population import Population def main() -> None: - example_genome = Genome() - print(example_genome.knights_red) - print(example_genome.knights_blue) - print(example_genome.grid) - islands = get_islands(example_genome.grid, example_genome.knights_red) - print(f'Roots {islands} and islands count {len(islands)}') - export_map(example_genome.grid) + population_size = 500 + mutation_rate = 0.4 + + population = Population(mutation_rate, population_size, 27) + + while not population.evaluate(): + # create next generation + population.generate() + + # calc fitness + population.calc_fitness() + + print(population.best_genome.grid) + print("Fitness of the best: ", population.best_genome.fitness) + + export_map(population.best_genome.grid) if __name__ == '__main__': diff --git a/algorithms/genetic/map_importer_exporter.py b/algorithms/genetic/map_importer_exporter.py index a3b5034..543c2ca 100644 --- a/algorithms/genetic/map_importer_exporter.py +++ b/algorithms/genetic/map_importer_exporter.py @@ -8,8 +8,6 @@ import numpy.typing as npt from os import listdir from os.path import isfile, join -MAPS_FOLDER = Path("resources/maps/") - # Save map to file def export_map(grid: npt.NDArray): @@ -17,9 +15,11 @@ def export_map(grid: npt.NDArray): now = datetime.now() file_name = "map_" + now.strftime("%Y_%m_%d_%H_%M_%S") + ".json" - file_to_open = MAPS_FOLDER / file_name + path = Path("../../resources/maps/") + file_to_open = path / file_name - with open(file_to_open, "w") as write_file: + print(file_to_open) + with open(file_to_open, "w+") as write_file: json.dump(json_data, write_file) print("Saved map to file " + file_name) @@ -33,7 +33,7 @@ def import_random_map() -> object: # Read map from file def import_map(file_name: string) -> object: - file_to_open = MAPS_FOLDER / file_name + file_to_open = "resources/maps/" + file_name with open(file_to_open, "r") as read_file: print("Reading map from file " + file_name) decoded_json = json.load(read_file) diff --git a/algorithms/genetic/population.py b/algorithms/genetic/population.py index e69de29..85ca8a4 100644 --- a/algorithms/genetic/population.py +++ b/algorithms/genetic/population.py @@ -0,0 +1,81 @@ +import random +from typing import List + +import numpy as np +import numpy.typing as npt + +from genome import Genome + + +class Population: + population: List[Genome] = [] # array to hold the current population + mating_pool: List[Genome] = [] # array which we will use for our "mating pool" + generations: int = 0 # number of generations + finished: bool = False # are we finished evolving? + mutation_rate: float + perfect_score: int + best_genome: Genome + + def __init__(self, mutation_rate, population_size, perfect_score=20): + self.mutation_rate = mutation_rate + self.perfect_score = perfect_score + + for i in range(0, population_size): + new_genome = Genome() + new_genome.calc_fitness() + self.population.append(new_genome) + + # create a new generation + def generate(self): + max_fitness = 0 + for genome in self.population: + if genome.fitness > max_fitness: + max_fitness = genome.fitness + + print("Max fitness of generation " + str(self.generations) + " = " + str(max_fitness)) + + # refill the population with children from the mating pool + new_population = [] + for genome in self.population: + partner_a = self.accept_reject(max_fitness) + partner_b = self.accept_reject(max_fitness) + child = partner_a.crossover(partner_b) + child.mutate(self.mutation_rate) + new_population.append(child) + + self.population = new_population + self.generations += 1 + + # select random with correct probability from population + def accept_reject(self, max_fitness: int): + safe_flag = 0 + + while safe_flag < 10000: + partner = random.choice(self.population) + r = random.randint(0, max_fitness) + + if r < partner.fitness: + return partner + + safe_flag += 1 + + # compute the current "most fit" member of the population + def evaluate(self): + record = 0 + best_index = 0 + + for index in range(len(self.population)): + genome = self.population[index] + if genome.fitness > record: + record = genome.fitness + best_index = index + + self.best_genome = self.population[best_index] + if record >= self.perfect_score: + self.finished = True + + return self.finished + + def calc_fitness(self): + for genome in self.population: + genome.calc_fitness() diff --git a/algorithms/neural_network/__init__.py b/algorithms/neural_network/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/resources/maps/map_2022_05_31_00_41_36.json b/resources/maps/map_2022_05_31_00_41_36.json deleted file mode 100644 index 9e72315..0000000 --- a/resources/maps/map_2022_05_31_00_41_36.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 4, 2, 3, 0, 0, 3, 3, 0, 3, 4, 0, 0], [0, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 1, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 3, 5, 5, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 7, 0, 0], [2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], [6, 6, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 2, 2, 0, 2, 0, 3, 0, 0, 7, 0], [0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0], [1, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0], [0, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_05_31_00_41_47.json b/resources/maps/map_2022_05_31_00_41_47.json deleted file mode 100644 index f9c80cd..0000000 --- a/resources/maps/map_2022_05_31_00_41_47.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 3, 0, 0, 3, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 2, 1, 2, 3, 0, 3, 0, 0, 0, 0], [3, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0], [0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 3, 0, 0, 7, 7], [0, 0, 3, 2, 0, 0, 0, 0, 0, 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 1, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0], [0, 0, 6, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 3, 0, 7, 0], [0, 6, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 1, 0, 0, 0], [0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 3, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 3, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_05_31_00_41_51.json b/resources/maps/map_2022_05_31_00_41_51.json deleted file mode 100644 index 879f5fd..0000000 --- a/resources/maps/map_2022_05_31_00_41_51.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0], [2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0], [0, 1, 0, 0, 3, 0, 0, 1, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], [6, 0, 0, 0, 1, 2, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 5, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 7, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0], [6, 2, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 7, 0, 7], [0, 3, 6, 2, 0, 3, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 3, 3, 0, 0, 0, 4, 0, 0, 0, 3, 1, 0, 0, 0], [0, 3, 2, 3, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_00_36_19.json b/resources/maps/map_2022_06_02_00_36_19.json new file mode 100644 index 0000000..c377a12 --- /dev/null +++ b/resources/maps/map_2022_06_02_00_36_19.json @@ -0,0 +1 @@ +{"map": [[3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 1, 1, 0], [2, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [0, 0, 6, 0, 1, 3, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 7, 0], [0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 1, 5, 5, 0, 0, 1, 0, 3, 0, 0, 3, 7, 0, 0], [0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 6, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 7, 0], [0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 3, 0, 3, 0, 3, 3], [3, 1, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 2, 1, 1, 3, 0, 1, 0], [0, 0, 0, 0, 3, 3, 3, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_00_38_31.json b/resources/maps/map_2022_06_02_00_38_31.json new file mode 100644 index 0000000..1f8bb43 --- /dev/null +++ b/resources/maps/map_2022_06_02_00_38_31.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0], [1, 2, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0], [6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [6, 0, 3, 0, 0, 0, 2, 3, 0, 3, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0], [0, 1, 0, 2, 3, 0, 0, 0, 2, 0, 0, 5, 5, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [0, 6, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 3], [0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3], [2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], [3, 0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_00_42_44.json b/resources/maps/map_2022_06_02_00_42_44.json new file mode 100644 index 0000000..b17c72d --- /dev/null +++ b/resources/maps/map_2022_06_02_00_42_44.json @@ -0,0 +1 @@ +{"map": [[0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0], [0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 1], [0, 0, 0, 6, 0, 0, 0, 6, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 3, 5, 5, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 7, 7], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0], [0, 0, 0, 0, 1, 0, 3, 0, 0, 3, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 2, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 6, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0]]} \ No newline at end of file From fd081d5c567e2901bf15e2d4d1b186913f70f61b Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Thu, 2 Jun 2022 01:31:26 +0200 Subject: [PATCH 10/14] fix monsters count; --- algorithms/genetic/common.py | 9 +++++++++ algorithms/genetic/genome.py | 7 ++++++- resources/maps/map_2022_06_02_00_42_44.json | 1 - resources/maps/map_2022_06_02_01_11_02.json | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) delete mode 100644 resources/maps/map_2022_06_02_00_42_44.json create mode 100644 resources/maps/map_2022_06_02_01_11_02.json diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py index 49b0412..3552281 100644 --- a/algorithms/genetic/common.py +++ b/algorithms/genetic/common.py @@ -120,3 +120,12 @@ def find_neighbours(grid: npt.NDArray, col: int, row: int) -> List[Position]: neighbours.append(Position(row=rr, col=cc)) return neighbours + + +def count_in_grid(grid: npt.NDArray, target) -> int: + count = 0 + for row in grid: + for col in row: + if col == target: + count += 1 + return count diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index 982b394..11b72c9 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -7,7 +7,7 @@ from typing import List import numpy as np import numpy.typing as npt -from common import Position, get_islands, AREAS_TO_CROSS, find_neighbours +from common import Position, get_islands, AREAS_TO_CROSS, find_neighbours, count_in_grid from const import * @@ -72,6 +72,11 @@ class Genome: score = SAND_COUNT + TREE_COUNT + WATER_COUNT score = score - len(self.sand_islands) - len(self.tree_islands) - len(self.water_islands) + monsters_count = count_in_grid(self.grid, MAP_ALIASES.get('MONSTER')) + if monsters_count < 2: + self.fitness = 0 + return + # todo: odległość manhattan od każdej wyspy self.fitness = score diff --git a/resources/maps/map_2022_06_02_00_42_44.json b/resources/maps/map_2022_06_02_00_42_44.json deleted file mode 100644 index b17c72d..0000000 --- a/resources/maps/map_2022_06_02_00_42_44.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0], [0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 1], [0, 0, 0, 6, 0, 0, 0, 6, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 3, 5, 5, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 7, 7], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0], [0, 0, 0, 0, 1, 0, 3, 0, 0, 3, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 2, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 6, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0], [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_01_11_02.json b/resources/maps/map_2022_06_02_01_11_02.json new file mode 100644 index 0000000..bf43233 --- /dev/null +++ b/resources/maps/map_2022_06_02_01_11_02.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 0, 3, 0, 0, 0, 0, 0, 4, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3], [0, 3, 3, 0, 7, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 5, 5, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0], [0, 0, 6, 6, 0, 0, 0, 1, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0], [6, 0, 3, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0, 0, 0, 7, 3, 0, 0], [0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 2, 3, 4, 2, 0], [0, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 3, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 7, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0], [0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file From fd4b34eed7c98ba8e91fda0fe84bc2cf477881ad Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Thu, 2 Jun 2022 13:32:59 +0200 Subject: [PATCH 11/14] fixed bugs in genetic alg; modified fitness; --- algorithms/genetic/common.py | 25 ++++++++++++------ algorithms/genetic/genome.py | 28 ++++++++++++--------- algorithms/genetic/map_generator.py | 4 +-- algorithms/genetic/map_importer_exporter.py | 1 - resources/maps/map_2022_06_02_00_36_19.json | 1 - resources/maps/map_2022_06_02_00_38_31.json | 1 - resources/maps/map_2022_06_02_01_11_02.json | 1 - resources/maps/map_2022_06_02_13_17_41.json | 1 + resources/maps/map_2022_06_02_13_24_20.json | 1 + resources/maps/map_2022_06_02_13_27_18.json | 1 + 10 files changed, 39 insertions(+), 25 deletions(-) delete mode 100644 resources/maps/map_2022_06_02_00_36_19.json delete mode 100644 resources/maps/map_2022_06_02_00_38_31.json delete mode 100644 resources/maps/map_2022_06_02_01_11_02.json create mode 100644 resources/maps/map_2022_06_02_13_17_41.json create mode 100644 resources/maps/map_2022_06_02_13_24_20.json create mode 100644 resources/maps/map_2022_06_02_13_27_18.json diff --git a/algorithms/genetic/common.py b/algorithms/genetic/common.py index 3552281..ab4d200 100644 --- a/algorithms/genetic/common.py +++ b/algorithms/genetic/common.py @@ -122,10 +122,21 @@ def find_neighbours(grid: npt.NDArray, col: int, row: int) -> List[Position]: return neighbours -def count_in_grid(grid: npt.NDArray, target) -> int: - count = 0 - for row in grid: - for col in row: - if col == target: - count += 1 - return count +def get_tiles_positions(grid: npt.NDArray): + sands = [] + trees = [] + waters = [] + monsters = [] + + for row_num in range(len(grid)): + for col_num in range(len(grid[row_num])): + if grid[row_num][col_num] == MAP_ALIASES.get('WATER'): + waters.append(Position(row=row_num, col=col_num)) + elif grid[row_num][col_num] == MAP_ALIASES.get('TREE'): + trees.append(Position(row=row_num, col=col_num)) + elif grid[row_num][col_num] == MAP_ALIASES.get('SAND'): + sands.append(Position(row=row_num, col=col_num)) + elif grid[row_num][col_num] == MAP_ALIASES.get('MONSTER'): + monsters.append(Position(row=row_num, col=col_num)) + + return sands, trees, waters, monsters diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index 11b72c9..9b09c56 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -7,7 +7,7 @@ from typing import List import numpy as np import numpy.typing as npt -from common import Position, get_islands, AREAS_TO_CROSS, find_neighbours, count_in_grid +from common import Position, get_islands, AREAS_TO_CROSS, find_neighbours, get_tiles_positions from const import * @@ -68,16 +68,26 @@ class Genome: self.tree_islands = get_islands(self.grid, self.trees) self.water_islands = get_islands(self.grid, self.waters) + def update_map(self): + self.sands, self.trees, self.waters, self.monsters = get_tiles_positions(self.grid) + + self.sand_islands = get_islands(self.grid, self.sands) + self.tree_islands = get_islands(self.grid, self.trees) + self.water_islands = get_islands(self.grid, self.waters) + def calc_fitness(self): score = SAND_COUNT + TREE_COUNT + WATER_COUNT score = score - len(self.sand_islands) - len(self.tree_islands) - len(self.water_islands) - monsters_count = count_in_grid(self.grid, MAP_ALIASES.get('MONSTER')) - if monsters_count < 2: + sands, trees, waters, monsters = get_tiles_positions(self.grid) + + if len(monsters) < MONSTERS_COUNT: self.fitness = 0 return - # todo: odległość manhattan od każdej wyspy + if len(sands) < SAND_COUNT or len(trees) < TREE_COUNT or len(waters) < WATER_COUNT: + self.fitness = 5 + return self.fitness = score @@ -91,9 +101,7 @@ class Genome: for col in range(area_to_cross.position.col, area_to_cross.position.col + area_to_cross.width): child.grid[row][col] = partner.grid[row][col] - child.sand_islands = get_islands(self.grid, self.sands) - child.tree_islands = get_islands(self.grid, self.trees) - child.water_islands = get_islands(self.grid, self.waters) + child.update_map() return child @@ -110,9 +118,7 @@ class Genome: free_tiles_nearby = find_neighbours(self.grid, next_island.col, next_island.row) tile_type = self.grid[island.row][island.col] - self.grid[island.row][island.col] = MAP_ALIASES.get('GRASS') - islands_of_same_type.remove(island) # todo: if there are no free tiles around then randomize another next_island if len(free_tiles_nearby) > 0: @@ -121,9 +127,7 @@ class Genome: island.col = random_free_tile.col self.grid[island.row][island.col] = tile_type - self.sand_islands = get_islands(self.grid, self.sands) - self.tree_islands = get_islands(self.grid, self.trees) - self.water_islands = get_islands(self.grid, self.waters) + self.update_map() def is_empty(grid: npt.NDArray, position: Position) -> bool: diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 0fe333a..08740f2 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -5,9 +5,9 @@ from population import Population def main() -> None: population_size = 500 - mutation_rate = 0.4 + mutation_rate = 0.3 - population = Population(mutation_rate, population_size, 27) + population = Population(mutation_rate, population_size, 60) while not population.evaluate(): # create next generation diff --git a/algorithms/genetic/map_importer_exporter.py b/algorithms/genetic/map_importer_exporter.py index 543c2ca..35796fe 100644 --- a/algorithms/genetic/map_importer_exporter.py +++ b/algorithms/genetic/map_importer_exporter.py @@ -18,7 +18,6 @@ def export_map(grid: npt.NDArray): path = Path("../../resources/maps/") file_to_open = path / file_name - print(file_to_open) with open(file_to_open, "w+") as write_file: json.dump(json_data, write_file) print("Saved map to file " + file_name) diff --git a/resources/maps/map_2022_06_02_00_36_19.json b/resources/maps/map_2022_06_02_00_36_19.json deleted file mode 100644 index c377a12..0000000 --- a/resources/maps/map_2022_06_02_00_36_19.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 1, 1, 0], [2, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [0, 0, 6, 0, 1, 3, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 7, 0], [0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 1, 5, 5, 0, 0, 1, 0, 3, 0, 0, 3, 7, 0, 0], [0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 6, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 7, 0], [0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 3, 0, 3, 0, 3, 3], [3, 1, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 2, 1, 1, 3, 0, 1, 0], [0, 0, 0, 0, 3, 3, 3, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_00_38_31.json b/resources/maps/map_2022_06_02_00_38_31.json deleted file mode 100644 index 1f8bb43..0000000 --- a/resources/maps/map_2022_06_02_00_38_31.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0], [1, 2, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0], [6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [6, 0, 3, 0, 0, 0, 2, 3, 0, 3, 0, 5, 5, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0], [0, 1, 0, 2, 3, 0, 0, 0, 2, 0, 0, 5, 5, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [0, 6, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 3], [0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3], [2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], [3, 0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_01_11_02.json b/resources/maps/map_2022_06_02_01_11_02.json deleted file mode 100644 index bf43233..0000000 --- a/resources/maps/map_2022_06_02_01_11_02.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 0, 3, 0, 0, 0, 0, 0, 4, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3], [0, 3, 3, 0, 7, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 5, 5, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0], [0, 0, 6, 6, 0, 0, 0, 1, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0], [6, 0, 3, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0, 0, 0, 7, 3, 0, 0], [0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 2, 3, 4, 2, 0], [0, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 3, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 7, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0], [0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_13_17_41.json b/resources/maps/map_2022_06_02_13_17_41.json new file mode 100644 index 0000000..c32a112 --- /dev/null +++ b/resources/maps/map_2022_06_02_13_17_41.json @@ -0,0 +1 @@ +{"map": [[3, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0], [0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 2, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0], [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 3, 3, 3, 0, 0, 0, 0, 0, 0, 7, 7], [3, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [3, 3, 6, 0, 1, 0, 0, 3, 3, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 0], [3, 3, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 7, 1, 0], [0, 3, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 1, 0], [0, 3, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0], [0, 0, 3, 3, 0, 4, 0, 0, 0, 1, 1, 0, 0, 0, 1, 4, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0], [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_13_24_20.json b/resources/maps/map_2022_06_02_13_24_20.json new file mode 100644 index 0000000..54dabaa --- /dev/null +++ b/resources/maps/map_2022_06_02_13_24_20.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0], [0, 2, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 3, 1, 0], [3, 2, 2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 0], [3, 3, 2, 1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], [0, 3, 2, 2, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 3, 2, 0, 0, 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 3, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 1, 1], [6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1], [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 7], [0, 0, 6, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 7, 0, 1, 0], [0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 0, 0, 0, 2, 1, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0], [1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0], [1, 0, 3, 3, 3, 4, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_13_27_18.json b/resources/maps/map_2022_06_02_13_27_18.json new file mode 100644 index 0000000..186d352 --- /dev/null +++ b/resources/maps/map_2022_06_02_13_27_18.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 3, 3, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3], [0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3], [0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 3], [0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2], [0, 0, 3, 3, 3, 0, 0, 0, 3, 3, 3, 3, 0, 2, 2, 2, 0, 0, 0, 0, 0, 7, 2, 0], [0, 0, 0, 6, 0, 0, 0, 2, 2, 2, 0, 5, 5, 0, 2, 0, 0, 2, 2, 2, 2, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 5, 5, 0, 2, 0, 0, 0, 0, 2, 2, 1, 1, 7], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 1, 7], [6, 0, 0, 6, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 1, 1, 0], [6, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 3, 0, 1, 1, 7, 0], [0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1, 1, 0], [0, 3, 3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0], [0, 3, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file From 3f68f4c8a6c6fe7540ca43065f70d7e05df25fe7 Mon Sep 17 00:00:00 2001 From: korzepadawid Date: Sun, 5 Jun 2022 10:57:20 +0200 Subject: [PATCH 12/14] bug fix --- learning/decision_tree.py | 11 ++++++----- logic/level.py | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/learning/decision_tree.py b/learning/decision_tree.py index 7f92344..57ef4b2 100644 --- a/learning/decision_tree.py +++ b/learning/decision_tree.py @@ -34,7 +34,7 @@ class DecisionTree: self.model = DecisionTreeClassifier(criterion='entropy') self.model.fit(self.train_set.values, self.goals) - def predict_move(self, grid: List[List[str]], current_knight: Knight, castle: Castle, monsters: List[Monster], + def predict_move(self, grid: List[List[int]], current_knight: Knight, castle: Castle, monsters: List[Monster], opponents: List[Knight]) -> \ List[Tuple[int, int]]: distance_to_castle = manhattan_distance(current_knight.position, castle.position) @@ -42,14 +42,15 @@ class DecisionTree: monsters_parsed = [] for monster in monsters: monsters_parsed.append((manhattan_distance(current_knight.position, monster.position), parse_hp( - monster.current_hp))) + monster.health_bar.current_hp))) opponents_parsed = [] for opponent in opponents: opponents_parsed.append( - (manhattan_distance(current_knight.position, opponent.position), parse_hp(opponent.health_bar.current_hp))) + (manhattan_distance(current_knight.position, opponent.position), + parse_hp(opponent.health_bar.current_hp))) - prediction = self.get_prediction(tower_dist=distance_to_castle, tower_hp=castle.current_hp, + prediction = self.get_prediction(tower_dist=distance_to_castle, tower_hp=castle.health_bar.current_hp, mob1_dist=monsters_parsed[0][0], mob1_hp=monsters_parsed[0][1], mob2_dist=monsters_parsed[1][0], mob2_hp=monsters_parsed[1][1], opp1_dist=opponents_parsed[0][0], opp1_hp=opponents_parsed[0][1], @@ -57,7 +58,7 @@ class DecisionTree: opp3_dist=opponents_parsed[2][0], opp3_hp=opponents_parsed[2][1], opp4_dist=opponents_parsed[3][0], opp4_hp=opponents_parsed[3][1], agent_hp=current_knight.health_bar.current_hp) - print(prediction) + print(f'Prediction = {prediction}') if prediction == 'tower': # castle... return castle_neighbors(grid, castle_bottom_right_row=castle.position[0], castle_bottom_right_col=castle.position[1]) diff --git a/logic/level.py b/logic/level.py index 0ea19a8..9f43721 100644 --- a/logic/level.py +++ b/logic/level.py @@ -100,8 +100,8 @@ class Level: goal_list = self.decision_tree.predict_move(grid=self.map, current_knight=current_knight, monsters=self.list_monsters, - opponents=self.list_knights_red - if current_knight.team_alias() == 'k_r' else self.list_knights_blue, + opponents=self.list_knights_blue + if current_knight.team_alias() == 'k_r' else self.list_knights_red, castle=self.list_castles[0]) if len(goal_list) == 0: From 6ddfddb2fd20f21ae73fdea9978deea58440704a Mon Sep 17 00:00:00 2001 From: Angelika Iskra Date: Mon, 6 Jun 2022 14:59:24 +0200 Subject: [PATCH 13/14] fix monsters count in fitness func; --- algorithms/genetic/genome.py | 2 +- algorithms/genetic/map_generator.py | 2 +- resources/maps/map_2022_06_02_13_17_41.json | 1 - resources/maps/map_2022_06_02_13_24_20.json | 1 - resources/maps/map_2022_06_06_14_55_49.json | 1 + resources/maps/map_2022_06_06_14_58_11.json | 1 + 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 resources/maps/map_2022_06_02_13_17_41.json delete mode 100644 resources/maps/map_2022_06_02_13_24_20.json create mode 100644 resources/maps/map_2022_06_06_14_55_49.json create mode 100644 resources/maps/map_2022_06_06_14_58_11.json diff --git a/algorithms/genetic/genome.py b/algorithms/genetic/genome.py index 9b09c56..a5f5c37 100644 --- a/algorithms/genetic/genome.py +++ b/algorithms/genetic/genome.py @@ -81,7 +81,7 @@ class Genome: sands, trees, waters, monsters = get_tiles_positions(self.grid) - if len(monsters) < MONSTERS_COUNT: + if len(monsters) != MONSTERS_COUNT: self.fitness = 0 return diff --git a/algorithms/genetic/map_generator.py b/algorithms/genetic/map_generator.py index 08740f2..80e5b08 100644 --- a/algorithms/genetic/map_generator.py +++ b/algorithms/genetic/map_generator.py @@ -7,7 +7,7 @@ def main() -> None: population_size = 500 mutation_rate = 0.3 - population = Population(mutation_rate, population_size, 60) + population = Population(mutation_rate, population_size, 55) while not population.evaluate(): # create next generation diff --git a/resources/maps/map_2022_06_02_13_17_41.json b/resources/maps/map_2022_06_02_13_17_41.json deleted file mode 100644 index c32a112..0000000 --- a/resources/maps/map_2022_06_02_13_17_41.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[3, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0], [0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 2, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0], [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 3, 3, 3, 0, 0, 0, 0, 0, 0, 7, 7], [3, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], [3, 3, 6, 0, 1, 0, 0, 3, 3, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 0], [3, 3, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 7, 1, 0], [0, 3, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 1, 0], [0, 3, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0], [0, 0, 3, 3, 0, 4, 0, 0, 0, 1, 1, 0, 0, 0, 1, 4, 0, 0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0], [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_02_13_24_20.json b/resources/maps/map_2022_06_02_13_24_20.json deleted file mode 100644 index 54dabaa..0000000 --- a/resources/maps/map_2022_06_02_13_24_20.json +++ /dev/null @@ -1 +0,0 @@ -{"map": [[0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0], [0, 2, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 3, 1, 0], [3, 2, 2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 0], [3, 3, 2, 1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], [0, 3, 2, 2, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 3, 2, 0, 0, 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 3, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 1, 1], [6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1], [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 7], [0, 0, 6, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 7, 0, 1, 0], [0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 0, 0, 0, 2, 1, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0], [1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0], [1, 0, 3, 3, 3, 4, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_06_14_55_49.json b/resources/maps/map_2022_06_06_14_55_49.json new file mode 100644 index 0000000..86d09a8 --- /dev/null +++ b/resources/maps/map_2022_06_06_14_55_49.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0], [0, 3, 3, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 3, 3, 3, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 2, 2, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 2, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 3, 0, 0, 0, 0, 0, 3, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 6, 3, 3, 0, 0, 0, 0, 0, 3, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 0, 0], [6, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 3, 7, 0, 0, 0], [0, 0, 6, 6, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0], [0, 2, 2, 2, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0], [2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file diff --git a/resources/maps/map_2022_06_06_14_58_11.json b/resources/maps/map_2022_06_06_14_58_11.json new file mode 100644 index 0000000..dbf2de1 --- /dev/null +++ b/resources/maps/map_2022_06_06_14_58_11.json @@ -0,0 +1 @@ +{"map": [[0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3], [0, 0, 0, 0, 2, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 0], [0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 2, 0], [0, 0, 3, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 2, 0], [0, 0, 3, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0], [0, 0, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 6, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], [0, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 5, 5, 1, 2, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], [0, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 4], [6, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 0, 7, 0, 7, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0], [0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} \ No newline at end of file From e31364b21c7c8263d06d82b7b16269ade153402b Mon Sep 17 00:00:00 2001 From: AleksandraMuczynska Date: Wed, 8 Jun 2022 12:51:09 +0200 Subject: [PATCH 14/14] fixed knights_hp + basic attack ^<>v (improvement in progress) --- logic/level.py | 15 +++++++++++++++ models/knight.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/logic/level.py b/logic/level.py index 9f43721..df2c462 100644 --- a/logic/level.py +++ b/logic/level.py @@ -94,9 +94,19 @@ class Level: def handle_turn(self): current_knight = self.knights_queue.dequeue_knight() + knights_list = self.list_knights_red + self.list_knights_blue print("next turn " + current_knight.team) knight_pos_x = current_knight.position[0] knight_pos_y = current_knight.position[1] + positions = [] + op_pos_1 = current_knight.position[0] - 1, current_knight.position[1] + positions.append(op_pos_1) + op_pos_2 = current_knight.position[0], current_knight.position[1] - 1 + positions.append(op_pos_2) + op_pos_3 = current_knight.position[0] + 1, current_knight.position[1] + positions.append(op_pos_3) + op_pos_4 = current_knight.position[0], current_knight.position[1] + 1 + positions.append(op_pos_4) goal_list = self.decision_tree.predict_move(grid=self.map, current_knight=current_knight, monsters=self.list_monsters, @@ -116,6 +126,11 @@ class Level: return next_action = action_list.pop(0) + for some_knight in knights_list: + for some_position in positions: + if some_knight.position == some_position: + some_knight.health_bar.take_dmg(1) + if next_action == TURN_LEFT: self.logs.enqueue_log(f'AI {current_knight.team}: Obrót w lewo.') current_knight.rotate_left() diff --git a/models/knight.py b/models/knight.py index 05eabfc..39c2679 100644 --- a/models/knight.py +++ b/models/knight.py @@ -37,7 +37,7 @@ class Knight(pygame.sprite.Sprite): self.attack = random.randint(4, 7) self.defense = random.randint(1, 4) self.points = 1 - self.health_bar = HealthBar(screen, self.rect, current_hp=random.randint(1, self.max_hp), max_hp=self.max_hp, calculate_xy=True, calculate_size=True) + self.health_bar = HealthBar(screen, self.rect, current_hp=self.max_hp, max_hp=self.max_hp, calculate_xy=True, calculate_size=True) def rotate_left(self): self.direction = self.direction.left()