1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::fmt::{Display, Formatter, Result};

/// Represents a square on the board.
///
/// ``` text
/// +----+----+----+----+-> X
/// | A1 | B1 | C1 | D1 |
/// +----+----+----+----+
/// | A2 | B2 | C2 | D2 |
/// +----+----+----+----+
/// | A3 | B3 | C3 | D3 |
/// +----+----+----+----+
/// | A4 | B4 | C4 | D4 |
/// +----+----+----+----+
/// V Y
/// ```
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
pub enum Square {
   A1 = 1 << 15,
   B1 = 1 << 14,
   C1 = 1 << 13,
   D1 = 1 << 12,
   A2 = 1 << 11,
   B2 = 1 << 10,
   C2 = 1 << 9,
   D2 = 1 << 8,
   A3 = 1 << 7,
   B3 = 1 << 6,
   C3 = 1 << 5,
   D3 = 1 << 4,
   A4 = 1 << 3,
   B4 = 1 << 2,
   C4 = 1 << 1,
   D4 = 1 << 0,
}

impl Square {
   /// An array that includes all the squares in the order of A1, B1, C1, ... .
   pub const ALL: [Self; 16] = [
      Self::A1,
      Self::B1,
      Self::C1,
      Self::D1,
      Self::A2,
      Self::B2,
      Self::C2,
      Self::D2,
      Self::A3,
      Self::B3,
      Self::C3,
      Self::D3,
      Self::A4,
      Self::B4,
      Self::C4,
      Self::D4,
   ];

   /// Returns a square corresponding to the given XY coordinates.
   pub fn from_pos(x: usize, y: usize) -> Self {
      Self::ALL[x.min(3) + 4 * y.min(3)]
   }
}

impl Display for Square {
   fn fmt(&self, f: &mut Formatter) -> Result {
      match self {
         Self::A1 => write!(f, "A1"),
         Self::B1 => write!(f, "B1"),
         Self::C1 => write!(f, "C1"),
         Self::D1 => write!(f, "D1"),
         Self::A2 => write!(f, "A2"),
         Self::B2 => write!(f, "B2"),
         Self::C2 => write!(f, "C2"),
         Self::D2 => write!(f, "D2"),
         Self::A3 => write!(f, "A3"),
         Self::B3 => write!(f, "B3"),
         Self::C3 => write!(f, "C3"),
         Self::D3 => write!(f, "D3"),
         Self::A4 => write!(f, "A4"),
         Self::B4 => write!(f, "B4"),
         Self::C4 => write!(f, "C4"),
         Self::D4 => write!(f, "D4"),
      }
   }
}