from random import randint import pygame import configparser config = configparser.ConfigParser() config.read("config.ini") from domain.commands.random_cat_move_command import RandomCatMoveCommand from domain.commands.vacuum_move_command import VacuumMoveCommand from domain.entities.cat import Cat from domain.entities.entity import Entity from domain.entities.vacuum import Vacuum from domain.entities.garbage import Garbage from domain.entities.earring import Earring from domain.entities.docking_station import Doc_Station from domain.world import World from view.renderer import Renderer from AI_brain.genetic_algorytm import GeneticAlgorytm, Path if not config.getboolean("NEURAL_NETWORK", "is_neural_network_off"): from AI_brain.image_recognition import VacuumRecognizer # from AI_brain.movement import GoAnyDirectionBFS, State # from AI_brain.rotate_and_go_bfs import RotateAndGoBFS, State from AI_brain.rotate_and_go_aStar import RotateAndGoAStar, State class Main: def __init__(self): tiles_x = 10 tiles_y = 10 self.renderer = Renderer(600, 600, tiles_x, tiles_y) self.world = generate_world(tiles_x, tiles_y) self.commands = [] self.clock = pygame.time.Clock() self.running = True self.fps = 60 def run(self): while self.running: self.process_input() self.update() self.renderer.render(self.world) self.clock.tick(self.fps) pygame.quit() def run_robot(self): self.renderer.render(self.world) if config["AI_BRAIN"]["mode"] == "to_station": start_state = State(self.world.vacuum.x, self.world.vacuum.y) end_state = State(self.world.doc_station.x, self.world.doc_station.y) path_searcher = RotateAndGoAStar(self.world, start_state, end_state) if not path_searcher.search(): print("No solution") exit(0) print(path_searcher.actions) print(path_searcher.cost) robot_actions = path_searcher.actions elif config["AI_BRAIN"]["mode"] == "full_clean": genetic_searcher = GeneticAlgorytm(self.world) genetic_searcher.run() genetic_searcher.print_top() robot_actions = genetic_searcher.best_path.real_path else: print("Wrong mode") exit(0) while self.running: for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if len(robot_actions) > 0: action_direction = robot_actions.pop(0) # self.handle_action1(action_direction) self.handle_action2(action_direction) self.update() self.renderer.render(self.world) self.clock.tick(5) pygame.quit() def handle_action1(self, action): if action == "UP": self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (0, -1)) ) elif action == "DOWN": self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (0, 1)) ) elif action == "LEFT": self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (-1, 0)) ) elif action == "RIGHT": self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (1, 0)) ) def handle_action2(self, action): if action == "GO": self.commands.append( VacuumMoveCommand( self.world, self.world.vacuum, self.world.vacuum.direction ) ) elif action == "RR": self.world.vacuum.direction = ( -self.world.vacuum.direction[1], self.world.vacuum.direction[0], ) elif action == "RL": self.world.vacuum.direction = ( self.world.vacuum.direction[1], -self.world.vacuum.direction[0], ) elif action == "DEFAULT_ROTATION": self.world.vacuum.direction = (1, 0) def process_input(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (-1, 0)) ) if event.key == pygame.K_RIGHT: self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (1, 0)) ) if event.key == pygame.K_UP: self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (0, -1)) ) if event.key == pygame.K_DOWN: self.commands.append( VacuumMoveCommand(self.world, self.world.vacuum, (0, 1)) ) def update(self): if config.getboolean("APP", "cat"): self.commands.append(RandomCatMoveCommand(self.world, self.world.cat)) for command in self.commands: command.run() self.commands.clear() def generate_world(tiles_x: int, tiles_y: int) -> World: if config.getboolean("NEURAL_NETWORK", "is_neural_network_off"): world = World(tiles_x, tiles_y) x, y = config.get("CONSTANT", "RobotStartPosition").split(",") x, y = int(x), int(y) world.vacuum = Vacuum(x, y) x, y = config.get("CONSTANT", "DockStationStartPosition").split(",") x, y = int(x), int(y) world.doc_station = Doc_Station(x, y) if config.getboolean("APP", "cat"): world.cat = Cat(7, 8) world.add_entity(world.cat) world.add_entity(world.doc_station) world.add_entity(world.vacuum) world.add_entity(Entity(2, 8, "PLANT1")) world.add_entity(Entity(4, 1, "PLANT1")) world.add_entity(Entity(3, 4, "PLANT2")) world.add_entity(Entity(8, 8, "PLANT2")) world.add_entity(Entity(9, 3, "PLANT3")) numberOfEarrings = config.getint("CONSTANT", "NumberOfEarrings") for _ in range(numberOfEarrings): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) while world.is_entity_at(temp_x, temp_y): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) world.add_entity(Earring(temp_x, temp_y)) for _ in range(config.getint("CONSTANT", "NumberOfBananas")): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) while world.is_entity_at(temp_x, temp_y): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) world.add_entity(Garbage(temp_x, temp_y)) else: def world_adder(x, y, object, style=None): print(object) if object == "Plant": world.add_entity(Entity(x, y, f"PLANT{randint(1, 3)}")) if object == "Earings": world.add_entity(Earring(x, y)) if object == "Banana": world.add_entity(Garbage(temp_x, temp_y)) if object == "Cat" and config.getboolean("APP", "cat"): world.add_entity(Cat(x, y)) neural_network = VacuumRecognizer() world = World(tiles_x, tiles_y) world.vacuum = Vacuum(1, 1) world.doc_station = Doc_Station(9, 8) if config.getboolean("APP", "cat"): world.cat = Cat(7, 8) world.add_entity(world.cat) for _ in range(config.getint("CONSTANT", "NumberOfPlants")): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) path = VacuumRecognizer.get_random_dir(neural_network, "Plant") world_adder(temp_x, temp_y, neural_network.recognize(path)) for _ in range(config.getint("CONSTANT", "NumberOfEarrings")): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) path = VacuumRecognizer.get_random_dir(neural_network, "Earings") world_adder(temp_x, temp_y, neural_network.recognize(path)) for _ in range(config.getint("CONSTANT", "NumberOfBananas")): temp_x = randint(0, tiles_x - 1) temp_y = randint(0, tiles_y - 1) path = VacuumRecognizer.get_random_dir(neural_network, "Banana") world_adder(temp_x, temp_y, neural_network.recognize(path)) for x in range(world.width): for y in range(world.height): if world.garbage_at(x, y): world.costs[x][y] = 1 else: world.costs[x][y] = 2 return world if __name__ == "__main__": app = Main() if config["APP"]["movement"] == "human": app.run() elif config["APP"]["movement"] == "robot": app.run_robot()