spacebattleship/board/common/
coordinate2d.rs

1// Copyright 2020 Zachary Stewart
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::board::Coordinate;
16
17/// The corrdinates of a [`GridCell`][crate::board::GridCell] in the board.
18#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
19pub struct Coordinate2D {
20    /// Horizontal position of the cell.
21    pub x: usize,
22    /// Vertical position of the cell.
23    pub y: usize,
24}
25
26impl Coordinate2D {
27    /// Construct a [`Coordinate2D`] from the given `x` and `y`.
28    pub fn new(x: usize, y: usize) -> Self {
29        Self { x, y }
30    }
31}
32
33impl Coordinate for Coordinate2D {}
34
35impl From<(usize, usize)> for Coordinate2D {
36    /// Construct a [`Coordinate2D`] from the given `(x, y)` pair.
37    fn from((x, y): (usize, usize)) -> Self {
38        Self::new(x, y)
39    }
40}
41
42impl From<Coordinate2D> for (usize, usize) {
43    /// Convert the [`Coordinate2D`] into an `(x, y)` pair.
44    fn from(coord: Coordinate2D) -> Self {
45        (coord.x, coord.y)
46    }
47}
48
49#[cfg(feature = "rng_gen")]
50pub use rand_impl::UniformCoordinate2D;
51
52#[cfg(feature = "rng_gen")]
53mod rand_impl {
54    use super::Coordinate2D;
55    use rand::{
56        distributions::uniform::{SampleBorrow, SampleUniform, UniformInt, UniformSampler},
57        Rng,
58    };
59
60    impl SampleUniform for Coordinate2D {
61        type Sampler = UniformCoordinate2D;
62    }
63
64    /// Implements uniform sampling for [`Coordinate2D`].
65    pub struct UniformCoordinate2D(UniformInt<usize>, UniformInt<usize>);
66
67    impl UniformSampler for UniformCoordinate2D {
68        type X = Coordinate2D;
69
70        fn new<B1, B2>(low: B1, high: B2) -> Self
71        where
72            B1: SampleBorrow<Self::X> + Sized,
73            B2: SampleBorrow<Self::X> + Sized,
74        {
75            UniformCoordinate2D(
76                UniformInt::new(low.borrow().x, high.borrow().x),
77                UniformInt::new(low.borrow().y, high.borrow().y),
78            )
79        }
80        fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
81        where
82            B1: SampleBorrow<Self::X> + Sized,
83            B2: SampleBorrow<Self::X> + Sized,
84        {
85            UniformCoordinate2D(
86                UniformInt::new_inclusive(low.borrow().x, high.borrow().x),
87                UniformInt::new_inclusive(low.borrow().y, high.borrow().y),
88            )
89        }
90        fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
91            Coordinate2D {
92                x: self.0.sample(rng),
93                y: self.1.sample(rng),
94            }
95        }
96    }
97}