#优化 #18xx #图形

navig18xx

构建 18xx 地块和地图,并寻找最佳路线组合

1 个不稳定版本

0.1.0 2021 年 10 月 8 日

#12 in #18xx


rusty-train 中使用

MIT/Apache

1MB
18K SLoC

概述

一个用于处理 18xx 地块和地图的 crate,并搜索具有最佳收益的火车路线。

当前状态

以下功能已实现

  • 定义大多数 18xx 地块的能力。
  • 在屏幕上绘制地块并将图像保存到磁盘。
  • 序列化和反序列化地块描述。
  • 在标记空间中放置标记。
  • 定义和操作 18xx 游戏地图。
  • 选择公司运行的路线。
  • 选择公司的路线奖金。
  • 在地图上搜索最佳火车与路线配对。

支持的游戏

以下游戏的地图、地块和火车已实现

  • 1830:铁路与强盗大亨
  • 1861:俄罗斯帝国的铁路
  • 1867:加拿大的铁路

定义地块

使用 Tile 数据结构。这使用了由 Cairo 绑定 提供的 Gtk-rs 项目。

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");

更复杂的地块,具有多个标记空间和重叠的轨道,可以以相同的方式定义。例如,以下是地块 45X5 的定义

#
#
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");

依赖关系

~8–12MB
~242K SLoC