From 5d0fedac8cb6ec720c35c06684b3e3938a21f9cf Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Tue, 13 Feb 2024 19:08:42 +0100 Subject: [PATCH 01/23] add hex utils --- crates/border-wars/src/hex.rs | 99 +++++++++++++++++++++++++++++++++++ crates/border-wars/src/lib.rs | 1 + 2 files changed, 100 insertions(+) create mode 100644 crates/border-wars/src/hex.rs diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs new file mode 100644 index 0000000..a5523b0 --- /dev/null +++ b/crates/border-wars/src/hex.rs @@ -0,0 +1,99 @@ +//! This file contains utilities for working with hex coordinates. + +use std::collections::HashSet; + +/// Contains all ``HexPosition`` neighbors of a ``HexPosition`` +pub struct GroupHexPosition(HashSet); + +impl GroupHexPosition { + /// Return an intersection of two ``GroupHexPosition`` + /// + /// ## example + /// ``` + /// use border_wars::hex::GroupHexPosition; + /// + /// let vec1 = GroupHexPosition( + /// vec![HexPosition { q: 0, r: 0 }, HexPosition { q: 1, r: -1 }] + /// ); + /// let vec2 = GroupHexPosition( + /// vec![HexPosition { q: 0, r: 0 }, HexPosition { q: 0, r: -1 }] + /// ); + /// let iter = vec1.iter_with(&vec2); + /// assert_eq!(iter, vec![HexPosition { q: 0, r: 0 }]); + pub fn iter_with(&self, other: &GroupHexPosition) -> Vec { + let mut result = Vec::new(); + for pos_1 in self.0.iter() { + if other.0.contains(pos_1) { + result.push(*pos_1); + } + } + result + } + + /// Removes the origin (``HexPosition { q: 0, r: 0 }``) of a + /// ``GroupHexPosition`` + /// + /// ## example + /// ``` + /// use border_wars::hex::GroupHexPosition; + /// + /// let mut vec = GroupHexPosition(vec![ + /// HexPosition { q: 0, r: 0 }, + /// HexPosition { q: 1, r: -1 }, + /// ]); + /// vec.remove_origin(); + /// assert_eq!(vec.0, vec![HexPosition { q: 1, r: -1 }]); + /// ``` + pub fn remove_origin(&mut self) -> &mut Self { + self.0.remove(&HexPosition { q: 0, r: 0 }); + self + } +} + +/// Hex position (in a hexagonal grid). +/// +/// usnig this doc : https://www.redblobgames.com/grids/hexagons/ +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct HexPosition { + /// Q coordinate + pub q: i32, + + /// R coordinate + pub r: i32, +} + +impl HexPosition { + /// Returns the distance between two ``HexPosition`` + /// + /// ## example + /// ``` + /// let hex1 = HexPosition { q: 0, r: 0 }; + /// let hex2 = HexPosition { q: 1, r: 1 }; + /// let distance = hex1.distance_to(&hex2); + /// assert_eq!(distance, 2); + /// ``` + pub fn distance_to(&self, other: &HexPosition) -> f32 { + (((self.q - other.q).abs() + + (self.r - other.r).abs() + + (self.q + self.r - other.q - other.r).abs()) + / 2) as f32 + } + + /// Returns all positions in a given range + /// + /// ## example + /// ``` + /// let hex = HexPosition { q: 0, r: 0 }; + /// let positions = hex.range(1); + /// assert_eq!(positions.len(), 6); + /// ``` + pub fn range(&self, range: i32) -> GroupHexPosition { + let mut positions = HashSet::new(); + for q in (-range)..=range { + for r in (-range).max(-q - range)..=range.min(-q + range) { + positions.insert(HexPosition { q, r }); + } + } + GroupHexPosition(positions) + } +} diff --git a/crates/border-wars/src/lib.rs b/crates/border-wars/src/lib.rs index c85940e..e475a9e 100644 --- a/crates/border-wars/src/lib.rs +++ b/crates/border-wars/src/lib.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; +pub mod hex; pub mod scenes; /// The current scene of the game. -- 2.43.4 From 9af2d354e7516606d497e0cad4e6dddd41446421 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Tue, 13 Feb 2024 20:41:48 +0100 Subject: [PATCH 02/23] Add num calcules --- crates/border-wars/src/hex.rs | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index a5523b0..ce313d3 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -1,6 +1,7 @@ //! This file contains utilities for working with hex coordinates. use std::collections::HashSet; +use std::ops; /// Contains all ``HexPosition`` neighbors of a ``HexPosition`` pub struct GroupHexPosition(HashSet); @@ -97,3 +98,71 @@ impl HexPosition { GroupHexPosition(positions) } } + +impl ops::Add for HexPosition { + type Output = HexPosition; + + fn add(self, other: HexPosition) -> HexPosition { + HexPosition { + q: self.q + other.q, + r: self.r + other.r, + } + } +} + +impl ops::AddAssign for HexPosition { + fn add_assign(&mut self, other: HexPosition) { + *self = *self + other; + } +} + +impl ops::Sub for HexPosition { + type Output = HexPosition; + + fn sub(self, other: HexPosition) -> HexPosition { + HexPosition { + q: self.q - other.q, + r: self.r - other.r, + } + } +} + +impl ops::SubAssign for HexPosition { + fn sub_assign(&mut self, other: HexPosition) { + *self = *self - other; + } +} + +impl ops::Mul for HexPosition { + type Output = HexPosition; + + fn mul(self, other: i32) -> HexPosition { + HexPosition { + q: self.q * other, + r: self.r * other, + } + } +} + +impl ops::MulAssign for HexPosition { + fn mul_assign(&mut self, other: i32) { + *self = *self * other; + } +} + +impl ops::Div for HexPosition { + type Output = HexPosition; + + fn div(self, other: i32) -> HexPosition { + HexPosition { + q: self.q / other, + r: self.r / other, + } + } +} + +impl ops::DivAssign for HexPosition { + fn div_assign(&mut self, other: i32) { + *self = *self / other; + } +} -- 2.43.4 From 9a4fb1a5fd0f97945db1a845f65288c8d32cdc58 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Tue, 13 Feb 2024 20:45:57 +0100 Subject: [PATCH 03/23] update doc --- crates/border-wars/src/hex.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index ce313d3..81481f2 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -68,6 +68,8 @@ impl HexPosition { /// /// ## example /// ``` + /// use border_wars::hex::HexPosition; + /// /// let hex1 = HexPosition { q: 0, r: 0 }; /// let hex2 = HexPosition { q: 1, r: 1 }; /// let distance = hex1.distance_to(&hex2); @@ -84,6 +86,8 @@ impl HexPosition { /// /// ## example /// ``` + /// use border_wars::hex::HexPosition; + /// /// let hex = HexPosition { q: 0, r: 0 }; /// let positions = hex.range(1); /// assert_eq!(positions.len(), 6); -- 2.43.4 From 2ed99e91b2f5f39df7ca74516ea36e7a1ccac432 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Tue, 13 Feb 2024 21:29:20 +0100 Subject: [PATCH 04/23] update doc --- crates/border-wars/src/hex.rs | 54 +++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 81481f2..1924365 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -4,31 +4,43 @@ use std::collections::HashSet; use std::ops; /// Contains all ``HexPosition`` neighbors of a ``HexPosition`` -pub struct GroupHexPosition(HashSet); +pub struct GroupHexPosition(pub HashSet); impl GroupHexPosition { + /// TODO + pub fn new(hexes: HashSet) -> Self { + GroupHexPosition(hexes) + } + /// Return an intersection of two ``GroupHexPosition`` /// /// ## example /// ``` - /// use border_wars::hex::GroupHexPosition; + /// use std::collections::HashSet; + /// + /// use border_wars::hex::{GroupHexPosition, HexPosition}; + /// + /// let vec1 = GroupHexPosition::new(HashSet::from([ + /// HexPosition { q: 0, r: 0 }, + /// HexPosition { q: 1, r: -1 }, + /// ])); + /// + /// let vec2 = GroupHexPosition::new(HashSet::from([ + /// HexPosition { q: 0, r: 0 }, + /// HexPosition { q: 1, r: 1 }, + /// ])); /// - /// let vec1 = GroupHexPosition( - /// vec![HexPosition { q: 0, r: 0 }, HexPosition { q: 1, r: -1 }] - /// ); - /// let vec2 = GroupHexPosition( - /// vec![HexPosition { q: 0, r: 0 }, HexPosition { q: 0, r: -1 }] - /// ); /// let iter = vec1.iter_with(&vec2); - /// assert_eq!(iter, vec![HexPosition { q: 0, r: 0 }]); - pub fn iter_with(&self, other: &GroupHexPosition) -> Vec { - let mut result = Vec::new(); + /// assert!(iter.0.contains(&HexPosition { q: 0, r: 0 })); + /// ``` + pub fn iter_with(&self, other: &GroupHexPosition) -> GroupHexPosition { + let mut result = HashSet::new(); for pos_1 in self.0.iter() { if other.0.contains(pos_1) { - result.push(*pos_1); + result.insert(*pos_1); } } - result + GroupHexPosition::new(result) } /// Removes the origin (``HexPosition { q: 0, r: 0 }``) of a @@ -36,14 +48,16 @@ impl GroupHexPosition { /// /// ## example /// ``` - /// use border_wars::hex::GroupHexPosition; + /// use std::collections::HashSet; /// - /// let mut vec = GroupHexPosition(vec![ + /// use border_wars::hex::{GroupHexPosition, HexPosition}; + /// + /// let mut vec = GroupHexPosition::new(HashSet::from([ /// HexPosition { q: 0, r: 0 }, /// HexPosition { q: 1, r: -1 }, - /// ]); + /// ])); /// vec.remove_origin(); - /// assert_eq!(vec.0, vec![HexPosition { q: 1, r: -1 }]); + /// assert_eq!(vec.0.len(), 1); /// ``` pub fn remove_origin(&mut self) -> &mut Self { self.0.remove(&HexPosition { q: 0, r: 0 }); @@ -68,12 +82,14 @@ impl HexPosition { /// /// ## example /// ``` + /// use std::collections::HashSet; + /// /// use border_wars::hex::HexPosition; /// /// let hex1 = HexPosition { q: 0, r: 0 }; /// let hex2 = HexPosition { q: 1, r: 1 }; /// let distance = hex1.distance_to(&hex2); - /// assert_eq!(distance, 2); + /// assert_eq!(distance, 2.0); /// ``` pub fn distance_to(&self, other: &HexPosition) -> f32 { (((self.q - other.q).abs() @@ -90,7 +106,7 @@ impl HexPosition { /// /// let hex = HexPosition { q: 0, r: 0 }; /// let positions = hex.range(1); - /// assert_eq!(positions.len(), 6); + /// assert_eq!(positions.0.len(), 6); /// ``` pub fn range(&self, range: i32) -> GroupHexPosition { let mut positions = HashSet::new(); -- 2.43.4 From 01c93e13deb7e675a897d74307caeb358bb65d37 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Tue, 13 Feb 2024 22:05:55 +0100 Subject: [PATCH 05/23] change doc --- crates/border-wars/src/hex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 1924365..07e1b8d 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -106,7 +106,7 @@ impl HexPosition { /// /// let hex = HexPosition { q: 0, r: 0 }; /// let positions = hex.range(1); - /// assert_eq!(positions.0.len(), 6); + /// assert_eq!(positions.0.len(), 7); /// ``` pub fn range(&self, range: i32) -> GroupHexPosition { let mut positions = HashSet::new(); -- 2.43.4 From 99489a46a1e97c0fc59ecdac0413459ab2cf0d1f Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 01:04:08 +0100 Subject: [PATCH 06/23] remove test --- crates/border-wars/src/hex.rs | 80 +++-------------------------------- 1 file changed, 6 insertions(+), 74 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 07e1b8d..4cc18ed 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use std::ops; -/// Contains all ``HexPosition`` neighbors of a ``HexPosition`` +/// Contains all "HexPosition" neighbors of "HexPosition" pub struct GroupHexPosition(pub HashSet); impl GroupHexPosition { @@ -12,53 +12,8 @@ impl GroupHexPosition { GroupHexPosition(hexes) } - /// Return an intersection of two ``GroupHexPosition`` - /// - /// ## example - /// ``` - /// use std::collections::HashSet; - /// - /// use border_wars::hex::{GroupHexPosition, HexPosition}; - /// - /// let vec1 = GroupHexPosition::new(HashSet::from([ - /// HexPosition { q: 0, r: 0 }, - /// HexPosition { q: 1, r: -1 }, - /// ])); - /// - /// let vec2 = GroupHexPosition::new(HashSet::from([ - /// HexPosition { q: 0, r: 0 }, - /// HexPosition { q: 1, r: 1 }, - /// ])); - /// - /// let iter = vec1.iter_with(&vec2); - /// assert!(iter.0.contains(&HexPosition { q: 0, r: 0 })); - /// ``` - pub fn iter_with(&self, other: &GroupHexPosition) -> GroupHexPosition { - let mut result = HashSet::new(); - for pos_1 in self.0.iter() { - if other.0.contains(pos_1) { - result.insert(*pos_1); - } - } - GroupHexPosition::new(result) - } - - /// Removes the origin (``HexPosition { q: 0, r: 0 }``) of a - /// ``GroupHexPosition`` - /// - /// ## example - /// ``` - /// use std::collections::HashSet; - /// - /// use border_wars::hex::{GroupHexPosition, HexPosition}; - /// - /// let mut vec = GroupHexPosition::new(HashSet::from([ - /// HexPosition { q: 0, r: 0 }, - /// HexPosition { q: 1, r: -1 }, - /// ])); - /// vec.remove_origin(); - /// assert_eq!(vec.0.len(), 1); - /// ``` + /// Removes the origin (`HexPosition { q: 0, r: 0 }`) of a + /// "GroupHexPosition" pub fn remove_origin(&mut self) -> &mut Self { self.0.remove(&HexPosition { q: 0, r: 0 }); self @@ -78,36 +33,13 @@ pub struct HexPosition { } impl HexPosition { - /// Returns the distance between two ``HexPosition`` - /// - /// ## example - /// ``` - /// use std::collections::HashSet; - /// - /// use border_wars::hex::HexPosition; - /// - /// let hex1 = HexPosition { q: 0, r: 0 }; - /// let hex2 = HexPosition { q: 1, r: 1 }; - /// let distance = hex1.distance_to(&hex2); - /// assert_eq!(distance, 2.0); - /// ``` + /// Returns the distance between two "HexPosition" pub fn distance_to(&self, other: &HexPosition) -> f32 { - (((self.q - other.q).abs() - + (self.r - other.r).abs() - + (self.q + self.r - other.q - other.r).abs()) - / 2) as f32 + + 1. } /// Returns all positions in a given range - /// - /// ## example - /// ``` - /// use border_wars::hex::HexPosition; - /// - /// let hex = HexPosition { q: 0, r: 0 }; - /// let positions = hex.range(1); - /// assert_eq!(positions.0.len(), 7); - /// ``` pub fn range(&self, range: i32) -> GroupHexPosition { let mut positions = HashSet::new(); for q in (-range)..=range { -- 2.43.4 From 1fc89b08dad6e580ad4638d9a8f5dfe29a0c384e Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 01:12:27 +0100 Subject: [PATCH 07/23] add "distance_to" fonction --- crates/border-wars/src/hex.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 4cc18ed..79969ad 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -35,8 +35,10 @@ pub struct HexPosition { impl HexPosition { /// Returns the distance between two "HexPosition" pub fn distance_to(&self, other: &HexPosition) -> f32 { - - 1. + ((self.q - other.q).abs() + + (self.r - other.r).abs() + + (self.q + self.r - other.q - other.r).abs()) as f32 + / 2. } /// Returns all positions in a given range -- 2.43.4 From 23d839ea3415e9846598448d74f21df99be0c4b0 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 01:52:23 +0100 Subject: [PATCH 08/23] WIP: Add docs --- crates/border-wars/src/hex.rs | 57 ++++++++++++++++------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 79969ad..c91027e 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -1,28 +1,10 @@ -//! This file contains utilities for working with hex coordinates. +//! All fonction related to calculations in hexagonal grid. use std::collections::HashSet; use std::ops; -/// Contains all "HexPosition" neighbors of "HexPosition" -pub struct GroupHexPosition(pub HashSet); - -impl GroupHexPosition { - /// TODO - pub fn new(hexes: HashSet) -> Self { - GroupHexPosition(hexes) - } - - /// Removes the origin (`HexPosition { q: 0, r: 0 }`) of a - /// "GroupHexPosition" - pub fn remove_origin(&mut self) -> &mut Self { - self.0.remove(&HexPosition { q: 0, r: 0 }); - self - } -} - -/// Hex position (in a hexagonal grid). -/// -/// usnig this doc : https://www.redblobgames.com/grids/hexagons/ +/// Hexagonal position (in a hexagonal grid). +/// We are using the axial coordinate system explained in this [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct HexPosition { /// Q coordinate @@ -33,23 +15,36 @@ pub struct HexPosition { } impl HexPosition { - /// Returns the distance between two "HexPosition" + /// Returns the distance between two [HexPosition] + /// + /// # How does it work ? + /// + /// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system, + /// is like a cube in 2D space. + /// The Manhattan distance between two positions is equal to: the half of the sum of abs(dx) + abs(dy) + abs(dz) pub fn distance_to(&self, other: &HexPosition) -> f32 { - ((self.q - other.q).abs() - + (self.r - other.r).abs() - + (self.q + self.r - other.q - other.r).abs()) as f32 - / 2. + // dx = |x1 - x2| and x = q + let dq = self.q - other.q; + + // dy = |y1 - y2| and y = r + let dr = self.r - other.r; + + // dz = |z1 - z2| and z = -q - r + let ds = self.q + self.r - other.q - other.r; + + // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 + (dq.abs() + dr.abs() + ds.abs()) as f32 / 2. } - /// Returns all positions in a given range - pub fn range(&self, range: i32) -> GroupHexPosition { - let mut positions = HashSet::new(); + /// Returns all positions in a given `range`. + pub fn range(&self, range: i32) -> HashSet { + let mut result_positions = HashSet::new(); for q in (-range)..=range { for r in (-range).max(-q - range)..=range.min(-q + range) { - positions.insert(HexPosition { q, r }); + result_positions.insert(HexPosition { q, r }); } } - GroupHexPosition(positions) + result_positions } } -- 2.43.4 From 471f516150400685db79b5670ea5714ce8885520 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 10:44:17 +0100 Subject: [PATCH 09/23] Add exemple --- crates/border-wars/src/hex.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index c91027e..10c3380 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -22,6 +22,17 @@ impl HexPosition { /// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system, /// is like a cube in 2D space. /// The Manhattan distance between two positions is equal to: the half of the sum of abs(dx) + abs(dy) + abs(dz) + /// + /// # Example: + /// + /// ```no_run + /// use border_wars::hex::HexPosition; + /// + /// let a = HexPosition { q: 0, r: 0 }; + /// let b = HexPosition { q: 1, r: 1 }; + /// + /// assert_eq!(a.distance_to(&b), 2.0); + /// ``` pub fn distance_to(&self, other: &HexPosition) -> f32 { // dx = |x1 - x2| and x = q let dq = self.q - other.q; @@ -36,7 +47,25 @@ impl HexPosition { (dq.abs() + dr.abs() + ds.abs()) as f32 / 2. } - /// Returns all positions in a given `range`. + /// Returns all positions within a given `range` from the current HexPosition. + /// + /// This function iterates over the possible q and r values within the specified range + /// and inserts HexPositions into a HashSet, ensuring that each generated position + /// is within the given range from the current position. + /// + /// for more details: https://www.redblobgames.com/grids/hexagons/#range + /// + /// # Example: + /// + /// ```no_run + /// use border_wars::hex::HexPosition; + /// + /// let position = HexPosition { q: 0, r: 0 }; + /// + /// let positions = position.range(1); + /// + /// assert_eq!(positions.len(), 7); + /// ``` pub fn range(&self, range: i32) -> HashSet { let mut result_positions = HashSet::new(); for q in (-range)..=range { @@ -46,8 +75,9 @@ impl HexPosition { } result_positions } -} +} + impl ops::Add for HexPosition { type Output = HexPosition; -- 2.43.4 From b6f7a202b43c662811d07307ea8a9dfba6a3f870 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 10:46:32 +0100 Subject: [PATCH 10/23] fix fmt --- crates/border-wars/src/hex.rs | 46 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 10c3380..6ce4920 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -16,21 +16,22 @@ pub struct HexPosition { impl HexPosition { /// Returns the distance between two [HexPosition] - /// + /// /// # How does it work ? - /// - /// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system, - /// is like a cube in 2D space. - /// The Manhattan distance between two positions is equal to: the half of the sum of abs(dx) + abs(dy) + abs(dz) - /// + /// + /// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system, + /// is like a cube in 2D space. + /// The Manhattan distance between two positions is equal to: the half of + /// the sum of abs(dx) + abs(dy) + abs(dz) + /// /// # Example: - /// + /// /// ```no_run /// use border_wars::hex::HexPosition; - /// + /// /// let a = HexPosition { q: 0, r: 0 }; /// let b = HexPosition { q: 1, r: 1 }; - /// + /// /// assert_eq!(a.distance_to(&b), 2.0); /// ``` pub fn distance_to(&self, other: &HexPosition) -> f32 { @@ -43,27 +44,29 @@ impl HexPosition { // dz = |z1 - z2| and z = -q - r let ds = self.q + self.r - other.q - other.r; - // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 + // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 (dq.abs() + dr.abs() + ds.abs()) as f32 / 2. } - /// Returns all positions within a given `range` from the current HexPosition. + /// Returns all positions within a given `range` from the current + /// HexPosition. + /// + /// This function iterates over the possible q and r values within the + /// specified range and inserts HexPositions into a HashSet, ensuring + /// that each generated position is within the given range from the + /// current position. /// - /// This function iterates over the possible q and r values within the specified range - /// and inserts HexPositions into a HashSet, ensuring that each generated position - /// is within the given range from the current position. - /// /// for more details: https://www.redblobgames.com/grids/hexagons/#range - /// + /// /// # Example: - /// + /// /// ```no_run /// use border_wars::hex::HexPosition; - /// + /// /// let position = HexPosition { q: 0, r: 0 }; - /// + /// /// let positions = position.range(1); - /// + /// /// assert_eq!(positions.len(), 7); /// ``` pub fn range(&self, range: i32) -> HashSet { @@ -75,9 +78,8 @@ impl HexPosition { } result_positions } - } - + impl ops::Add for HexPosition { type Output = HexPosition; -- 2.43.4 From 4da153b626e89bf9bfc00a253a1b93e5c5512910 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 10:51:25 +0100 Subject: [PATCH 11/23] Fix clippy --- crates/border-wars/src/hex.rs | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 6ce4920..8026dc1 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -34,7 +34,7 @@ impl HexPosition { /// /// assert_eq!(a.distance_to(&b), 2.0); /// ``` - pub fn distance_to(&self, other: &HexPosition) -> f32 { + pub fn distance_to(&self, other: &Self) -> f32 { // dx = |x1 - x2| and x = q let dq = self.q - other.q; @@ -61,7 +61,7 @@ impl HexPosition { /// # Example: /// /// ```no_run - /// use border_wars::hex::HexPosition; + /// use border_wars::hex::Self; /// /// let position = HexPosition { q: 0, r: 0 }; /// @@ -69,56 +69,56 @@ impl HexPosition { /// /// assert_eq!(positions.len(), 7); /// ``` - pub fn range(&self, range: i32) -> HashSet { + pub fn range(&self, range: i32) -> HashSet { let mut result_positions = HashSet::new(); for q in (-range)..=range { for r in (-range).max(-q - range)..=range.min(-q + range) { - result_positions.insert(HexPosition { q, r }); + result_positions.insert(Self { q, r }); } } result_positions } } -impl ops::Add for HexPosition { - type Output = HexPosition; +impl ops::Add for HexPosition { + type Output = Self; - fn add(self, other: HexPosition) -> HexPosition { - HexPosition { + fn add(self, other: Self) -> Self::Output { + Self { q: self.q + other.q, r: self.r + other.r, } } } -impl ops::AddAssign for HexPosition { - fn add_assign(&mut self, other: HexPosition) { +impl ops::AddAssign for HexPosition { + fn add_assign(&mut self, other: Self) { *self = *self + other; } } -impl ops::Sub for HexPosition { - type Output = HexPosition; +impl ops::Sub for HexPosition { + type Output = Self; - fn sub(self, other: HexPosition) -> HexPosition { - HexPosition { + fn sub(self, other: Self) -> Self { + Self { q: self.q - other.q, r: self.r - other.r, } } } -impl ops::SubAssign for HexPosition { - fn sub_assign(&mut self, other: HexPosition) { +impl ops::SubAssign for HexPosition { + fn sub_assign(&mut self, other: Self) { *self = *self - other; } } impl ops::Mul for HexPosition { - type Output = HexPosition; + type Output = Self; - fn mul(self, other: i32) -> HexPosition { - HexPosition { + fn mul(self, other: i32) -> Self { + Self { q: self.q * other, r: self.r * other, } @@ -132,10 +132,10 @@ impl ops::MulAssign for HexPosition { } impl ops::Div for HexPosition { - type Output = HexPosition; + type Output = Self; - fn div(self, other: i32) -> HexPosition { - HexPosition { + fn div(self, other: i32) -> Self { + Self { q: self.q / other, r: self.r / other, } -- 2.43.4 From d44db4fa3e466e38c123f2d528b58faac171d18e Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 10:53:26 +0100 Subject: [PATCH 12/23] fix fmt --- crates/border-wars/src/hex.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 8026dc1..744329c 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -4,7 +4,8 @@ use std::collections::HashSet; use std::ops; /// Hexagonal position (in a hexagonal grid). -/// We are using the axial coordinate system explained in this [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). +/// We are using the axial coordinate system explained in this +/// [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct HexPosition { /// Q coordinate @@ -19,7 +20,8 @@ impl HexPosition { /// /// # How does it work ? /// - /// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system, + /// Hexagonal grid using the + /// [cube coordinate system](https://www.redblobgames.com/grids/hexagons/#coordinates), /// is like a cube in 2D space. /// The Manhattan distance between two positions is equal to: the half of /// the sum of abs(dx) + abs(dy) + abs(dz) -- 2.43.4 From ff1a6d6ab4dc7e1d9e143e472a5fff70587a468c Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 10:58:40 +0100 Subject: [PATCH 13/23] fix test --- crates/border-wars/src/hex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 744329c..627f48a 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -63,7 +63,7 @@ impl HexPosition { /// # Example: /// /// ```no_run - /// use border_wars::hex::Self; + /// use border_wars::hex::HexPosition; /// /// let position = HexPosition { q: 0, r: 0 }; /// -- 2.43.4 From 1f0083bba8551b4476a611d587a8f63f48874b92 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 11:15:36 +0100 Subject: [PATCH 14/23] better doc --- crates/border-wars/src/hex.rs | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 627f48a..c7902ce 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -1,10 +1,10 @@ -//! All fonction related to calculations in hexagonal grid. +//! All functions related to calculations in a hexagonal grid. use std::collections::HashSet; use std::ops; -/// Hexagonal position (in a hexagonal grid). -/// We are using the axial coordinate system explained in this +/// Represents a position in a hexagonal grid. +/// We use the axial coordinate system explained in this /// [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct HexPosition { @@ -16,19 +16,20 @@ pub struct HexPosition { } impl HexPosition { - /// Returns the distance between two [HexPosition] + /// Returns the distance between two [HexPosition]s. /// - /// # How does it work ? + /// # How it works /// - /// Hexagonal grid using the + /// In the hexagonal grid, using the /// [cube coordinate system](https://www.redblobgames.com/grids/hexagons/#coordinates), - /// is like a cube in 2D space. - /// The Manhattan distance between two positions is equal to: the half of - /// the sum of abs(dx) + abs(dy) + abs(dz) + /// it's akin to a cube in 3D space. + /// The Manhattan distance between two positions is equal to half of + /// the sum of abs(dx) + abs(dy) + abs(dz). + /// However, in hexagonal grids, z is defined as -q - r. /// - /// # Example: + /// # Example /// - /// ```no_run + /// ``` /// use border_wars::hex::HexPosition; /// /// let a = HexPosition { q: 0, r: 0 }; @@ -37,32 +38,31 @@ impl HexPosition { /// assert_eq!(a.distance_to(&b), 2.0); /// ``` pub fn distance_to(&self, other: &Self) -> f32 { - // dx = |x1 - x2| and x = q + // dx = |x1 - x2| where x = q let dq = self.q - other.q; - // dy = |y1 - y2| and y = r + // dy = |y1 - y2| where y = r let dr = self.r - other.r; - // dz = |z1 - z2| and z = -q - r - let ds = self.q + self.r - other.q - other.r; + // dz = |z1 - z2| where z = -q - r + let dz = self.q + self.r - other.q - other.r; // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 - (dq.abs() + dr.abs() + ds.abs()) as f32 / 2. + (dq.abs() + dr.abs() + dz.abs()) as f32 / 2.0 } /// Returns all positions within a given `range` from the current - /// HexPosition. + /// `HexPosition`. /// /// This function iterates over the possible q and r values within the - /// specified range and inserts HexPositions into a HashSet, ensuring - /// that each generated position is within the given range from the - /// current position. + /// specified range. + /// Note that the original position is also returned. /// - /// for more details: https://www.redblobgames.com/grids/hexagons/#range + /// For more details, refer to: https://www.redblobgames.com/grids/hexagons/#range /// - /// # Example: + /// # Example /// - /// ```no_run + /// ``` /// use border_wars::hex::HexPosition; /// /// let position = HexPosition { q: 0, r: 0 }; -- 2.43.4 From cfb3de298e282d1372c8c56ebe0a24cfd30d86b4 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 11:17:54 +0100 Subject: [PATCH 15/23] add no run to exemple --- crates/border-wars/src/hex.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index c7902ce..1761ab5 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -29,7 +29,7 @@ impl HexPosition { /// /// # Example /// - /// ``` + /// ```no_run /// use border_wars::hex::HexPosition; /// /// let a = HexPosition { q: 0, r: 0 }; @@ -62,7 +62,7 @@ impl HexPosition { /// /// # Example /// - /// ``` + /// ```no_run /// use border_wars::hex::HexPosition; /// /// let position = HexPosition { q: 0, r: 0 }; -- 2.43.4 From 8590c949739934ebda3b720584e79ac45b94a87f Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 14:36:00 +0100 Subject: [PATCH 16/23] add generique type --- Cargo.lock | 67 +++++++++++++++++++++++++++ crates/border-wars/Cargo.toml | 1 + crates/border-wars/src/hex.rs | 87 ++++++++++++++++------------------- 3 files changed, 107 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f17b55..04d3d7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1316,6 +1316,7 @@ version = "0.1.0" dependencies = [ "bevy", "bevy_egui", + "num", ] [[package]] @@ -2993,6 +2994,40 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -3004,6 +3039,38 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" diff --git a/crates/border-wars/Cargo.toml b/crates/border-wars/Cargo.toml index 19f39d9..389e9b0 100644 --- a/crates/border-wars/Cargo.toml +++ b/crates/border-wars/Cargo.toml @@ -13,3 +13,4 @@ workspace = true [dependencies] bevy = "0.12.1" bevy_egui = "0.24.0" +num = "0.4.1" diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 1761ab5..7462106 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -1,21 +1,44 @@ //! All functions related to calculations in a hexagonal grid. use std::collections::HashSet; +use std::hash::Hash; use std::ops; +use num::Signed; + +/// Represents a number that can be used in a hexagonal grid. +pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd { + /// Returns the minimum value between `self` and `other`. + fn min(&self, other: Self) -> Self { + if *self < other { + return *self; + } + other + } + + /// Returns the maximum value between `self` and `other`. + fn max(&self, other: Self) -> Self { + if *self > other { + return *self; + } + other + } +} +impl HexNumber for T {} + /// Represents a position in a hexagonal grid. /// We use the axial coordinate system explained in this /// [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct HexPosition { +pub struct HexPosition { /// Q coordinate - pub q: i32, + pub q: T, /// R coordinate - pub r: i32, + pub r: T, } -impl HexPosition { +impl HexPosition { /// Returns the distance between two [HexPosition]s. /// /// # How it works @@ -37,7 +60,7 @@ impl HexPosition { /// /// assert_eq!(a.distance_to(&b), 2.0); /// ``` - pub fn distance_to(&self, other: &Self) -> f32 { + pub fn distance_to(&self, other: &Self) -> T { // dx = |x1 - x2| where x = q let dq = self.q - other.q; @@ -48,9 +71,11 @@ impl HexPosition { let dz = self.q + self.r - other.q - other.r; // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 - (dq.abs() + dr.abs() + dz.abs()) as f32 / 2.0 + (dq.abs() + dr.abs() + dz.abs()) / (T::one() + T::one()) } +} +impl HexPosition { /// Returns all positions within a given `range` from the current /// `HexPosition`. /// @@ -62,7 +87,7 @@ impl HexPosition { /// /// # Example /// - /// ```no_run + /// ``` /// use border_wars::hex::HexPosition; /// /// let position = HexPosition { q: 0, r: 0 }; @@ -71,10 +96,10 @@ impl HexPosition { /// /// assert_eq!(positions.len(), 7); /// ``` - pub fn range(&self, range: i32) -> HashSet { + pub fn range(&self, range: T) -> HashSet { let mut result_positions = HashSet::new(); - for q in (-range)..=range { - for r in (-range).max(-q - range)..=range.min(-q + range) { + for q in num::range_inclusive(-range, range) { + for r in num::range_inclusive((-range).max(-q - range), range.min(-q + range)) { result_positions.insert(Self { q, r }); } } @@ -82,7 +107,7 @@ impl HexPosition { } } -impl ops::Add for HexPosition { +impl ops::Add for HexPosition { type Output = Self; fn add(self, other: Self) -> Self::Output { @@ -93,13 +118,13 @@ impl ops::Add for HexPosition { } } -impl ops::AddAssign for HexPosition { +impl ops::AddAssign for HexPosition { fn add_assign(&mut self, other: Self) { *self = *self + other; } } -impl ops::Sub for HexPosition { +impl ops::Sub for HexPosition { type Output = Self; fn sub(self, other: Self) -> Self { @@ -110,42 +135,8 @@ impl ops::Sub for HexPosition { } } -impl ops::SubAssign for HexPosition { +impl ops::SubAssign for HexPosition { fn sub_assign(&mut self, other: Self) { *self = *self - other; } } - -impl ops::Mul for HexPosition { - type Output = Self; - - fn mul(self, other: i32) -> Self { - Self { - q: self.q * other, - r: self.r * other, - } - } -} - -impl ops::MulAssign for HexPosition { - fn mul_assign(&mut self, other: i32) { - *self = *self * other; - } -} - -impl ops::Div for HexPosition { - type Output = Self; - - fn div(self, other: i32) -> Self { - Self { - q: self.q / other, - r: self.r / other, - } - } -} - -impl ops::DivAssign for HexPosition { - fn div_assign(&mut self, other: i32) { - *self = *self / other; - } -} -- 2.43.4 From b6587abea1109971c1d554e2338dd815134ab249 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 14:46:15 +0100 Subject: [PATCH 17/23] update test --- crates/border-wars/src/hex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 7462106..5d7adcc 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -58,7 +58,7 @@ impl HexPosition { /// let a = HexPosition { q: 0, r: 0 }; /// let b = HexPosition { q: 1, r: 1 }; /// - /// assert_eq!(a.distance_to(&b), 2.0); + /// assert_eq!(a.distance_to(&b), 2); /// ``` pub fn distance_to(&self, other: &Self) -> T { // dx = |x1 - x2| where x = q -- 2.43.4 From f95f63ffd1a3aa83b6137108c4cb5fcaded6c997 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 15:26:45 +0100 Subject: [PATCH 18/23] change min and max --- Cargo.lock | 7 +++++++ crates/border-wars/Cargo.toml | 1 + crates/border-wars/src/hex.rs | 21 +++------------------ 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04d3d7d..58bf08f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,6 +1317,7 @@ dependencies = [ "bevy", "bevy_egui", "num", + "partial-min-max", ] [[package]] @@ -3328,6 +3329,12 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "partial-min-max" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6448add382c60bbbc64f9dab41309a12ec530c05191601042f911356ac09758c" + [[package]] name = "paste" version = "1.0.14" diff --git a/crates/border-wars/Cargo.toml b/crates/border-wars/Cargo.toml index 389e9b0..5f2e0a0 100644 --- a/crates/border-wars/Cargo.toml +++ b/crates/border-wars/Cargo.toml @@ -14,3 +14,4 @@ workspace = true bevy = "0.12.1" bevy_egui = "0.24.0" num = "0.4.1" +partial-min-max = "0.4.0" diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 5d7adcc..492afd9 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -5,25 +5,10 @@ use std::hash::Hash; use std::ops; use num::Signed; +use partial_min_max::{max, min}; /// Represents a number that can be used in a hexagonal grid. -pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd { - /// Returns the minimum value between `self` and `other`. - fn min(&self, other: Self) -> Self { - if *self < other { - return *self; - } - other - } - - /// Returns the maximum value between `self` and `other`. - fn max(&self, other: Self) -> Self { - if *self > other { - return *self; - } - other - } -} +pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd {} impl HexNumber for T {} /// Represents a position in a hexagonal grid. @@ -99,7 +84,7 @@ impl HexPosi pub fn range(&self, range: T) -> HashSet { let mut result_positions = HashSet::new(); for q in num::range_inclusive(-range, range) { - for r in num::range_inclusive((-range).max(-q - range), range.min(-q + range)) { + for r in num::range_inclusive(max(-range, -q - range), min(range, -q + range)) { result_positions.insert(Self { q, r }); } } -- 2.43.4 From fafdcc0b0ba5c309df4508561da53fa0f73b9ed1 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 17:27:13 +0100 Subject: [PATCH 19/23] change doc --- crates/border-wars/src/hex.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 492afd9..c775ded 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -16,10 +16,10 @@ impl HexNumber for T {} /// [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct HexPosition { - /// Q coordinate + /// Q coordinate. pub q: T, - /// R coordinate + /// R coordinate. pub r: T, } @@ -46,13 +46,9 @@ impl HexPosition { /// assert_eq!(a.distance_to(&b), 2); /// ``` pub fn distance_to(&self, other: &Self) -> T { - // dx = |x1 - x2| where x = q + // Calculate the difference between the q and r coordinates. let dq = self.q - other.q; - - // dy = |y1 - y2| where y = r let dr = self.r - other.r; - - // dz = |z1 - z2| where z = -q - r let dz = self.q + self.r - other.q - other.r; // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 -- 2.43.4 From 648bbf9c61901271bb82723a931ddfefe1fb5525 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 17:30:14 +0100 Subject: [PATCH 20/23] update calcule --- crates/border-wars/src/hex.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index c775ded..0f9aa3a 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -47,12 +47,12 @@ impl HexPosition { /// ``` pub fn distance_to(&self, other: &Self) -> T { // Calculate the difference between the q and r coordinates. - let dq = self.q - other.q; - let dr = self.r - other.r; - let dz = self.q + self.r - other.q - other.r; + let dq = (self.q - other.q).abs(); + let dr = (self.r - other.r).abs(); + let ds = dq + dr; // Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2 - (dq.abs() + dr.abs() + dz.abs()) / (T::one() + T::one()) + (dq + dr + ds) / (T::one() + T::one()) } } -- 2.43.4 From 4c08cd83c4975735d5db56f754eb051086ce9f1f Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 17:34:54 +0100 Subject: [PATCH 21/23] update --- crates/border-wars/src/hex.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 0f9aa3a..b02c530 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -8,8 +8,8 @@ use num::Signed; use partial_min_max::{max, min}; /// Represents a number that can be used in a hexagonal grid. -pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd {} -impl HexNumber for T {} +pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd + FromPrimitive {} +impl HexNumber for T {} /// Represents a position in a hexagonal grid. /// We use the axial coordinate system explained in this -- 2.43.4 From b04ed1acf4aa2db19505ecb66b2d04d567de49ee Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 18:41:14 +0100 Subject: [PATCH 22/23] Change num methode --- crates/border-wars/src/hex.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index b02c530..03ae69e 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -2,9 +2,9 @@ use std::collections::HashSet; use std::hash::Hash; -use std::ops; +use std::ops::{Add, AddAssign, Sub, SubAssign}; -use num::Signed; +use num::{FromPrimitive, Signed}; use partial_min_max::{max, min}; /// Represents a number that can be used in a hexagonal grid. @@ -88,7 +88,7 @@ impl HexPosi } } -impl ops::Add for HexPosition { +impl Add for HexPosition { type Output = Self; fn add(self, other: Self) -> Self::Output { @@ -99,13 +99,14 @@ impl ops::Add for HexPosition { } } -impl ops::AddAssign for HexPosition { +impl AddAssign for HexPosition { fn add_assign(&mut self, other: Self) { - *self = *self + other; + self.q += other.q; + self.r += other.r; } } -impl ops::Sub for HexPosition { +impl Sub for HexPosition { type Output = Self; fn sub(self, other: Self) -> Self { @@ -116,8 +117,9 @@ impl ops::Sub for HexPosition { } } -impl ops::SubAssign for HexPosition { +impl SubAssign for HexPosition { fn sub_assign(&mut self, other: Self) { - *self = *self - other; + self.q -= other.q; + self.r -= other.r; } } -- 2.43.4 From 0736a2381dbde85e495f44486f9abae7c922afb3 Mon Sep 17 00:00:00 2001 From: CoCoSol007 Date: Wed, 14 Feb 2024 18:44:33 +0100 Subject: [PATCH 23/23] add \n --- crates/border-wars/src/hex.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/border-wars/src/hex.rs b/crates/border-wars/src/hex.rs index 03ae69e..83e3776 100644 --- a/crates/border-wars/src/hex.rs +++ b/crates/border-wars/src/hex.rs @@ -9,6 +9,7 @@ use partial_min_max::{max, min}; /// Represents a number that can be used in a hexagonal grid. pub trait HexNumber: Signed + PartialEq + Copy + PartialOrd + FromPrimitive {} + impl HexNumber for T {} /// Represents a position in a hexagonal grid. -- 2.43.4