Traktor/app/graphsearch.py
2021-04-27 21:40:59 +02:00

137 lines
4.4 KiB
Python

from __future__ import annotations
from abc import abstractmethod
from typing import Callable, Union
from queue import Queue
from app.board import Board
from app.tractor import Tractor
from app.fields import Clay, Sand, Plant, CROPS
from config import *
class Node:
def __init__(self, parent: Union[Node, None], x: int, y: int,
direction: float, amount_of_harvested_crops: int,
movement: str, action: str):
self.__x = x
self.__y = y
self.__parent = parent
self.__direction = direction
self.__movement = movement
self.__action = action
self.__amount_of_harvested_crops = amount_of_harvested_crops
# self.__type_field = type_field
def get_x(self) -> int:
return self.__x
def get_y(self) -> int:
return self.__y
def get_node(self) -> Node:
return self.__parent
def get_direction(self) -> float:
return self.__direction
def get_action(self) -> str:
return self.__action
def get_movement(self) -> str:
return self.__movement
def get_amount_of_harvested_crops(self) -> int:
return self.__amount_of_harvested_crops
def transform_node_to_tuple(self) -> tuple[int, int, float]:
return self.__x, self.__y, self.__direction
class Graphsearch:
@staticmethod
def convert_queue_of_nodes_to_list(q: Queue[Node], *args) -> list:
items = []
[items.append((i.get_x(), i.get_y(), i.get_direction(), *args)) for i in q.queue]
return items
@staticmethod
def succ(item: Node, board: Board) -> list:
# list of tuples (movement,action),(x,y,direction, harvested_crops)
actions = []
x = item.get_x()
y = item.get_y()
current_harvested_crops = item.get_amount_of_harvested_crops()
# do action ex. harvest:
field = board.get_field(x, y)
action_name = A_DO_NOTHING
if isinstance(field, Clay):
# fertilize
action_name = A_FERTILIZE
field = Tractor.fertilize_clay_succ(field, board, x, y)
elif isinstance(field, Sand):
# sow, letter hydrate
action_name = A_SOW
field = Tractor.sow_succ(field)
field = Tractor.irrigate_sand_succ(field, board, x, y)
# action_name = A_HYDRATE
elif isinstance(field, Plant):
# hydrate
action_name = A_HYDRATE
field = Tractor.irrigate_plants_succ(field, board, x, y)
elif type(field).__name__ in CROPS:
# harvest
action_name = A_HARVEST
field = Tractor.harvest_crops_succ(board, x, y)
current_harvested_crops += 1
# print(current_harvested_crops)
# move
current_direction = item.get_direction()
tractor_move = Tractor.move_is_correct(x, y, current_direction)
# print(f"res: {tractor_move}")
if tractor_move is not None:
pos_x, pos_y = tractor_move
actions.append(((M_GO_FORWARD, action_name),
(pos_x, pos_y, current_direction, current_harvested_crops)))
rotated_direction = (current_direction - 90.0) % 360.0
actions.append(((M_ROTATE_LEFT, action_name), (x, y, rotated_direction, current_harvested_crops)))
rotated_direction = (current_direction + 90.0) % 360.0
actions.append(((M_ROTATE_RIGHT, action_name), (x, y, rotated_direction, current_harvested_crops)))
return actions
@staticmethod
def goaltest(item: Node) -> bool:
# print(item.get_amount_of_harvested_crops())
if item.get_amount_of_harvested_crops() == AMOUNT_OF_CROPS:
return True
else:
return False
@staticmethod
def get_all_moves(item: Node) -> list:
moves = []
str_moves = []
while item.get_node() is not None:
moves.append((item.get_movement(), item.get_action()))
str_moves.append(
f"{item.get_action()} - {item.get_movement()} - {item.get_x()}:{item.get_y()} {item.get_direction()}")
item = item.get_node()
print(str_moves[::-1])
return moves[::-1]
@staticmethod
@abstractmethod
def search(fringe: Queue, explored: Queue, istate: Node,
succ: Callable[[Node, Board], list],
goaltest: Callable[[Node], bool], board: Board) -> Union[bool, list]:
raise NotImplementedError