Machine_learning_2023/main.py

263 lines
9.3 KiB
Python

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()