# Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. """ Data models for the Container Yard Environment. The Container Yard environment simulates a port container yard where containers arrive sequentially and must be placed into stacks to minimize rehandles during retrieval operations. """ from typing import List, Optional from openenv.core.env_server.types import Action, Observation from pydantic import Field class Container: """Represents a single container with ID and priority.""" def __init__(self, container_id: int, priority: int): self.container_id = container_id priority_map = {1: 0, 2: 1, 3: 2} # 1=earliest (0), 3=latest (2) self.retrieval_priority = priority_map.get(priority, 0) def __repr__(self): return f"C{self.container_id}(P{self.retrieval_priority})" class ContainerYardAction(Action): """Action to place a container in a specific stack.""" stack_index: int = Field(..., description="Index of the stack to place container in (0-9)") class ContainerYardObservation(Observation): """Observation of the current container yard state.""" stacks: List[List[int]] = Field( default_factory=list, description="Current state of stacks (container IDs, -1 means empty slot)" ) containers_placed: int = Field(default=0, description="Number of containers placed so far") total_containers: int = Field(default=0, description="Total containers in this episode") current_container_id: int = Field(default=-1, description="ID of current container to place (-1 if done)") current_container_priority: int = Field(default=0, description="Priority of current container (1-3)") rehandles_so_far: int = Field(default=0, description="Total rehandles occurred so far") num_stacks: int = Field(default=10, description="Number of stacks in the yard") max_stack_height: int = Field(default=5, description="Maximum height of each stack") action_error: Optional[str] = Field(default=None, description="Error message if last action failed")