mirror of
https://github.com/illiumst/marl-factory-grid.git
synced 2025-07-05 17:11:35 +02:00
new rules, new spawn logic, small fixes, default and narrow corridor debugged
This commit is contained in:
@ -1,4 +1,3 @@
|
||||
from .actions import ItemAction
|
||||
from .entitites import Item, DropOffLocation
|
||||
from .groups import DropOffLocations, Items, Inventory, Inventories
|
||||
from .rules import ItemRules
|
||||
|
@ -29,7 +29,7 @@ class ItemAction(Action):
|
||||
elif items := state[i.ITEM].by_pos(entity.pos):
|
||||
item = items[0]
|
||||
item.change_parent_collection(inventory)
|
||||
item.set_pos_to(c.VALUE_NO_POS)
|
||||
item.set_pos(c.VALUE_NO_POS)
|
||||
state.print(f'{entity.name} just picked up an item at {entity.pos}')
|
||||
return ActionResult(entity=entity, identifier=self._identifier, validity=c.VALID, reward=r.PICK_UP_VALID)
|
||||
|
||||
|
@ -8,16 +8,11 @@ from marl_factory_grid.modules.items import constants as i
|
||||
|
||||
class Item(Entity):
|
||||
|
||||
@property
|
||||
def var_can_collide(self):
|
||||
return False
|
||||
|
||||
def render(self):
|
||||
return RenderEntity(i.ITEM, self.pos) if self.pos != c.VALUE_NO_POS else None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._auto_despawn = -1
|
||||
|
||||
@property
|
||||
def auto_despawn(self):
|
||||
@ -31,9 +26,6 @@ class Item(Entity):
|
||||
def set_auto_despawn(self, auto_despawn):
|
||||
self._auto_despawn = auto_despawn
|
||||
|
||||
def set_pos_to(self, no_pos):
|
||||
self._pos = no_pos
|
||||
|
||||
def summarize_state(self) -> dict:
|
||||
super_summarization = super(Item, self).summarize_state()
|
||||
super_summarization.update(dict(auto_despawn=self.auto_despawn))
|
||||
@ -42,21 +34,6 @@ class Item(Entity):
|
||||
|
||||
class DropOffLocation(Entity):
|
||||
|
||||
@property
|
||||
def var_can_collide(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def var_can_move(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def var_is_blocking_light(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def var_has_position(self):
|
||||
return True
|
||||
|
||||
def render(self):
|
||||
return RenderEntity(i.DROP_OFF, self.pos)
|
||||
|
@ -8,6 +8,7 @@ from marl_factory_grid.environment.groups.objects import _Objects
|
||||
from marl_factory_grid.environment.groups.mixins import IsBoundMixin
|
||||
from marl_factory_grid.environment.entity.agent import Agent
|
||||
from marl_factory_grid.modules.items.entitites import Item, DropOffLocation
|
||||
from marl_factory_grid.utils.results import Result
|
||||
|
||||
|
||||
class Items(Collection):
|
||||
@ -15,7 +16,7 @@ class Items(Collection):
|
||||
|
||||
@property
|
||||
def var_has_position(self):
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_blocking_light(self):
|
||||
@ -28,18 +29,18 @@ class Items(Collection):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def trigger_item_spawn(state, n_items, spawn_frequency):
|
||||
if item_to_spawns := max(0, (n_items - len(state[i.ITEM]))):
|
||||
position_list = [x for x in state.entities.floorlist]
|
||||
shuffle(position_list)
|
||||
position_list = state.entities.floorlist[:item_to_spawns]
|
||||
state[i.ITEM].spawn(position_list)
|
||||
state.print(f'{item_to_spawns} new items have been spawned; next spawn in {spawn_frequency}')
|
||||
return len(position_list)
|
||||
def trigger_spawn(self, state, *entity_args, coords_or_quantity=None, **entity_kwargs) -> [Result]:
|
||||
coords_or_quantity = coords_or_quantity if coords_or_quantity else self._coords_or_quantity
|
||||
assert coords_or_quantity
|
||||
|
||||
if item_to_spawns := max(0, (coords_or_quantity - len(self))):
|
||||
return super().trigger_spawn(state,
|
||||
*entity_args,
|
||||
coords_or_quantity=item_to_spawns,
|
||||
**entity_kwargs)
|
||||
else:
|
||||
state.print('No Items are spawning, limit is reached.')
|
||||
return 0
|
||||
return Result(identifier=f'{self.name}_spawn', validity=c.NOT_VALID, value=coords_or_quantity)
|
||||
|
||||
|
||||
class Inventory(IsBoundMixin, Collection):
|
||||
@ -76,9 +77,15 @@ class Inventory(IsBoundMixin, Collection):
|
||||
class Inventories(_Objects):
|
||||
_entity = Inventory
|
||||
|
||||
var_can_move = False
|
||||
var_has_position = False
|
||||
|
||||
|
||||
symbol = None
|
||||
|
||||
@property
|
||||
def var_can_move(self):
|
||||
return False
|
||||
def spawn_rule(self):
|
||||
return {c.SPAWN_ENTITY_RULE: dict(collection=self, coords_or_quantity=None)}
|
||||
|
||||
def __init__(self, size: int, *args, **kwargs):
|
||||
super(Inventories, self).__init__(*args, **kwargs)
|
||||
@ -86,10 +93,12 @@ class Inventories(_Objects):
|
||||
self._obs = None
|
||||
self._lazy_eval_transforms = []
|
||||
|
||||
def spawn(self, agents):
|
||||
inventories = [self._entity(agent, self.size, )
|
||||
for _, agent in enumerate(agents)]
|
||||
self.add_items(inventories)
|
||||
def spawn(self, agents, *args, **kwargs):
|
||||
self.add_items([self._entity(agent, self.size, *args, **kwargs) for _, agent in enumerate(agents)])
|
||||
return [Result(identifier=f'{self.name}_spawn', validity=c.VALID, value=len(self))]
|
||||
|
||||
def trigger_spawn(self, state, *args, **kwargs) -> [Result]:
|
||||
return self.spawn(state[c.AGENT], *args, **kwargs)
|
||||
|
||||
def idx_by_entity(self, entity):
|
||||
try:
|
||||
@ -106,9 +115,6 @@ class Inventories(_Objects):
|
||||
def summarize_states(self, **kwargs):
|
||||
return [val.summarize_states(**kwargs) for key, val in self.items()]
|
||||
|
||||
@staticmethod
|
||||
def trigger_inventory_spawn(state):
|
||||
state[i.INVENTORY].spawn(state[c.AGENT])
|
||||
|
||||
|
||||
class DropOffLocations(Collection):
|
||||
@ -135,7 +141,7 @@ class DropOffLocations(Collection):
|
||||
|
||||
@staticmethod
|
||||
def trigger_drop_off_location_spawn(state, n_locations):
|
||||
empty_positions = state.entities.empty_positions()[:n_locations]
|
||||
empty_positions = state.entities.empty_positions[:n_locations]
|
||||
do_entites = state[i.DROP_OFF]
|
||||
drop_offs = [DropOffLocation(pos) for pos in empty_positions]
|
||||
do_entites.add_items(drop_offs)
|
||||
|
@ -6,52 +6,28 @@ from marl_factory_grid.utils.results import TickResult
|
||||
from marl_factory_grid.modules.items import constants as i
|
||||
|
||||
|
||||
class ItemRules(Rule):
|
||||
class RespawnItems(Rule):
|
||||
|
||||
def __init__(self, n_items: int = 5, spawn_frequency: int = 15,
|
||||
n_locations: int = 5, max_dropoff_storage_size: int = 0):
|
||||
def __init__(self, n_items: int = 5, respawn_freq: int = 15, n_locations: int = 5):
|
||||
super().__init__()
|
||||
self.spawn_frequency = spawn_frequency
|
||||
self._next_item_spawn = spawn_frequency
|
||||
self.spawn_frequency = respawn_freq
|
||||
self._next_item_spawn = respawn_freq
|
||||
self.n_items = n_items
|
||||
self.max_dropoff_storage_size = max_dropoff_storage_size
|
||||
self.n_locations = n_locations
|
||||
|
||||
def on_init(self, state, lvl_map):
|
||||
state[i.DROP_OFF].trigger_drop_off_location_spawn(state, self.n_locations)
|
||||
self._next_item_spawn = self.spawn_frequency
|
||||
state[i.INVENTORY].trigger_inventory_spawn(state)
|
||||
state[i.ITEM].trigger_item_spawn(state, self.n_items, self.spawn_frequency)
|
||||
|
||||
def tick_step(self, state):
|
||||
for item in list(state[i.ITEM].values()):
|
||||
if item.auto_despawn >= 1:
|
||||
item.set_auto_despawn(item.auto_despawn - 1)
|
||||
elif not item.auto_despawn:
|
||||
state[i.ITEM].delete_env_object(item)
|
||||
else:
|
||||
pass
|
||||
|
||||
if not self._next_item_spawn:
|
||||
state[i.ITEM].trigger_item_spawn(state, self.n_items, self.spawn_frequency)
|
||||
state[i.ITEM].trigger_spawn(state, self.n_items, self.spawn_frequency)
|
||||
else:
|
||||
self._next_item_spawn = max(0, self._next_item_spawn - 1)
|
||||
return []
|
||||
|
||||
def tick_post_step(self, state) -> List[TickResult]:
|
||||
for item in list(state[i.ITEM].values()):
|
||||
if item.auto_despawn >= 1:
|
||||
item.set_auto_despawn(item.auto_despawn-1)
|
||||
elif not item.auto_despawn:
|
||||
state[i.ITEM].delete_env_object(item)
|
||||
else:
|
||||
pass
|
||||
|
||||
if not self._next_item_spawn:
|
||||
if spawned_items := state[i.ITEM].trigger_item_spawn(state, self.n_items, self.spawn_frequency):
|
||||
return [TickResult(self.name, validity=c.VALID, value=spawned_items, entity=None)]
|
||||
if spawned_items := state[i.ITEM].trigger_spawn(state, self.n_items, self.spawn_frequency):
|
||||
return [TickResult(self.name, validity=c.VALID, value=spawned_items.value)]
|
||||
else:
|
||||
return [TickResult(self.name, validity=c.NOT_VALID, value=0, entity=None)]
|
||||
return [TickResult(self.name, validity=c.NOT_VALID, value=0)]
|
||||
else:
|
||||
self._next_item_spawn = max(0, self._next_item_spawn-1)
|
||||
return []
|
||||
|
Reference in New Issue
Block a user