From 650b5ab78717e713175f87773f70125a13f91cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20Szama=C5=82ek?= Date: Sat, 16 Apr 2022 15:55:43 +0200 Subject: [PATCH] decision structure --- ForkliftAgent.py | 80 +++++++++++++------------- Generator.py => InitialStateFactory.py | 17 +++--- data/Game.py | 37 ------------ data/GameConstants.py | 15 +++++ decision/ActionType.py | 13 +++++ decision/State.py | 22 +++++++ decision/StateTree.py | 25 ++++++++ main.py | 27 ++++----- test/nastepnik.py | 28 ++++----- util/TWOJSTARY.py | 27 --------- 10 files changed, 152 insertions(+), 139 deletions(-) rename Generator.py => InitialStateFactory.py (67%) delete mode 100644 data/Game.py create mode 100644 data/GameConstants.py create mode 100644 decision/ActionType.py create mode 100644 decision/State.py create mode 100644 decision/StateTree.py delete mode 100644 util/TWOJSTARY.py diff --git a/ForkliftAgent.py b/ForkliftAgent.py index cee713c..9162587 100644 --- a/ForkliftAgent.py +++ b/ForkliftAgent.py @@ -11,48 +11,48 @@ class ForkliftAgent(AgentBase): def __init__(self, model): super().__init__(model) - self.movement_queue = [Tuple[int, int]] - self.current_position = Tuple[int, int] + # self.movement_queue = [Tuple[int, int]] + # self.current_position = Tuple[int, int] self.current_rotation = Direction.right - def assign_new_movement_task(self, movement_list): - self.movement_queue = [] - - for m in movement_list: - self.movement_queue.append(m) - - print("Assigned new movement queue to forklift agent") - - def get_proper_rotation(self, next_pos: Tuple[int, int]) -> Direction: - - if next_pos[0] < self.current_position[0]: - return Direction.left - elif next_pos[0] > self.current_position[0]: - return Direction.right - elif next_pos[1] > self.current_position[1]: - return Direction.top - elif next_pos[1] < self.current_position[1]: - return Direction.down - elif next_pos == self.current_position: - return self.current_rotation - - def move(self): - if len(self.movement_queue) > 0: - next_pos = self.movement_queue.pop(0) - - dir = self.get_proper_rotation(next_pos) - - if dir == self.current_rotation: - print("move {} --> {}".format(self.current_position, next_pos)) - self.current_position = next_pos - else: - print("rotate {} --> {}".format(self.current_rotation, dir)) - self.current_rotation = dir - self.movement_queue.insert(0, next_pos) - - def step(self) -> None: - print("forklift step") - self.move() + # def assign_new_movement_task(self, movement_list): + # self.movement_queue = [] + # + # for m in movement_list: + # self.movement_queue.append(m) + # + # print("Assigned new movement queue to forklift agent") + # + # def get_proper_rotation(self, next_pos: Tuple[int, int]) -> Direction: + # + # if next_pos[0] < self.current_position[0]: + # return Direction.left + # elif next_pos[0] > self.current_position[0]: + # return Direction.right + # elif next_pos[1] > self.current_position[1]: + # return Direction.top + # elif next_pos[1] < self.current_position[1]: + # return Direction.down + # elif next_pos == self.current_position: + # return self.current_rotation + # + # def move(self): + # if len(self.movement_queue) > 0: + # next_pos = self.movement_queue.pop(0) + # + # dir = self.get_proper_rotation(next_pos) + # + # if dir == self.current_rotation: + # print("move {} --> {}".format(self.current_position, next_pos)) + # self.current_position = next_pos + # else: + # print("rotate {} --> {}".format(self.current_rotation, dir)) + # self.current_rotation = dir + # self.movement_queue.insert(0, next_pos) + # + # def step(self) -> None: + # print("forklift step") + # self.move() def creation_log(self): print("Created Forklift Agent [id: {}]".format(self.unique_id)) diff --git a/Generator.py b/InitialStateFactory.py similarity index 67% rename from Generator.py rename to InitialStateFactory.py index a05e805..c354625 100644 --- a/Generator.py +++ b/InitialStateFactory.py @@ -1,22 +1,22 @@ import random + from data.Item import Item from data.ItemType import ItemType from data.Order import Order -class Generator: - def __init__(self, input_sequence_size: int, output_order_list_size: int): - self.input_sequence = self.generate_input_sequence(input_sequence_size) - self.output_order_list = self.generate_order_list(output_order_list_size) +class InitialStateFactory: + @staticmethod def generate_order_list(self, output_order_list_size: int): order_list = [Order] for i in range(0, output_order_list_size): - order_list.append(self.generate_order()) + order_list.append(self.__generate_order()) return order_list - def generate_order(self) -> Order: + @staticmethod + def __generate_order(self) -> Order: order_size = random.randint(1, 4) items = [Item] @@ -30,14 +30,15 @@ class Generator: return Order(final_time, items, value) + @staticmethod def generate_input_sequence(self, input_sequence_size): sequence = [Item] for i in range(0, input_sequence_size): - sequence.append(self.generate_item()) + sequence.append(self.__generate_item()) return sequence @staticmethod - def generate_item() -> Item: + def __generate_item() -> Item: randomly_picked_type = random.choice(list(ItemType)) return Item(randomly_picked_type) diff --git a/data/Game.py b/data/Game.py deleted file mode 100644 index 92de383..0000000 --- a/data/Game.py +++ /dev/null @@ -1,37 +0,0 @@ -from data import Direction -from data.ItemType import ItemType -from data.Item import Item -from data.Order import Order -from typing import Dict - -class Game: - def __init__(self, id: int, agentPos: (int, int), agentDirection: Direction, deliveryPos: (int, int), orderPos: (int,int), stockPilePos: Dict, - deliveryItem: Item, carriedItem: Item, orderStock: Dict, orderList: [Order]): - self.agentDirection = agentDirection - self.id = id - self.agentPos = agentPos - self.deliveryPos = deliveryPos - self.orderPos = orderPos - self.stockPilePos = stockPilePos - self.deliveryItem = deliveryItem - self.carriedItem = carriedItem - self.orderStock = orderStock - self.orderList = orderList - - def getCopy(self): - newGame = Game(self) - return newGame - # def move(self, x: int, y: int): - # self.agentPos = (x, y) - # - # def pickUp(self, item: Item): - # self.deliveryItem = item - # - # def drop(self, item: Item): - # self.deliveryItem = -1 - # - # def identify(item: Item, category: CATEGORY): - # item.category = category - # - # def finishOrder(order: Order): - # order.id = -1 \ No newline at end of file diff --git a/data/GameConstants.py b/data/GameConstants.py new file mode 100644 index 0000000..bdfd898 --- /dev/null +++ b/data/GameConstants.py @@ -0,0 +1,15 @@ +from typing import Dict + +from data.ItemType import ItemType +from util.PathDefinitions import GridLocation + + +class GameConstants: + def __init__(self, grid_width: int, grid_height: int, delivery_pos: GridLocation, order_pos: GridLocation, + special_positions: Dict[ItemType, GridLocation], walls: [GridLocation]): + self.grid_width = grid_width + self.grid_height = grid_height + self.delivery_pos = delivery_pos + self.order_pos = order_pos + self.special_positions = special_positions + self.walls = walls diff --git a/decision/ActionType.py b/decision/ActionType.py new file mode 100644 index 0000000..d088153 --- /dev/null +++ b/decision/ActionType.py @@ -0,0 +1,13 @@ +from enum import Enum + + +class ActionType(Enum): + MOVE = 1 + ROTATE_RIGHT = 2 + ROTATE_DOWN = 3 + ROTATE_LEFT = 4 + ROTATE_UP = 5 + PICK_ITEM = 6 + DROP_ITEM = 7 + SPECIAL = 8 + NONE = 9 diff --git a/decision/State.py b/decision/State.py new file mode 100644 index 0000000..70dcb34 --- /dev/null +++ b/decision/State.py @@ -0,0 +1,22 @@ +from data.Direction import Direction +from data.Item import Item +from data.Order import Order +from decision.ActionType import ActionType +from util.PathDefinitions import GridLocation + + +class State: + def __init__(self, + action_taken: ActionType, + forklift_position: GridLocation, + forklift_rotation: Direction, + pending_orders: [Order], + filled_orders: [Order], + input_items: [Item] + ): + self.action_taken = action_taken + self.forklift_position = forklift_position + self.forklift_rotation = forklift_rotation + self.pending_orders = pending_orders + self.filled_orders = filled_orders + self.input_items = input_items diff --git a/decision/StateTree.py b/decision/StateTree.py new file mode 100644 index 0000000..944730b --- /dev/null +++ b/decision/StateTree.py @@ -0,0 +1,25 @@ +from typing import List + +from InitialStateFactory import InitialStateFactory +from data.GameConstants import GameConstants +from decision.ActionType import ActionType +from decision.State import State +from util.PathDefinitions import GridLocation + + +class StateTree: + + def __init__(self, initial_state_factory: InitialStateFactory, game_constants: GameConstants, + initial_forklift_position: GridLocation): + self.game_constants = game_constants + + parent = State( + action_taken=ActionType.NONE, + forklift_position=initial_forklift_position, + pending_orders=initial_state_factory.generate_order_list(5), + filled_orders=[], + input_items=initial_state_factory.generate_input_sequence(20) + ) + + def expansion(self, from_state: State) -> List[State]: + return [] diff --git a/main.py b/main.py index d5babf9..cd5d0a8 100644 --- a/main.py +++ b/main.py @@ -49,19 +49,20 @@ def agent_portrayal(agent): return portrayal -base = 512 -gridWidth = 10 -gridHeight = 10 -scale = base / gridWidth +if __name__ == '__main__': + base = 512 + gridWidth = 10 + gridHeight = 10 + scale = base / gridWidth -diagram4 = GridWithWeights(gridWidth, gridHeight) -diagram4.walls = [(5, 5), (5, 6)] + diagram4 = GridWithWeights(gridWidth, gridHeight) + diagram4.walls = [(6, 5), (6, 6), (6, 7), (6, 8), (2, 3), (2, 4)] -grid = CanvasGrid(agent_portrayal, gridWidth, gridHeight, scale * gridWidth, scale * gridHeight) + grid = CanvasGrid(agent_portrayal, gridWidth, gridHeight, scale * gridWidth, scale * gridHeight) -server = ModularServer(GameModel, - [grid], - "Automatyczny Wózek Widłowy", - {"width": gridHeight, "height": gridWidth, "graph": diagram4}) -server.port = 8888 -server.launch() + server = ModularServer(GameModel, + [grid], + "Automatyczny Wózek Widłowy", + {"width": gridHeight, "height": gridWidth, "graph": diagram4}) + server.port = 8888 + server.launch() diff --git a/test/nastepnik.py b/test/nastepnik.py index 8c36f6d..800d054 100644 --- a/test/nastepnik.py +++ b/test/nastepnik.py @@ -1,36 +1,36 @@ from enum import Enum from typing import Tuple, Dict -from data import Game, Direction +from data import GameConstants, Direction -def getHotSpot(game:Game) -> (int, int): +def getHotSpot(game:GameConstants) -> (int, int): pass -def isOrderReady(game:Game) -> bool: +def isOrderReady(game:GameConstants) -> bool: pass -def getReadyOrderId(game:Game) -> int: +def getReadyOrderId(game:GameConstants) -> int: pass class Action(): - def __init__(self, game: Game): - self.game = Game + def __init__(self, game: GameConstants): + self.game = GameConstants - def rotate(self, direction: Direction) -> Game: + def rotate(self, direction: Direction) -> GameConstants: self.game.agentDirection = direction pass - def move(self) -> Game: + def move(self) -> GameConstants: # w zaleznosci od kierunku napierdala do przodu pass - def special(self) -> Game: + def special(self) -> GameConstants: # w zaleznosci od miejsca gdzie jest i czy ma cos na lapie odklada albo bierze przedmiot pass - def orderOut(self, orderId: int) -> Game: + def orderOut(self, orderId: int) -> GameConstants: # nalicza punkty wypierdalaorder i czysci orderStock pass @@ -52,7 +52,7 @@ def getRotationEvaluation(direction: Direction): # get evaluationForMoveAfterRotation return 1.0 -def evaluateMoves(game: Game) -> Dict: +def evaluateMoves(game: GameConstants) -> Dict: posibleMoves = Dict currPos = game.agentPos gameCopy = game.getCopy() @@ -77,12 +77,12 @@ def getMaxFromList(list: [float]) -> float: return maxi -def getBestPossibleMove(game: Game) -> PossibleMoves: +def getBestPossibleMove(game: GameConstants) -> PossibleMoves: movesDict = evaluateMoves() bestChoice = getMaxFromList(movesDict.values()) return getIndex(bestChoice, movesDict) -def getBestMove(game: Game) -> Game: +def getBestMove(game: GameConstants) -> GameConstants: gameCopy = game.getCopy() bestPossibleMove = getBestPossibleMove(gameCopy) @@ -99,7 +99,7 @@ def getBestMove(game: Game) -> Game: -def nastepnik(game: Game) -> Game: +def nastepnik(game: GameConstants) -> GameConstants: if isOrderReady(game) > -1: return Action(game.getCopy()).orderOut(getReadyOrderId(game)) elif game.agentPos == getHotSpot(game): diff --git a/util/TWOJSTARY.py b/util/TWOJSTARY.py deleted file mode 100644 index a0d9d8a..0000000 --- a/util/TWOJSTARY.py +++ /dev/null @@ -1,27 +0,0 @@ -from data import Game, Order - - -def pickBestOrder(game: Game) -> Order: - maxi = game.orderList[0] - for i in range(len(game.orderList)): - if(game.orderList[i].money > maxi.money): - maxi = game.orderList[i] - - return maxi - -def realizeOrder(game: Game, orderId: int): - return 1 - -def getCorrectStockPile(game: Game) -> (int, int): - return game.stockPilePos[game.carriedItem.category].pos - -def TwojStary(game: Game) -> (int, int): - if len(game.orderList) == 0: - if game.carriedItem is None: - return game.deliveryPos - else: - return getCorrectStockPile(game) - elif game.carriedItem is None: - return realizeOrder(game, pickBestOrder(game)) - else: - return getCorrectStockPile(game) \ No newline at end of file