2021-03-16 10:06:56 +01:00
|
|
|
#!/usr/bin/python3
|
2021-04-13 09:55:19 +02:00
|
|
|
import copy
|
2021-06-23 11:52:04 +02:00
|
|
|
import random
|
2021-04-27 21:40:59 +02:00
|
|
|
from queue import Queue, PriorityQueue
|
2021-04-13 10:40:56 +02:00
|
|
|
from threading import Event
|
2021-03-16 10:06:56 +01:00
|
|
|
|
|
|
|
import pygame
|
|
|
|
|
|
|
|
from config import *
|
2021-05-05 16:59:41 +02:00
|
|
|
from app.cmd_parser import Arg
|
2021-04-27 21:40:59 +02:00
|
|
|
from app.graphsearch import Node
|
2021-03-16 10:06:56 +01:00
|
|
|
from app.board import Board
|
2021-03-30 11:24:50 +02:00
|
|
|
from app.tractor import Tractor
|
2021-04-27 21:40:59 +02:00
|
|
|
from app.a_star import AStar
|
|
|
|
from app.bfs import Bfs
|
2021-03-16 10:06:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
class App:
|
2021-05-05 16:59:41 +02:00
|
|
|
def __init__(self, args: list[Arg]):
|
2021-03-16 10:06:56 +01:00
|
|
|
self.__running = True
|
|
|
|
self.__screen = None
|
|
|
|
self.__clock = None
|
2021-05-05 16:59:41 +02:00
|
|
|
self.__board = Board(args=args)
|
2021-03-30 11:24:50 +02:00
|
|
|
self.__tractor = Tractor(self.__board)
|
2021-04-13 10:40:56 +02:00
|
|
|
self.__bot_is_running = Event()
|
2021-04-13 09:55:19 +02:00
|
|
|
self.__moves = None
|
2021-06-23 14:26:59 +02:00
|
|
|
self.__auto_mode = self.get_auto_mode_arg(args)
|
|
|
|
|
|
|
|
def get_auto_mode_arg(self, args: list[Arg]):
|
|
|
|
for arg in args:
|
|
|
|
if arg.get_arg_name() == AUTO_MODE:
|
|
|
|
return True
|
|
|
|
return False
|
2021-03-16 10:06:56 +01:00
|
|
|
|
|
|
|
def initialize(self):
|
|
|
|
pygame.init()
|
|
|
|
pygame.display.set_caption(CAPTION)
|
|
|
|
self.__screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
|
|
|
|
|
|
|
self.__clock = pygame.time.Clock()
|
|
|
|
|
|
|
|
def event_handler(self, event: pygame.event.Event):
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
self.__running = False
|
|
|
|
|
|
|
|
def loop_handler(self):
|
|
|
|
self.__board.draw(self.__screen)
|
2021-03-30 11:24:50 +02:00
|
|
|
self.__tractor.draw(self.__screen)
|
2021-03-16 10:06:56 +01:00
|
|
|
|
|
|
|
def keys_pressed_handler(self):
|
|
|
|
keys = pygame.key.get_pressed()
|
|
|
|
|
2021-04-11 19:48:44 +02:00
|
|
|
if keys[pygame.K_w]:
|
|
|
|
self.__tractor.move()
|
|
|
|
print(self.__tractor)
|
|
|
|
|
2021-06-01 21:13:32 +02:00
|
|
|
if keys[pygame.K_n]:
|
|
|
|
self.__bot_is_running.set()
|
|
|
|
self.__tractor.harvest_checked_fields_handler(self.__bot_is_running)
|
|
|
|
|
2021-03-30 11:24:50 +02:00
|
|
|
if keys[pygame.K_h]:
|
|
|
|
self.__tractor.harvest()
|
|
|
|
|
|
|
|
if keys[pygame.K_v]:
|
|
|
|
self.__tractor.sow()
|
|
|
|
|
2021-06-01 21:13:32 +02:00
|
|
|
if keys[pygame.K_j]:
|
2021-03-30 11:24:50 +02:00
|
|
|
self.__tractor.hydrate()
|
|
|
|
|
|
|
|
if keys[pygame.K_f]:
|
|
|
|
self.__tractor.fertilize()
|
|
|
|
|
2021-04-11 19:48:44 +02:00
|
|
|
if keys[pygame.K_l]:
|
|
|
|
self.__tractor.rotate_left()
|
|
|
|
|
|
|
|
if keys[pygame.K_r]:
|
|
|
|
self.__tractor.rotate_right()
|
|
|
|
|
2021-04-13 09:55:19 +02:00
|
|
|
if keys[pygame.K_b]:
|
|
|
|
self.get_moves_by_bfs()
|
|
|
|
if not self.__moves:
|
|
|
|
print(f"Bfs is failed")
|
|
|
|
else:
|
|
|
|
print(f"Bfs is succeed")
|
2021-04-13 10:40:56 +02:00
|
|
|
self.__bot_is_running.set()
|
2021-04-27 21:40:59 +02:00
|
|
|
self.__tractor.run_bot_handler(self.__moves, self.__bot_is_running)
|
2021-04-13 09:55:19 +02:00
|
|
|
|
2021-04-27 21:40:59 +02:00
|
|
|
if keys[pygame.K_c]:
|
2021-06-23 14:26:59 +02:00
|
|
|
self.get_moves_by_a_star_with_random_coords()
|
2021-04-27 21:40:59 +02:00
|
|
|
if not self.__moves:
|
|
|
|
print(f"A Star is failed")
|
|
|
|
else:
|
|
|
|
print(f"A Star is succeed")
|
|
|
|
self.__bot_is_running.set()
|
|
|
|
self.__tractor.run_bot_handler(self.__moves, self.__bot_is_running)
|
2021-03-16 10:06:56 +01:00
|
|
|
|
2021-06-23 11:52:04 +02:00
|
|
|
if keys[pygame.K_a]:
|
2021-06-23 14:26:59 +02:00
|
|
|
self.auto_moving_mode()
|
2021-06-23 11:52:04 +02:00
|
|
|
|
2021-04-27 21:40:59 +02:00
|
|
|
def update_screen(self) -> None:
|
2021-03-16 10:06:56 +01:00
|
|
|
pygame.display.flip()
|
|
|
|
|
2021-04-27 21:40:59 +02:00
|
|
|
def quit(self) -> None:
|
2021-03-16 10:06:56 +01:00
|
|
|
pygame.quit()
|
|
|
|
|
2021-06-23 14:26:59 +02:00
|
|
|
def auto_moving_mode(self):
|
|
|
|
coords, action = self.get_coords_and_action()
|
2021-04-27 21:40:59 +02:00
|
|
|
x, y = self.__tractor.get_position()
|
2021-06-23 14:26:59 +02:00
|
|
|
if coords is not None:
|
|
|
|
x1, y1 = coords
|
|
|
|
else:
|
|
|
|
x1, y1 = None, None
|
|
|
|
print(action, coords)
|
|
|
|
if action != A_DO_NOTHING and x1 == x and y == y1:
|
|
|
|
self.__tractor.do_action_on_fields(action)
|
|
|
|
elif action == A_DO_NOTHING:
|
|
|
|
print(action)
|
|
|
|
elif not self.__moves:
|
|
|
|
print(f"A Star is failed")
|
|
|
|
else:
|
|
|
|
print(f"A Star is succeed")
|
|
|
|
self.__bot_is_running.set()
|
|
|
|
self.__tractor.run_auto_bot_handler(action, self.__moves, self.__bot_is_running)
|
|
|
|
|
|
|
|
def get_coords_and_action(self) -> tuple[tuple[int, int], str]:
|
|
|
|
coords, action = self.__tractor.choose_action()
|
|
|
|
if coords is not None:
|
|
|
|
self.get_moves_by_a_star(coords)
|
|
|
|
else:
|
|
|
|
self.__moves = None
|
|
|
|
return coords, action[0]
|
|
|
|
|
|
|
|
def get_moves_by_a_star_with_random_coords(self) -> None:
|
2021-06-23 11:52:04 +02:00
|
|
|
x1 = random.randint(0, HORIZONTAL_NUM_OF_FIELDS)
|
|
|
|
y1 = random.randint(0, VERTICAL_NUM_OF_FIELDS)
|
|
|
|
dest = (x1, y1)
|
2021-06-23 14:26:59 +02:00
|
|
|
self.get_moves_by_a_star(dest)
|
|
|
|
|
|
|
|
def get_moves_by_a_star(self, coords: tuple[int, int]) -> None:
|
|
|
|
x, y = self.__tractor.get_position()
|
|
|
|
node = Node(None, x, y, self.__tractor.get_direction(), 0, "movement", "initial state")
|
|
|
|
board = copy.deepcopy(self.__board)
|
|
|
|
self.__moves = AStar.search_solution(PriorityQueue(), Queue(), coords, node,
|
2021-06-23 11:52:04 +02:00
|
|
|
lambda n=node, b=board: AStar.succ(n, b),
|
2021-06-23 14:26:59 +02:00
|
|
|
lambda d=coords, n=node: AStar.goaltest_by_coords(d, n), board)
|
2021-04-27 21:40:59 +02:00
|
|
|
|
|
|
|
def get_moves_by_bfs(self) -> None:
|
2021-04-13 09:55:19 +02:00
|
|
|
x, y = self.__tractor.get_position()
|
2021-04-13 10:40:56 +02:00
|
|
|
node = Node(None, x, y, self.__tractor.get_direction(), 0, "movement", "initial state")
|
2021-04-13 09:55:19 +02:00
|
|
|
board = copy.deepcopy(self.__board)
|
2021-04-27 21:40:59 +02:00
|
|
|
self.__moves = Bfs.search(Queue(), Queue(), node,
|
2021-06-23 11:52:04 +02:00
|
|
|
lambda n=node, b=board: Bfs.succ(n, b),
|
|
|
|
lambda n=node: Bfs.goaltest(n), board)
|
2021-04-13 09:55:19 +02:00
|
|
|
|
2021-04-27 21:40:59 +02:00
|
|
|
def run(self) -> None:
|
2021-03-16 10:06:56 +01:00
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
while self.__running:
|
|
|
|
self.__clock.tick(FPS)
|
2021-06-23 14:26:59 +02:00
|
|
|
|
2021-03-16 10:06:56 +01:00
|
|
|
for event in pygame.event.get():
|
|
|
|
self.event_handler(event)
|
|
|
|
|
2021-06-23 14:26:59 +02:00
|
|
|
if not self.__bot_is_running.is_set() and not self.__auto_mode:
|
2021-04-13 09:55:19 +02:00
|
|
|
self.keys_pressed_handler()
|
2021-06-23 14:26:59 +02:00
|
|
|
if not self.__bot_is_running.is_set() and self.__auto_mode:
|
|
|
|
self.auto_moving_mode()
|
2021-03-16 10:06:56 +01:00
|
|
|
|
|
|
|
self.loop_handler()
|
|
|
|
self.update_screen()
|
|
|
|
|
|
|
|
self.quit()
|