1 unstable release
0.1.0 | Oct 8, 2021 |
---|
#8 in #optimisation
Used in rusty-train
1MB
18K
SLoC
Overview
A crate for working with 18xx tiles and maps, and searching for train routes with optimal revenue.
Current status
The following features are implemented:
- Ability to define most 18xx tiles.
- Drawing tiles on-screen and saving images to disk.
- (De)serialising tile descriptions.
- Placing tokens in token spaces.
- Defining and manipulating 18xx game maps.
- Selecting trains to operate routes for a company.
- Selecting route bonuses for a company.
- Searching maps for optimal pairings of trains to routes.
Supported games
Maps, tiles, and trains for the following games are implemented:
- 1830: Railways and Robber Barons
- 1861: The Railways of the Russian Empire
- 1867: The Railways of Canada
Defining tiles
Use the Tile
data
structure.
This uses the Cairo bindings provided by
the Gtk-rs project.
use navig18xx::prelude::*;
// Define the basic tile geometry.
let hex_max_diameter = 125.0;
let hex = Hex::new(hex_max_diameter);
// Create a tile that contains two track segments and a dit.
let tile = Tile::new(
HexColour::Yellow,
"3",
vec![
Track::hard_l(HexFace::Bottom)
.with_span(0.0, 0.5)
.with_dit(TrackEnd::End, 10, DitShape::Bar),
Track::hard_l(HexFace::Bottom).with_span(0.5, 1.0),
],
vec![],
&hex,
);
// Save this tile to a JSON file.
let pretty_json = true;
write_tile("tile_3.json", &tile, pretty_json);
tile.save_png(&hex, "tile_3.png")
.expect("Could not save tile as a PNG");
More complex tiles, with multiple token spaces and overlapping tracks, can be defined in the same way. For example, here are definitions of tiles 45 and X5:
#
#
let tile_45 = Tile::new(
HexColour::Brown,
"45",
vec![
Track::gentle_l(HexFace::UpperLeft),
Track::hard_r(HexFace::Top),
Track::gentle_r(HexFace::Bottom),
Track::straight(HexFace::Bottom),
],
vec![],
&hex,
);
let tile_x5 = Tile::new(
HexColour::Brown,
"X5",
vec![
Track::straight(HexFace::Top).with_span(0.0, 0.1),
Track::straight(HexFace::Top)
.with_span(0.1, 1.0)
.with_clip(0.3625, 0.75),
Track::mid(HexFace::UpperLeft),
Track::mid(HexFace::LowerLeft),
Track::mid(HexFace::LowerRight),
Track::mid(HexFace::UpperRight),
],
vec![
City::single_at_face(70, &HexFace::Top),
City::double(70).in_dir(Direction::S, 0.1),
],
&hex,
)
.label(Label::City("M".to_string()), HexCorner::BottomLeft)
.label(Label::Revenue(0), HexCorner::Left.to_centre(0.1));
tile_x5.save_png(&hex, "tile_x5.png")
.expect("Could not save tile X5 as a PNG");
tile_x5.save_svg(&hex, "tile_x5.svg")
.expect("Could not save tile X5 as an SVG");
tile_x5.save_pdf(&hex, "tile_x5.pdf")
.expect("Could not save tile X5 as a PDF");
Dependencies
~8–12MB
~244K SLoC