mirror of
https://github.com/ZGCA-Forge/Elevator.git
synced 2025-12-14 04:54:50 +00:00
Update docs
This commit is contained in:
14
README.md
14
README.md
@@ -30,20 +30,6 @@ Elevator Saga is a Python implementation of an elevator [simulation game](https:
|
||||
pip install elevator-py
|
||||
```
|
||||
|
||||
### With Development Dependencies
|
||||
|
||||
```bash
|
||||
pip install elevator-py[dev]
|
||||
```
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ZGCA-Forge/Elevator.git
|
||||
cd Elevator
|
||||
pip install -e .[dev]
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Running the Game
|
||||
|
||||
@@ -343,25 +343,6 @@ Benefits of Proxy Architecture
|
||||
5. **Separation of Concerns**: State management handled by proxies, logic in controller
|
||||
6. **Testability**: Can mock API client for unit tests
|
||||
|
||||
Performance Considerations
|
||||
--------------------------
|
||||
|
||||
Each attribute access triggers an API call. For better performance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# ❌ Inefficient - multiple API calls
|
||||
if elevator.current_floor < elevator.target_floor:
|
||||
diff = elevator.target_floor - elevator.current_floor
|
||||
|
||||
# ✅ Better - store references
|
||||
current = elevator.current_floor
|
||||
target = elevator.target_floor
|
||||
if current < target:
|
||||
diff = target - current
|
||||
|
||||
However, the API client implements **caching within a single tick**, so multiple accesses during event processing are efficient.
|
||||
|
||||
Next Steps
|
||||
----------
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ Architecture Overview
|
||||
│ api_client │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
│ GET /api/state │
|
||||
│ POST /api/step │
|
||||
│ POST /api/elevators/:id/go_to_floor │
|
||||
│ GET /api/state │
|
||||
│ POST /api/step │
|
||||
│ POST /api/elevators/:id/go_to_floor │
|
||||
│ │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -394,37 +394,37 @@ Typical communication sequence during one tick:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Client Server
|
||||
│ │
|
||||
│ 1. GET /api/state │
|
||||
├────────────────────────────────────►│
|
||||
│ ◄── SimulationState (cached) │
|
||||
│ │
|
||||
│ 2. Analyze state, make decisions │
|
||||
│ │
|
||||
│ 3. POST /api/elevators/0/go_to_floor │
|
||||
├────────────────────────────────────►│
|
||||
│ ◄── {"success": true} │
|
||||
│ │
|
||||
│ 4. GET /api/state (from cache) │
|
||||
│ No HTTP request! │
|
||||
│ │
|
||||
│ 5. POST /api/step │
|
||||
├────────────────────────────────────►│
|
||||
│ Server processes tick │
|
||||
│ - Moves elevators │
|
||||
│ - Boards/alights passengers │
|
||||
│ - Generates events │
|
||||
│ ◄── {tick: 43, events: [...]} │
|
||||
│ │
|
||||
│ 6. Process events │
|
||||
│ Cache invalidated │
|
||||
│ │
|
||||
│ 7. GET /api/state (fetches fresh) │
|
||||
├────────────────────────────────────►│
|
||||
│ ◄── SimulationState │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
Client Server
|
||||
│ │
|
||||
│ 1. GET /api/state │
|
||||
├─────────────────────────────────────►│
|
||||
│ ◄── SimulationState (cached) │
|
||||
│ │
|
||||
│ 2. Analyze state, make decisions │
|
||||
│ │
|
||||
│ 3. POST /api/elevators/0/go_to_floor│
|
||||
├─────────────────────────────────────►│
|
||||
│ ◄── {"success": true} │
|
||||
│ │
|
||||
│ 4. GET /api/state (from cache) │
|
||||
│ No HTTP request! │
|
||||
│ │
|
||||
│ 5. POST /api/step │
|
||||
├─────────────────────────────────────►│
|
||||
│ Server processes tick │
|
||||
│ - Moves elevators │
|
||||
│ - Boards/alights passengers │
|
||||
│ - Generates events │
|
||||
│ ◄── {tick: 43, events: [...]} │
|
||||
│ │
|
||||
│ 6. Process events │
|
||||
│ Cache invalidated │
|
||||
│ │
|
||||
│ 7. GET /api/state (fetches fresh) │
|
||||
├─────────────────────────────────────►│
|
||||
│ ◄── SimulationState │
|
||||
│ │
|
||||
└──────────────────────────────────────┘
|
||||
|
||||
Error Handling
|
||||
--------------
|
||||
@@ -476,23 +476,6 @@ The simulator uses a lock to ensure thread-safe access:
|
||||
|
||||
This allows Flask to handle concurrent requests safely.
|
||||
|
||||
Performance Considerations
|
||||
--------------------------
|
||||
|
||||
**Minimize HTTP Calls**:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# ❌ Bad - 3 HTTP calls
|
||||
for i in range(3):
|
||||
state = api_client.get_state()
|
||||
print(state.tick)
|
||||
|
||||
# ✅ Good - 1 HTTP call (cached)
|
||||
state = api_client.get_state()
|
||||
for i in range(3):
|
||||
print(state.tick)
|
||||
|
||||
**Batch Commands**:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -8,21 +8,21 @@ Simulation Overview
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ Simulation Loop │
|
||||
│ │
|
||||
│ Tick N │
|
||||
│ 1. Update elevator status (START_UP → CONSTANT_SPEED)│
|
||||
│ 1. Update elevator status (START_UP → CONSTANT_SPEED) │
|
||||
│ 2. Process arrivals (new passengers) │
|
||||
│ 3. Move elevators (physics simulation) │
|
||||
│ 4. Process stops (boarding/alighting) │
|
||||
│ 5. Generate events │
|
||||
│ │
|
||||
│ Events sent to client → Client processes → Commands │
|
||||
│ Events sent to client → Client processes → Commands │
|
||||
│ │
|
||||
│ Tick N+1 │
|
||||
│ (repeat...) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
|
||||
Tick-Based Execution
|
||||
--------------------
|
||||
@@ -463,27 +463,6 @@ Here's what happens in a typical tick:
|
||||
Key Timing Concepts
|
||||
-------------------
|
||||
|
||||
Command vs. Execution
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Tick 42: Controller sends command
|
||||
elevator.go_to_floor(5, immediate=False)
|
||||
# ← Command queued in elevator.next_target_floor
|
||||
|
||||
# Tick 43: Server processes
|
||||
# ← _update_elevator_status() assigns target
|
||||
# ← Elevator starts moving
|
||||
|
||||
# Tick 44-46: Elevator in motion
|
||||
# ← Events: PASSING_FLOOR
|
||||
|
||||
# Tick 47: Elevator arrives
|
||||
# ← Event: STOPPED_AT_FLOOR
|
||||
|
||||
There's a **one-tick delay** between command and execution (unless ``immediate=True``).
|
||||
|
||||
Immediate vs. Queued
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -531,47 +510,6 @@ Key metrics:
|
||||
- **System time**: ``dropoff_tick - arrive_tick`` (total time in system)
|
||||
- **P95**: 95th percentile (worst-case for most passengers)
|
||||
|
||||
Best Practices
|
||||
--------------
|
||||
|
||||
1. **React to Events**: Don't poll state - implement event handlers
|
||||
2. **Use Queued Commands**: Default ``immediate=False`` is safer
|
||||
3. **Track Passengers**: Monitor ``on_passenger_call`` to know demand
|
||||
4. **Optimize for Wait Time**: Reduce time between arrival and pickup
|
||||
5. **Consider Load**: Check ``elevator.is_full`` before dispatching
|
||||
6. **Handle Idle**: Always give idle elevators something to do (even if it's "go to floor 0")
|
||||
|
||||
Example: Efficient Dispatch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def on_passenger_call(self, passenger: ProxyPassenger, floor: ProxyFloor, direction: str) -> None:
|
||||
"""Dispatch nearest suitable elevator"""
|
||||
best_elevator = None
|
||||
best_cost = float('inf')
|
||||
|
||||
for elevator in self.elevators:
|
||||
# Skip if full
|
||||
if elevator.is_full:
|
||||
continue
|
||||
|
||||
# Calculate cost (distance + current load)
|
||||
distance = abs(elevator.current_floor - floor.floor)
|
||||
load_penalty = elevator.load_factor * 10
|
||||
cost = distance + load_penalty
|
||||
|
||||
# Check if going in right direction
|
||||
if elevator.target_floor_direction.value == direction:
|
||||
cost *= 0.5 # Prefer elevators already going that way
|
||||
|
||||
if cost < best_cost:
|
||||
best_cost = cost
|
||||
best_elevator = elevator
|
||||
|
||||
if best_elevator:
|
||||
best_elevator.go_to_floor(floor.floor)
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
|
||||
@@ -42,22 +42,6 @@ Basic Installation
|
||||
|
||||
pip install elevator-py
|
||||
|
||||
With Development Dependencies
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install elevator-py[dev]
|
||||
|
||||
From Source
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/ZGCA-Forge/Elevator.git
|
||||
cd Elevator
|
||||
pip install -e .[dev]
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user