use navig18xx::prelude::*;
mod output;
type Result = std::result::Result<(), Box<dyn std::error::Error>>;
#[test]
fn test_draw_tiles() -> Result {
let json_dir = output::Dir::Examples;
let output_dir = output::Dir::Examples;
let try_files = vec![
("tile_catalogue.json", 8, 16, Orientation::FlatTop),
("tile_1830.json", 8, 13, Orientation::PointedTop),
("tile_1861.json", 8, 16, Orientation::FlatTop),
("tile_1867.json", 8, 16, Orientation::FlatTop),
];
for (basename, rows, cols, orientation) in &try_files {
let json_file = json_dir.join(basename);
if !json_file.exists() {
println!("{} not found", json_file.to_str().unwrap());
continue;
}
let png_basename =
std::path::Path::new(basename).with_extension("png");
let png_file = output_dir.join(png_basename);
draw_tiles(&json_file, png_file, *rows, *cols, *orientation)?;
}
Ok(())
}
fn main() -> Result {
let output_dir = output::Dir::Root;
let mut rows: usize = 6;
let mut cols: usize = 14;
let mut orientation = Orientation::FlatTop;
let mut json_files: Vec<String> = vec![];
let mut args = std::env::args();
args.next();
while let Some(arg) = args.next() {
match arg.as_str() {
"-h" | "--help" => {
print_usage();
return Ok(());
}
"-r" => {
if let Some(row_str) = args.next() {
rows = row_str.parse::<usize>()?
} else {
panic!("Missing argument for {}", arg)
}
}
"-c" => {
if let Some(row_str) = args.next() {
cols = row_str.parse::<usize>()?
} else {
panic!("Missing argument for {}", arg)
}
}
"-f" => {
orientation = Orientation::FlatTop;
}
"-p" => {
orientation = Orientation::PointedTop;
}
_ => json_files.push(arg),
}
}
if json_files.is_empty() {
println!("ERROR: No input files given");
print_usage();
return Ok(());
}
for json_file in &json_files {
let png_basename =
std::path::Path::new(json_file).with_extension("png");
let png_file = output_dir.join(png_basename);
draw_tiles(json_file, png_file, rows, cols, orientation)?;
}
Ok(())
}
fn draw_tiles<P: AsRef<std::path::Path>>(
json_file: P,
png_file: std::path::PathBuf,
rows: usize,
cols: usize,
orientation: Orientation,
) -> Result {
let hex_max_diameter = 125.0;
let mut hex = Hex::new(hex_max_diameter);
hex.set_orientation(orientation);
let margin = 10;
let bg_rgba = Some(Colour::WHITE);
let json_str = json_file.as_ref().to_str().unwrap();
println!("Reading {} ...", json_str);
let tiles = read_tiles(json_file)?;
let example = place_tiles(hex, &tiles, rows, cols);
example.draw_map();
println!("Writing {} ...", png_file.to_str().unwrap());
example.write_png(margin, bg_rgba, png_file);
Ok(())
}
fn print_usage() {
println!();
println!("draw_tiles [-c COLS] [-r ROWS] [-f|-p] JSON_FILES");
println!();
println!(" -c COLS The number of tile columns");
println!(" -r ROWS The number of tile rows");
println!(" -f Orient tiles so the top is flat (default)");
println!(" -p Orient tiles so the top is pointed");
println!(" JSON_FILES The tile JSON file(s) to draw");
println!();
}
fn place_tiles(
hex: Hex,
tiles: &[Tile],
rows: usize,
cols: usize,
) -> Example {
let tile_names = tiles.iter().map(|t| &t.name).cycle();
let coords = Coordinates {
orientation: hex.orientation(),
letters: Letters::AsColumns,
first_row: FirstRow::OddColumns,
};
let mut tile_addrs: Vec<String> = vec![];
let rows: Vec<isize> = (0..rows as isize).collect();
let cols: Vec<isize> = (0..cols as isize).collect();
for row in &rows {
for col in &cols {
let addr = HexAddress::new(*row, *col);
let addr_string = coords.format(&addr).unwrap();
tile_addrs.push(addr_string)
}
}
let placed_tiles: Vec<_> = tile_addrs
.iter()
.zip(tile_names)
.map(|(addr, name)| tile_at(name, addr))
.collect();
let tokens: Vec<(String, _)> = vec![];
Example::new_catalogue(hex, tokens, placed_tiles, tiles.to_vec(), coords)
}