mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-15 23:59:33 +00:00
85def73bd951f8cd0023a7c70281fd22bcd0669e
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
33810e41c5 |
Optimize edge lookup railnetwork (#2493)
## Description:
This PR optimizes how the rail network looks up railroads connecting two
stations by introducing an O(1) neighbor→railroad map on `TrainStation`.
It also updates `getOrientedRailroad` and railroad deletion to use this
new API, avoiding repeated linear scans over all railroads attached to a
station.
### What changed
- **TrainStation neighbor→railroad index**
- Added `railroadByNeighbor: Map<TrainStation, Railroad>` to
`TrainStation` for quick edge lookup.
- Kept `railroads: Set<Railroad>` for iteration and existing APIs.
- Updated lifecycle methods to keep both data structures in sync:
- `addRailroad(railRoad: Railroad)` now:
- Adds to `railroads`.
- Computes the neighbor station (`railRoad.from === this ? railRoad.to :
railRoad.from`).
- Stores the mapping in `railroadByNeighbor`.
- `removeRailroad(railRoad: Railroad)` now:
- Removes from `railroads`.
- Removes the corresponding entry from `railroadByNeighbor`.
- `clearRailroads()` now clears both `railroads` and
`railroadByNeighbor`.
- Added `getRailroadTo(station: TrainStation): Railroad | null` to
retrieve the connecting railroad in O(1).
- **Use the new API in `TrainStation` and `Railroad`**
- `TrainStation.removeNeighboringRails(station)` now calls
`removeRailroad(toRemove)` instead of manually deleting from the set,
ensuring the map stays in sync.
- `Railroad.delete(game)` now calls `from.removeRailroad(this)` and
`to.removeRailroad(this)` instead of mutating the sets directly.
- **Refactor `getOrientedRailroad` to use O(1) lookup**
- Replaced a linear scan over `from.getRailroads()` with a direct
lookup:
```ts
export function getOrientedRailroad(
from: TrainStation,
to: TrainStation,
): OrientedRailroad | null {
const railroad = from.getRailroadTo(to);
if (!railroad) return null;
// If tiles are stored from -> to, we go forward when railroad.to === to
const forward = railroad.to === to;
return new OrientedRailroad(railroad, forward);
}
```
- Behavior is preserved:
- `getRailroadTo` returns the same `Railroad` instance that was
previously found by scanning `getRailroads()`.
- Direction (`forward` vs reversed) is still derived from the
`Railroad.from` / `.to` fields in the same way as before.
### Motivation
- `getOrientedRailroad` and upcoming logic both need to resolve “the
railroad between station A and station B” frequently.
- The old pattern (`for (const railroad of from.getRailroads()) { ...
}`) was:
- O(degree) per lookup,
- Repeated in multiple places,
- Harder to maintain as more features (like fare-based costs) touch this
code.
- Centralizing edge lookup in a dedicated `railroadByNeighbor` map makes
this:
- **O(1)** per lookup,
- Less error-prone (one source of truth),
- Easier to reuse from new systems (e.g. train pathfinding, fare-aware
logic).
### Impact / Risk
- **Public behavior:** No functional change in how railroads are
created, deleted, or oriented; only the lookup mechanism changed.
- **Internal invariants:** Correctness relies on:
- All railroad creations using `addRailroad` on both endpoints (already
true via `RailNetworkImpl.connect`).
- All removals (`Railroad.delete`,
`TrainStation.removeNeighboringRails`, `disconnectFromNetwork`) using
`removeRailroad` / `clearRailroads`, which this PR updates.
- **Tests:** Existing `TrainStation` tests still pass; they exercise
`addRailroad`, `removeNeighboringRails`, and `getRailroads()`, which
continue to behave the same from the outside.
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
DISCORD_USERNAME
|
||
|
|
43397779fa |
Add trains (#1159)
## Description: Add a rail network to handle train stations/railroad between structures. Changes: - `RailNetwork` is responsible for the train station graph. Use it to connect new `TrainStations` - A `RailRoad` connects two `TrainStation` - No loop possible in the rail network - Train stations handles its railroads - Added a layer to draw the railroads under the structures #### Clusters - To speed up computations, each `TrainStation` references its own cluster - A cluster is a list of `TrainStation` connected with each other, created by the `RailNetwork` when connecting the station - Train stations spawn trains randomly depending on its current cluster size - A `TrainStation` decides randomly of the train destination by picking one from the cluster #### Production building: - Added a factory which has no gameplay impact currently. _To be discussed._ #### Train stops: - When a train reaches a factory, it's filled with a "cargo". The loaded trains has no impact currently. _To be discussed._ - When a train reaches a city, the player earn 10k gold - When a train reaches a port, it sends a new tradeship if possible - If a destination/source is destroyed, the train & railroad are deleted too https://github.com/user-attachments/assets/42375c17-9e04-4a42-98d0-708c81ffd609 https://github.com/user-attachments/assets/fbecdb53-a516-4df8-87fb-1f9a62c4efa0 ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: IngloriousTom --------- Co-authored-by: Scott Anderson <scottanderson@users.noreply.github.com> |