Make maps carry real data that is both readable and writeable.
This commit is contained in:
parent
c5528d1ceb
commit
ac5d8e0c75
|
@ -45,6 +45,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
name = "coordinates"
|
name = "coordinates"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"nom",
|
||||||
"proptest",
|
"proptest",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -96,6 +97,28 @@ version = "0.2.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|
|
@ -8,3 +8,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proptest = "1.0"
|
proptest = "1.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
nom = { version = "7" }
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Seeds for failure cases proptest has generated in the past. It is
|
||||||
|
# automatically read and these particular cases re-run before any
|
||||||
|
# novel cases are generated.
|
||||||
|
#
|
||||||
|
# It is recommended to check this file in to source control so that
|
||||||
|
# everyone who runs the test benefits from these saved cases.
|
||||||
|
cc a2c4f3291703eca342388b116ee0849a96e5f977c5af22a6b5bc805edecfeb5d # shrinks to (q, r) = (0, 0), idx = 0
|
||||||
|
cc f80f4dd28944bad3a39512535e38ca3db1870c6daefd5317856f70bb58a505df # shrinks to (x, y) = (0, 0), idx = 0
|
|
@ -6,19 +6,19 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
/// An address within the hex coordinate system
|
/// An address within the hex coordinate system
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct HexAddr {
|
pub struct AxialAddr {
|
||||||
q: i32,
|
q: i32,
|
||||||
r: i32,
|
r: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HexAddr {
|
impl AxialAddr {
|
||||||
/// Create a new axial coordinate address.
|
/// Create a new axial coordinate address.
|
||||||
pub fn new(q: i32, r: i32) -> Self {
|
pub fn new(q: i32, r: i32) -> Self {
|
||||||
Self { q, r }
|
Self { q, r }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn origin() -> HexAddr {
|
pub fn origin() -> AxialAddr {
|
||||||
HexAddr { q: 0, r: 0 }
|
AxialAddr { q: 0, r: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn q(&self) -> i32 {
|
pub fn q(&self) -> i32 {
|
||||||
|
@ -34,49 +34,50 @@ impl HexAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of coordinates adjacent to this one.
|
/// Get a list of coordinates adjacent to this one.
|
||||||
pub fn adjacencies(&self) -> impl Iterator<Item = HexAddr> {
|
pub fn adjacencies(&self) -> impl Iterator<Item = AxialAddr> {
|
||||||
vec![
|
vec![
|
||||||
HexAddr::new(self.q + 1, self.r),
|
AxialAddr::new(self.q + 1, self.r),
|
||||||
HexAddr::new(self.q, self.r + 1),
|
AxialAddr::new(self.q, self.r + 1),
|
||||||
HexAddr::new(self.q - 1, self.r + 1),
|
AxialAddr::new(self.q - 1, self.r + 1),
|
||||||
HexAddr::new(self.q - 1, self.r),
|
AxialAddr::new(self.q - 1, self.r),
|
||||||
HexAddr::new(self.q, self.r - 1),
|
AxialAddr::new(self.q, self.r - 1),
|
||||||
HexAddr::new(self.q + 1, self.r - 1),
|
AxialAddr::new(self.q + 1, self.r - 1),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test whether a coordinate is adjacent to this one
|
/// Test whether a coordinate is adjacent to this one
|
||||||
pub fn is_adjacent(&self, dest: &HexAddr) -> bool {
|
pub fn is_adjacent(&self, dest: &AxialAddr) -> bool {
|
||||||
dest.adjacencies().collect::<Vec<HexAddr>>().contains(&self)
|
dest.adjacencies()
|
||||||
|
.collect::<Vec<AxialAddr>>()
|
||||||
|
.contains(&self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Measure the distance to a destination
|
/// Measure the distance to a destination
|
||||||
pub fn distance(&self, dest: &HexAddr) -> usize {
|
pub fn distance(&self, dest: &AxialAddr) -> usize {
|
||||||
(((self.q() - dest.q()).abs() + (self.r() - dest.r()).abs() + (self.s() - dest.s()).abs())
|
(((self.q() - dest.q()).abs() + (self.r() - dest.r()).abs() + (self.s() - dest.s()).abs())
|
||||||
/ 2) as usize
|
/ 2) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iteration to all of the coordinates within the specified distance of this one.
|
/// Get an iteration of all of the coordinates within the specified distance of this one.
|
||||||
pub fn within(&self, distance: usize) -> impl Iterator<Item = HexAddr> {
|
pub fn addresses(&self, distance: usize) -> impl Iterator<Item = AxialAddr> {
|
||||||
let eko = self.clone();
|
let item = self.clone();
|
||||||
let mut rezulto: HashSet<HexAddr> = HashSet::new();
|
let mut results: HashSet<AxialAddr> = HashSet::new();
|
||||||
let mut vico: Vec<HexAddr> = Vec::new();
|
let mut positions: Vec<AxialAddr> = Vec::new();
|
||||||
|
|
||||||
vico.push(eko);
|
positions.push(item);
|
||||||
|
|
||||||
while vico.len() > 0 {
|
while positions.len() > 0 {
|
||||||
let elem = vico.remove(0);
|
let elem = positions.remove(0);
|
||||||
for adj in elem.adjacencies() {
|
for adj in elem.adjacencies() {
|
||||||
if self.distance(&adj) <= distance && !rezulto.contains(&adj) {
|
if self.distance(&adj) <= distance && !results.contains(&adj) {
|
||||||
vico.push(adj.clone());
|
positions.push(adj.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rezulto.insert(elem);
|
results.insert(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
rezulto.remove(self);
|
results.into_iter()
|
||||||
rezulto.into_iter()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,24 +88,25 @@ mod tests {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn distance_0_is_empty() {
|
fn distance_0_has_the_source() {
|
||||||
let addr = HexAddr::origin();
|
let addr = AxialAddr::origin();
|
||||||
let lst: Vec<HexAddr> = addr.within(0).collect();
|
let lst: Vec<AxialAddr> = addr.addresses(0).collect();
|
||||||
assert_eq!(lst.len(), 0);
|
assert_eq!(lst.len(), 1);
|
||||||
|
assert!(lst.contains(&AxialAddr::origin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn distance_1_has_six_addresses() {
|
fn distance_1_has_seven_addresses() {
|
||||||
let hexaddr = HexAddr::origin();
|
let hexaddr = AxialAddr::origin();
|
||||||
let lst: Vec<HexAddr> = hexaddr.within(1).collect();
|
let lst: Vec<AxialAddr> = hexaddr.addresses(1).collect();
|
||||||
assert_eq!(lst.len(), 6);
|
assert_eq!(lst.len(), 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn distance_2_has_18_addresses() {
|
fn distance_2_has_19_addresses() {
|
||||||
let hexaddr = HexAddr::origin();
|
let hexaddr = AxialAddr::origin();
|
||||||
let lst: Vec<HexAddr> = hexaddr.within(2).collect();
|
let lst: Vec<AxialAddr> = hexaddr.addresses(2).collect();
|
||||||
assert_eq!(lst.len(), 18);
|
assert_eq!(lst.len(), 19);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address() -> (std::ops::Range<i32>, std::ops::Range<i32>) {
|
fn address() -> (std::ops::Range<i32>, std::ops::Range<i32>) {
|
||||||
|
@ -114,20 +116,20 @@ mod tests {
|
||||||
proptest! {
|
proptest! {
|
||||||
#[test]
|
#[test]
|
||||||
fn produces_adjacent_coordinates((x, y) in address(), idx in 0_usize..6) {
|
fn produces_adjacent_coordinates((x, y) in address(), idx in 0_usize..6) {
|
||||||
let coord1 = HexAddr::new(x, y);
|
let coord1 = AxialAddr::new(x, y);
|
||||||
let lst1: HashSet<HexAddr> = coord1.adjacencies().collect();
|
let lst1: HashSet<AxialAddr> = coord1.adjacencies().collect();
|
||||||
assert_eq!(lst1.len(), 6);
|
assert_eq!(lst1.len(), 6);
|
||||||
|
|
||||||
let lst1 = lst1.into_iter().collect::<Vec<_>>();
|
let lst1 = lst1.into_iter().collect::<Vec<_>>();
|
||||||
let coord2 = &lst1[idx];
|
let coord2 = &lst1[idx];
|
||||||
let lst2: Vec<HexAddr> = coord2.adjacencies().collect();
|
let lst2: Vec<AxialAddr> = coord2.adjacencies().collect();
|
||||||
assert!(lst2.contains(&coord1));
|
assert!(lst2.contains(&coord1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tests_adjacencies((q, r) in address(), idx in 0_usize..6) {
|
fn tests_adjacencies((q, r) in address(), idx in 0_usize..6) {
|
||||||
let coord1 = HexAddr::new(q, r);
|
let coord1 = AxialAddr::new(q, r);
|
||||||
let lst1: Vec<HexAddr> = coord1.adjacencies().collect();
|
let lst1: Vec<AxialAddr> = coord1.adjacencies().collect();
|
||||||
assert_eq!(lst1.len(), 6);
|
assert_eq!(lst1.len(), 6);
|
||||||
|
|
||||||
let coord2 = &lst1[idx];
|
let coord2 = &lst1[idx];
|
||||||
|
@ -138,8 +140,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn measures_distance((q1, r1) in address(),
|
fn measures_distance((q1, r1) in address(),
|
||||||
(q2, r2) in address()) {
|
(q2, r2) in address()) {
|
||||||
let hexaddr_1 = HexAddr::new(q1, r1);
|
let hexaddr_1 = AxialAddr::new(q1, r1);
|
||||||
let hexaddr_2 = HexAddr::new(q2, r2);
|
let hexaddr_2 = AxialAddr::new(q2, r2);
|
||||||
|
|
||||||
let s1 = -q1 - r1;
|
let s1 = -q1 - r1;
|
||||||
let s2 = -q2 - r2;
|
let s2 = -q2 - r2;
|
||||||
|
@ -150,10 +152,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn calculates_distance((q, r) in address(), distance in 0_usize..6) {
|
fn calculates_distance((q, r) in address(), distance in 0_usize..6) {
|
||||||
let hexaddr = HexAddr::new(q, r);
|
let hexaddr = AxialAddr::new(q, r);
|
||||||
let en_distancaj_hexaddr: Vec<HexAddr> = hexaddr.within(distance).collect();
|
let en_distancaj_hexaddr: Vec<AxialAddr> = hexaddr.addresses(distance).collect();
|
||||||
|
|
||||||
let expected_cnt = ((0..distance+1).map(|v| v * 6).fold(0, |acc, val| acc + val)) as usize;
|
let expected_cnt = ((0..distance+1).map(|v| v * 6).fold(1, |acc, val| acc + val)) as usize;
|
||||||
assert_eq!(en_distancaj_hexaddr.len(), expected_cnt);
|
assert_eq!(en_distancaj_hexaddr.len(), expected_cnt);
|
||||||
for c in en_distancaj_hexaddr {
|
for c in en_distancaj_hexaddr {
|
||||||
assert!(c.distance(&hexaddr) <= distance as usize);
|
assert!(c.distance(&hexaddr) <= distance as usize);
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022-2023, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||||
|
|
||||||
|
This file is part of the Luminescent Dreams Tools.
|
||||||
|
|
||||||
|
Luminescent Dreams Tools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Luminescent Dreams Tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with Luminescent Dreams Tools. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::hex::AxialAddr;
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::alphanumeric1,
|
||||||
|
error::ParseError,
|
||||||
|
multi::many1,
|
||||||
|
sequence::{delimited, separated_pair},
|
||||||
|
Finish, IResult, Parser,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
collections::{hash_map::Entry, HashMap},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Map<A> {
|
||||||
|
cells: HashMap<AxialAddr, A>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Default + From<String> + Clone> Map<A>
|
||||||
|
where
|
||||||
|
String: From<A>,
|
||||||
|
{
|
||||||
|
pub fn new_hexagonal(radius: usize) -> Map<A> {
|
||||||
|
let cells = vec![(AxialAddr::origin(), Default::default())]
|
||||||
|
.into_iter()
|
||||||
|
.chain(
|
||||||
|
AxialAddr::origin()
|
||||||
|
.addresses(radius)
|
||||||
|
.map(|addr| (addr, Default::default())),
|
||||||
|
)
|
||||||
|
.collect::<HashMap<AxialAddr, A>>();
|
||||||
|
Map { cells }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, coordinate: AxialAddr) -> bool {
|
||||||
|
self.cells.contains_key(&coordinate)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell(&mut self, addr: AxialAddr) -> Entry<AxialAddr, A> {
|
||||||
|
self.cells.entry(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, addr: &AxialAddr) -> Option<&A> {
|
||||||
|
self.cells.get(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn from_file(path: PathBuf) -> Map<A> {}
|
||||||
|
|
||||||
|
pub fn to_file(&self, path: PathBuf) -> () {}
|
||||||
|
|
||||||
|
pub fn from_data(data: Vec<String>) -> Map<A> {
|
||||||
|
fn parse_line<A: From<String>>(
|
||||||
|
input: &str,
|
||||||
|
) -> Result<(AxialAddr, A), nom::error::Error<&str>> {
|
||||||
|
fn parse<A: From<String>>(input: &str) -> IResult<&str, (AxialAddr, A)> {
|
||||||
|
let (input, addr) = parse_address(input)?;
|
||||||
|
let (input, value) = cell_value::<A>(input)?;
|
||||||
|
Ok((input, (addr, value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(input).finish().map(|(_, pair)| pair)
|
||||||
|
}
|
||||||
|
|
||||||
|
let cells = data
|
||||||
|
.into_iter()
|
||||||
|
.map(|line| parse_line::<A>(&line).unwrap())
|
||||||
|
.collect::<Vec<(AxialAddr, A)>>();
|
||||||
|
let cells = cells.into_iter().collect::<HashMap<AxialAddr, A>>();
|
||||||
|
Map { cells }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_data(&self) -> Vec<String> {
|
||||||
|
self.cells
|
||||||
|
.iter()
|
||||||
|
.map(|(addr, val)| {
|
||||||
|
format!("[{}, {}] {}", addr.q(), addr.r(), String::from(val.clone()))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_address(input: &str) -> IResult<&str, AxialAddr> {
|
||||||
|
let (input, (q, r)) = delimited(
|
||||||
|
tag("["),
|
||||||
|
separated_pair(
|
||||||
|
nom::character::complete::i32,
|
||||||
|
tag(", "),
|
||||||
|
nom::character::complete::i32,
|
||||||
|
),
|
||||||
|
tag("] "),
|
||||||
|
)(input)?;
|
||||||
|
Ok((input, (AxialAddr::new(q, r))))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cell_value<A: From<String>>(input: &str) -> IResult<&str, A> {
|
||||||
|
many1(alphanumeric1)
|
||||||
|
.or(tag(".").map(|v| vec![v]))
|
||||||
|
.map(|v| v.join(""))
|
||||||
|
.map(|v| A::from(v))
|
||||||
|
.parse(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
struct MapVal(char);
|
||||||
|
impl Default for MapVal {
|
||||||
|
fn default() -> MapVal {
|
||||||
|
MapVal('.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<MapVal> for String {
|
||||||
|
fn from(v: MapVal) -> String {
|
||||||
|
format!("{}", v.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<String> for MapVal {
|
||||||
|
fn from(s: String) -> MapVal {
|
||||||
|
MapVal(s.chars().next().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_can_modify_a_map() {
|
||||||
|
let mut map: Map<MapVal> = Map::new_hexagonal(1);
|
||||||
|
map.cell(AxialAddr::new(0, 0))
|
||||||
|
.and_modify(|cell| *cell = MapVal('L'));
|
||||||
|
assert_eq!(map.get(&AxialAddr::new(0, 0)), Some(&MapVal('L')));
|
||||||
|
assert_eq!(map.get(&AxialAddr::new(0, 1)), Some(&MapVal('.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_can_serialize_a_map() {
|
||||||
|
let mut map: Map<MapVal> = Map::new_hexagonal(1);
|
||||||
|
map.cell(AxialAddr::new(0, 0))
|
||||||
|
.and_modify(|cell| *cell = MapVal('L'));
|
||||||
|
map.cell(AxialAddr::new(1, 0))
|
||||||
|
.and_modify(|cell| *cell = MapVal('A'));
|
||||||
|
|
||||||
|
let mut expected: HashSet<String> = HashSet::new();
|
||||||
|
expected.insert("[0, 0] L".to_owned());
|
||||||
|
expected.insert("[1, 0] A".to_owned());
|
||||||
|
expected.insert("[0, 1] .".to_owned());
|
||||||
|
expected.insert("[-1, 1] .".to_owned());
|
||||||
|
expected.insert("[-1, 0] .".to_owned());
|
||||||
|
expected.insert("[0, -1] .".to_owned());
|
||||||
|
expected.insert("[1, -1] .".to_owned());
|
||||||
|
|
||||||
|
let map_rows = map.to_data();
|
||||||
|
assert_eq!(map_rows.len(), expected.len());
|
||||||
|
map_rows
|
||||||
|
.iter()
|
||||||
|
.for_each(|row| assert!(expected.contains(row)));
|
||||||
|
expected
|
||||||
|
.iter()
|
||||||
|
.for_each(|expected| assert!(map_rows.contains(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_can_deserialize_a_map() {
|
||||||
|
let map_data = "[0, 0] L
|
||||||
|
[1, 0] A
|
||||||
|
[0, 1] .
|
||||||
|
[-1, 1] .
|
||||||
|
[-1, 0] .
|
||||||
|
[0, -1] .
|
||||||
|
[1, -1] .";
|
||||||
|
let map: Map<MapVal> = Map::from_data(
|
||||||
|
map_data
|
||||||
|
.lines()
|
||||||
|
.map(|l| l.to_owned())
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
|
);
|
||||||
|
assert_eq!(map.get(&AxialAddr::new(0, 0)), Some(&MapVal('L')));
|
||||||
|
assert_eq!(map.get(&AxialAddr::new(1, 0)), Some(&MapVal('A')));
|
||||||
|
assert_eq!(map.get(&AxialAddr::new(0, 1)), Some(&MapVal('.')));
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,11 @@ use thiserror;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("La enhavita koordinato ne estas valida en ĉi-tiu sistemo")]
|
#[error("IO error on reading or writing: {0}")]
|
||||||
InvalidCoordinate,
|
IO(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
mod hex;
|
mod hex;
|
||||||
|
mod hex_map;
|
||||||
|
|
||||||
pub use hex::HexAddr;
|
pub use hex::AxialAddr;
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"narHash": "sha256-VCSmIYJy/ZzTvEGjdfITmTYfybXBgZpMjyjDndbou+8=",
|
"narHash": "sha256-/YOtiDKPUXKKpIhsAds11llfC42ScGW27bbHnNZebco=",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"
|
"url": "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue