chess/
square.rs

1use crate::color::Color;
2use crate::error::Error;
3use crate::file::File;
4use crate::rank::Rank;
5use std::fmt;
6use std::str::FromStr;
7
8/// Represent a square on the chess board
9#[derive(PartialEq, Ord, Eq, PartialOrd, Copy, Clone, Debug, Hash)]
10pub struct Square(u8);
11
12/// How many squares are there?
13pub const NUM_SQUARES: usize = 64;
14
15impl Default for Square {
16    /// Create a square on A1.
17    ///
18    /// ```
19    /// use chess::{Square, Rank, File};
20    ///
21    /// let explicit_sq = Square::make_square(Rank::First, File::A);
22    /// let implicit_sq = Square::default();
23    ///
24    /// assert_eq!(explicit_sq, implicit_sq);
25    /// ```
26    fn default() -> Square {
27        unsafe { Square::new(0) }
28    }
29}
30
31impl Square {
32    /// Create a new square, given an index.
33    /// Note: It is invalid, but allowed, to pass in a number >= 64.  Doing so will crash stuff.
34    ///
35    /// ```
36    ///
37    /// use chess::{Square, Rank, File, EMPTY};
38    ///
39    /// assert_eq!(unsafe { Square::new(0) }, Square::default());
40    ///
41    /// let bad_sq = unsafe { Square::new(64) };
42    ///
43    /// // Iterate over all possible squares and ensure that *none* of them are equal to `bad_sq`.
44    /// for sq in !EMPTY {
45    ///     assert_ne!(bad_sq, sq);
46    /// }
47    /// ```
48    #[inline]
49    pub unsafe fn new(sq: u8) -> Square {
50        Square(sq)
51    }
52
53    /// Make a square given a rank and a file
54    ///
55    /// ```
56    /// use chess::{Square, Rank, File, BitBoard};
57    ///
58    /// // Make the A1 square
59    /// let sq = Square::make_square(Rank::First, File::A);
60    ///
61    /// // Convert it to a bitboard
62    /// let bb = BitBoard::from_square(sq);
63    ///
64    /// // loop over all squares in the bitboard (should be only one), and ensure that the square
65    /// // is what we created
66    /// for x in bb {
67    ///     assert_eq!(sq, x);
68    /// }
69    /// ```
70    #[inline]
71    pub fn make_square(rank: Rank, file: File) -> Square {
72        Square((rank.to_index() as u8) << 3 ^ (file.to_index() as u8))
73    }
74
75    /// Return the rank given this square.
76    ///
77    /// ```
78    /// use chess::{Square, Rank, File};
79    ///
80    /// let sq = Square::make_square(Rank::Seventh, File::D);
81    ///
82    /// assert_eq!(sq.get_rank(), Rank::Seventh);
83    /// ```
84    #[inline]
85    pub fn get_rank(&self) -> Rank {
86        Rank::from_index((self.0 >> 3) as usize)
87    }
88
89    /// Return the file given this square.
90    ///
91    /// ```
92    /// use chess::{Square, Rank, File};
93    ///
94    /// let sq = Square::make_square(Rank::Seventh, File::D);
95    ///
96    /// assert_eq!(sq.get_file(), File::D);
97    /// ```
98    #[inline]
99    pub fn get_file(&self) -> File {
100        File::from_index((self.0 & 7) as usize)
101    }
102
103    /// If there is a square above me, return that.  Otherwise, None.
104    ///
105    /// ```
106    /// use chess::{Square, Rank, File};
107    ///
108    /// let sq = Square::make_square(Rank::Seventh, File::D);
109    ///
110    /// assert_eq!(sq.up().expect("Valid Square"), Square::make_square(Rank::Eighth, File::D));
111    ///
112    /// assert_eq!(sq.up().expect("Valid Square").up(), None);
113    /// ```
114    #[inline]
115    pub fn up(&self) -> Option<Square> {
116        if self.get_rank() == Rank::Eighth {
117            None
118        } else {
119            Some(Square::make_square(self.get_rank().up(), self.get_file()))
120        }
121    }
122
123    /// If there is a square below me, return that.  Otherwise, None.
124    ///
125    /// ```
126    /// use chess::{Square, Rank, File};
127    ///
128    /// let sq = Square::make_square(Rank::Second, File::D);
129    ///
130    /// assert_eq!(sq.down().expect("Valid Square"), Square::make_square(Rank::First, File::D));
131    ///
132    /// assert_eq!(sq.down().expect("Valid Square").down(), None);
133    /// ```
134    #[inline]
135    pub fn down(&self) -> Option<Square> {
136        if self.get_rank() == Rank::First {
137            None
138        } else {
139            Some(Square::make_square(self.get_rank().down(), self.get_file()))
140        }
141    }
142
143    /// If there is a square to the left of me, return that.  Otherwise, None.
144    ///
145    /// ```
146    /// use chess::{Square, Rank, File};
147    ///
148    /// let sq = Square::make_square(Rank::Seventh, File::B);
149    ///
150    /// assert_eq!(sq.left().expect("Valid Square"), Square::make_square(Rank::Seventh, File::A));
151    ///
152    /// assert_eq!(sq.left().expect("Valid Square").left(), None);
153    /// ```
154    #[inline]
155    pub fn left(&self) -> Option<Square> {
156        if self.get_file() == File::A {
157            None
158        } else {
159            Some(Square::make_square(self.get_rank(), self.get_file().left()))
160        }
161    }
162
163    /// If there is a square to the right of me, return that.  Otherwise, None.
164    ///
165    /// ```
166    /// use chess::{Square, Rank, File};
167    ///
168    /// let sq = Square::make_square(Rank::Seventh, File::G);
169    ///
170    /// assert_eq!(sq.right().expect("Valid Square"), Square::make_square(Rank::Seventh, File::H));
171    ///
172    /// assert_eq!(sq.right().expect("Valid Square").right(), None);
173    /// ```
174    #[inline]
175    pub fn right(&self) -> Option<Square> {
176        if self.get_file() == File::H {
177            None
178        } else {
179            Some(Square::make_square(
180                self.get_rank(),
181                self.get_file().right(),
182            ))
183        }
184    }
185
186    /// If there is a square "forward", given my `Color`, go in that direction.  Otherwise, None.
187    ///
188    /// ```
189    /// use chess::{Square, Rank, File, Color};
190    ///
191    /// let mut sq = Square::make_square(Rank::Seventh, File::D);
192    ///
193    /// assert_eq!(sq.forward(Color::White).expect("Valid Square"), Square::make_square(Rank::Eighth, File::D));
194    /// assert_eq!(sq.forward(Color::White).expect("Valid Square").forward(Color::White), None);
195    ///
196    /// sq = Square::make_square(Rank::Second, File::D);
197    ///
198    /// assert_eq!(sq.forward(Color::Black).expect("Valid Square"), Square::make_square(Rank::First, File::D));
199    /// assert_eq!(sq.forward(Color::Black).expect("Valid Square").forward(Color::Black), None);
200    /// ```
201    #[inline]
202    pub fn forward(&self, color: Color) -> Option<Square> {
203        match color {
204            Color::White => self.up(),
205            Color::Black => self.down(),
206        }
207    }
208
209    /// If there is a square "backward" given my `Color`, go in that direction.  Otherwise, None.
210    ///
211    /// ```
212    /// use chess::{Square, Rank, File, Color};
213    ///
214    /// let mut sq = Square::make_square(Rank::Seventh, File::D);
215    ///
216    /// assert_eq!(sq.backward(Color::Black).expect("Valid Square"), Square::make_square(Rank::Eighth, File::D));
217    /// assert_eq!(sq.backward(Color::Black).expect("Valid Square").backward(Color::Black), None);
218    ///
219    /// sq = Square::make_square(Rank::Second, File::D);
220    ///
221    /// assert_eq!(sq.backward(Color::White).expect("Valid Square"), Square::make_square(Rank::First, File::D));
222    /// assert_eq!(sq.backward(Color::White).expect("Valid Square").backward(Color::White), None);
223    /// ```
224    #[inline]
225    pub fn backward(&self, color: Color) -> Option<Square> {
226        match color {
227            Color::White => self.down(),
228            Color::Black => self.up(),
229        }
230    }
231
232    /// If there is a square above me, return that.  If not, wrap around to the other side.
233    ///
234    /// ```
235    /// use chess::{Square, Rank, File};
236    ///
237    /// let sq = Square::make_square(Rank::Seventh, File::D);
238    ///
239    /// assert_eq!(sq.uup(), Square::make_square(Rank::Eighth, File::D));
240    ///
241    /// assert_eq!(sq.uup().uup(), Square::make_square(Rank::First, File::D));
242    /// ```
243    #[inline]
244    pub fn uup(&self) -> Square {
245        Square::make_square(self.get_rank().up(), self.get_file())
246    }
247
248    /// If there is a square below me, return that.  If not, wrap around to the other side.
249    ///
250    /// ```
251    /// use chess::{Square, Rank, File};
252    ///
253    /// let sq = Square::make_square(Rank::Second, File::D);
254    ///
255    /// assert_eq!(sq.udown(), Square::make_square(Rank::First, File::D));
256    ///
257    /// assert_eq!(sq.udown().udown(), Square::make_square(Rank::Eighth, File::D));
258    /// ```
259    #[inline]
260    pub fn udown(&self) -> Square {
261        Square::make_square(self.get_rank().down(), self.get_file())
262    }
263
264    /// If there is a square to the left of me, return that. If not, wrap around to the other side.
265    ///
266    /// ```
267    /// use chess::{Square, Rank, File};
268    ///
269    /// let sq = Square::make_square(Rank::Seventh, File::B);
270    ///
271    /// assert_eq!(sq.uleft(), Square::make_square(Rank::Seventh, File::A));
272    ///
273    /// assert_eq!(sq.uleft().uleft(), Square::make_square(Rank::Seventh, File::H));
274    /// ```
275    #[inline]
276    pub fn uleft(&self) -> Square {
277        Square::make_square(self.get_rank(), self.get_file().left())
278    }
279
280    /// If there is a square to the right of me, return that.  If not, wrap around to the other
281    /// side.
282    ///
283    /// ```
284    /// use chess::{Square, Rank, File};
285    ///
286    /// let sq = Square::make_square(Rank::Seventh, File::G);
287    ///
288    /// assert_eq!(sq.uright(), Square::make_square(Rank::Seventh, File::H));
289    ///
290    /// assert_eq!(sq.uright().uright(), Square::make_square(Rank::Seventh, File::A));
291    /// ```
292    #[inline]
293    pub fn uright(&self) -> Square {
294        Square::make_square(self.get_rank(), self.get_file().right())
295    }
296
297    /// If there is a square "forward", given my color, return that.  If not, wrap around to the
298    /// other side.
299    ///
300    /// ```
301    /// use chess::{Square, Rank, File, Color};
302    ///
303    /// let mut sq = Square::make_square(Rank::Seventh, File::D);
304    ///
305    /// assert_eq!(sq.uforward(Color::White), Square::make_square(Rank::Eighth, File::D));
306    /// assert_eq!(sq.uforward(Color::White).uforward(Color::White), Square::make_square(Rank::First, File::D));
307    ///
308    /// sq = Square::make_square(Rank::Second, File::D);
309    ///
310    /// assert_eq!(sq.uforward(Color::Black), Square::make_square(Rank::First, File::D));
311    /// assert_eq!(sq.uforward(Color::Black).uforward(Color::Black), Square::make_square(Rank::Eighth, File::D));
312    /// ```
313    #[inline]
314    pub fn uforward(&self, color: Color) -> Square {
315        match color {
316            Color::White => self.uup(),
317            Color::Black => self.udown(),
318        }
319    }
320
321    /// If there is a square "backward", given my color, return that.  If not, wrap around to the
322    /// other side.
323    ///
324    /// ```
325    /// use chess::{Square, Rank, File, Color};
326    ///
327    /// let mut sq = Square::make_square(Rank::Seventh, File::D);
328    ///
329    /// assert_eq!(sq.ubackward(Color::Black), Square::make_square(Rank::Eighth, File::D));
330    /// assert_eq!(sq.ubackward(Color::Black).ubackward(Color::Black), Square::make_square(Rank::First, File::D));
331    ///
332    /// sq = Square::make_square(Rank::Second, File::D);
333    ///
334    /// assert_eq!(sq.ubackward(Color::White), Square::make_square(Rank::First, File::D));
335    /// assert_eq!(sq.ubackward(Color::White).ubackward(Color::White), Square::make_square(Rank::Eighth, File::D));
336    /// ```
337    #[inline]
338    pub fn ubackward(&self, color: Color) -> Square {
339        match color {
340            Color::White => self.udown(),
341            Color::Black => self.uup(),
342        }
343    }
344
345    /// Convert this square to an integer.
346    ///
347    /// ```
348    /// use chess::{Square, Rank, File};
349    ///
350    /// assert_eq!(Square::make_square(Rank::First, File::A).to_int(), 0);
351    /// assert_eq!(Square::make_square(Rank::Second, File::A).to_int(), 8);
352    /// assert_eq!(Square::make_square(Rank::First, File::B).to_int(), 1);
353    /// assert_eq!(Square::make_square(Rank::Eighth, File::H).to_int(), 63);
354    /// ```
355    #[inline]
356    pub fn to_int(&self) -> u8 {
357        self.0
358    }
359
360    /// Convert this `Square` to a `usize` for table lookup purposes
361    ///
362    /// ```
363    /// use chess::{Square, Rank, File};
364    ///
365    /// assert_eq!(Square::make_square(Rank::First, File::A).to_index(), 0);
366    /// assert_eq!(Square::make_square(Rank::Second, File::A).to_index(), 8);
367    /// assert_eq!(Square::make_square(Rank::First, File::B).to_index(), 1);
368    /// assert_eq!(Square::make_square(Rank::Eighth, File::H).to_index(), 63);
369    /// ```
370    #[inline]
371    pub fn to_index(&self) -> usize {
372        self.0 as usize
373    }
374
375    /// Convert a UCI `String` to a square.  If invalid, return `None`
376    ///
377    /// ```
378    /// use chess::Square;
379    ///
380    /// let sq = Square::default();
381    ///
382    /// assert_eq!(Square::from_string("a1".to_owned()).expect("Valid Square"), sq);
383    /// ```
384    #[deprecated(
385        since = "3.1.0",
386        note = "please use `Square::from_str(square)?` instead"
387    )]
388    pub fn from_string(s: String) -> Option<Square> {
389        Square::from_str(&s).ok()
390    }
391
392    /// The A1 square on the chess board
393    ///
394    /// ```
395    /// use chess::{Square, Rank, File};
396    ///
397    /// assert_eq!(Square::A1, Square::make_square(Rank::First, File::A));
398    /// ```
399    pub const A1: Square = Square(0);
400
401    /// The B1 square on the chess board
402    ///
403    /// ```
404    /// use chess::{Square, Rank, File};
405    ///
406    /// assert_eq!(Square::B1, Square::make_square(Rank::First, File::B));
407    /// ```
408    pub const B1: Square = Square(1);
409
410    /// The C1 square on the chess board
411    ///
412    /// ```
413    /// use chess::{Square, Rank, File};
414    ///
415    /// assert_eq!(Square::C1, Square::make_square(Rank::First, File::C));
416    /// ```
417    pub const C1: Square = Square(2);
418
419    /// The D1 square on the chess board
420    ///
421    /// ```
422    /// use chess::{Square, Rank, File};
423    ///
424    /// assert_eq!(Square::D1, Square::make_square(Rank::First, File::D));
425    /// ```
426    pub const D1: Square = Square(3);
427
428    /// The E1 square on the chess board
429    ///
430    /// ```
431    /// use chess::{Square, Rank, File};
432    ///
433    /// assert_eq!(Square::E1, Square::make_square(Rank::First, File::E));
434    /// ```
435    pub const E1: Square = Square(4);
436
437    /// The F1 square on the chess board
438    ///
439    /// ```
440    /// use chess::{Square, Rank, File};
441    ///
442    /// assert_eq!(Square::F1, Square::make_square(Rank::First, File::F));
443    /// ```
444    pub const F1: Square = Square(5);
445
446    /// The G1 square on the chess board
447    ///
448    /// ```
449    /// use chess::{Square, Rank, File};
450    ///
451    /// assert_eq!(Square::G1, Square::make_square(Rank::First, File::G));
452    /// ```
453    pub const G1: Square = Square(6);
454
455    /// The H1 square on the chess board
456    ///
457    /// ```
458    /// use chess::{Square, Rank, File};
459    ///
460    /// assert_eq!(Square::H1, Square::make_square(Rank::First, File::H));
461    /// ```
462    pub const H1: Square = Square(7);
463
464    /// The A2 square on the chess board
465    ///
466    /// ```
467    /// use chess::{Square, Rank, File};
468    ///
469    /// assert_eq!(Square::A2, Square::make_square(Rank::Second, File::A));
470    /// ```
471    pub const A2: Square = Square(8);
472
473    /// The B2 square on the chess board
474    ///
475    /// ```
476    /// use chess::{Square, Rank, File};
477    ///
478    /// assert_eq!(Square::B2, Square::make_square(Rank::Second, File::B));
479    /// ```
480    pub const B2: Square = Square(9);
481
482    /// The C2 square on the chess board
483    ///
484    /// ```
485    /// use chess::{Square, Rank, File};
486    ///
487    /// assert_eq!(Square::C2, Square::make_square(Rank::Second, File::C));
488    /// ```
489    pub const C2: Square = Square(10);
490
491    /// The D2 square on the chess board
492    ///
493    /// ```
494    /// use chess::{Square, Rank, File};
495    ///
496    /// assert_eq!(Square::D2, Square::make_square(Rank::Second, File::D));
497    /// ```
498    pub const D2: Square = Square(11);
499
500    /// The E2 square on the chess board
501    ///
502    /// ```
503    /// use chess::{Square, Rank, File};
504    ///
505    /// assert_eq!(Square::E2, Square::make_square(Rank::Second, File::E));
506    /// ```
507    pub const E2: Square = Square(12);
508
509    /// The F2 square on the chess board
510    ///
511    /// ```
512    /// use chess::{Square, Rank, File};
513    ///
514    /// assert_eq!(Square::F2, Square::make_square(Rank::Second, File::F));
515    /// ```
516    pub const F2: Square = Square(13);
517
518    /// The G2 square on the chess board
519    ///
520    /// ```
521    /// use chess::{Square, Rank, File};
522    ///
523    /// assert_eq!(Square::G2, Square::make_square(Rank::Second, File::G));
524    /// ```
525    pub const G2: Square = Square(14);
526
527    /// The H2 square on the chess board
528    ///
529    /// ```
530    /// use chess::{Square, Rank, File};
531    ///
532    /// assert_eq!(Square::H2, Square::make_square(Rank::Second, File::H));
533    /// ```
534    pub const H2: Square = Square(15);
535
536    /// The A3 square on the chess board
537    ///
538    /// ```
539    /// use chess::{Square, Rank, File};
540    ///
541    /// assert_eq!(Square::A3, Square::make_square(Rank::Third, File::A));
542    /// ```
543    pub const A3: Square = Square(16);
544
545    /// The B3 square on the chess board
546    ///
547    /// ```
548    /// use chess::{Square, Rank, File};
549    ///
550    /// assert_eq!(Square::B3, Square::make_square(Rank::Third, File::B));
551    /// ```
552    pub const B3: Square = Square(17);
553
554    /// The C3 square on the chess board
555    ///
556    /// ```
557    /// use chess::{Square, Rank, File};
558    ///
559    /// assert_eq!(Square::C3, Square::make_square(Rank::Third, File::C));
560    /// ```
561    pub const C3: Square = Square(18);
562
563    /// The D3 square on the chess board
564    ///
565    /// ```
566    /// use chess::{Square, Rank, File};
567    ///
568    /// assert_eq!(Square::D3, Square::make_square(Rank::Third, File::D));
569    /// ```
570    pub const D3: Square = Square(19);
571
572    /// The E3 square on the chess board
573    ///
574    /// ```
575    /// use chess::{Square, Rank, File};
576    ///
577    /// assert_eq!(Square::E3, Square::make_square(Rank::Third, File::E));
578    /// ```
579    pub const E3: Square = Square(20);
580
581    /// The F3 square on the chess board
582    ///
583    /// ```
584    /// use chess::{Square, Rank, File};
585    ///
586    /// assert_eq!(Square::F3, Square::make_square(Rank::Third, File::F));
587    /// ```
588    pub const F3: Square = Square(21);
589
590    /// The G3 square on the chess board
591    ///
592    /// ```
593    /// use chess::{Square, Rank, File};
594    ///
595    /// assert_eq!(Square::G3, Square::make_square(Rank::Third, File::G));
596    /// ```
597    pub const G3: Square = Square(22);
598
599    /// The H3 square on the chess board
600    ///
601    /// ```
602    /// use chess::{Square, Rank, File};
603    ///
604    /// assert_eq!(Square::H3, Square::make_square(Rank::Third, File::H));
605    /// ```
606    pub const H3: Square = Square(23);
607
608    /// The A4 square on the chess board
609    ///
610    /// ```
611    /// use chess::{Square, Rank, File};
612    ///
613    /// assert_eq!(Square::A4, Square::make_square(Rank::Fourth, File::A));
614    /// ```
615    pub const A4: Square = Square(24);
616
617    /// The B4 square on the chess board
618    ///
619    /// ```
620    /// use chess::{Square, Rank, File};
621    ///
622    /// assert_eq!(Square::B4, Square::make_square(Rank::Fourth, File::B));
623    /// ```
624    pub const B4: Square = Square(25);
625
626    /// The C4 square on the chess board
627    ///
628    /// ```
629    /// use chess::{Square, Rank, File};
630    ///
631    /// assert_eq!(Square::C4, Square::make_square(Rank::Fourth, File::C));
632    /// ```
633    pub const C4: Square = Square(26);
634
635    /// The D4 square on the chess board
636    ///
637    /// ```
638    /// use chess::{Square, Rank, File};
639    ///
640    /// assert_eq!(Square::D4, Square::make_square(Rank::Fourth, File::D));
641    /// ```
642    pub const D4: Square = Square(27);
643
644    /// The E4 square on the chess board
645    ///
646    /// ```
647    /// use chess::{Square, Rank, File};
648    ///
649    /// assert_eq!(Square::E4, Square::make_square(Rank::Fourth, File::E));
650    /// ```
651    pub const E4: Square = Square(28);
652
653    /// The F4 square on the chess board
654    ///
655    /// ```
656    /// use chess::{Square, Rank, File};
657    ///
658    /// assert_eq!(Square::F4, Square::make_square(Rank::Fourth, File::F));
659    /// ```
660    pub const F4: Square = Square(29);
661
662    /// The G4 square on the chess board
663    ///
664    /// ```
665    /// use chess::{Square, Rank, File};
666    ///
667    /// assert_eq!(Square::G4, Square::make_square(Rank::Fourth, File::G));
668    /// ```
669    pub const G4: Square = Square(30);
670
671    /// The H4 square on the chess board
672    ///
673    /// ```
674    /// use chess::{Square, Rank, File};
675    ///
676    /// assert_eq!(Square::H4, Square::make_square(Rank::Fourth, File::H));
677    /// ```
678    pub const H4: Square = Square(31);
679
680    /// The A5 square on the chess board
681    ///
682    /// ```
683    /// use chess::{Square, Rank, File};
684    ///
685    /// assert_eq!(Square::A5, Square::make_square(Rank::Fifth, File::A));
686    /// ```
687    pub const A5: Square = Square(32);
688
689    /// The B5 square on the chess board
690    ///
691    /// ```
692    /// use chess::{Square, Rank, File};
693    ///
694    /// assert_eq!(Square::B5, Square::make_square(Rank::Fifth, File::B));
695    /// ```
696    pub const B5: Square = Square(33);
697
698    /// The C5 square on the chess board
699    ///
700    /// ```
701    /// use chess::{Square, Rank, File};
702    ///
703    /// assert_eq!(Square::C5, Square::make_square(Rank::Fifth, File::C));
704    /// ```
705    pub const C5: Square = Square(34);
706
707    /// The D5 square on the chess board
708    ///
709    /// ```
710    /// use chess::{Square, Rank, File};
711    ///
712    /// assert_eq!(Square::D5, Square::make_square(Rank::Fifth, File::D));
713    /// ```
714    pub const D5: Square = Square(35);
715
716    /// The E5 square on the chess board
717    ///
718    /// ```
719    /// use chess::{Square, Rank, File};
720    ///
721    /// assert_eq!(Square::E5, Square::make_square(Rank::Fifth, File::E));
722    /// ```
723    pub const E5: Square = Square(36);
724
725    /// The F5 square on the chess board
726    ///
727    /// ```
728    /// use chess::{Square, Rank, File};
729    ///
730    /// assert_eq!(Square::F5, Square::make_square(Rank::Fifth, File::F));
731    /// ```
732    pub const F5: Square = Square(37);
733
734    /// The G5 square on the chess board
735    ///
736    /// ```
737    /// use chess::{Square, Rank, File};
738    ///
739    /// assert_eq!(Square::G5, Square::make_square(Rank::Fifth, File::G));
740    /// ```
741    pub const G5: Square = Square(38);
742
743    /// The H5 square on the chess board
744    ///
745    /// ```
746    /// use chess::{Square, Rank, File};
747    ///
748    /// assert_eq!(Square::H5, Square::make_square(Rank::Fifth, File::H));
749    /// ```
750    pub const H5: Square = Square(39);
751
752    /// The A6 square on the chess board
753    ///
754    /// ```
755    /// use chess::{Square, Rank, File};
756    ///
757    /// assert_eq!(Square::A6, Square::make_square(Rank::Sixth, File::A));
758    /// ```
759    pub const A6: Square = Square(40);
760
761    /// The B6 square on the chess board
762    ///
763    /// ```
764    /// use chess::{Square, Rank, File};
765    ///
766    /// assert_eq!(Square::B6, Square::make_square(Rank::Sixth, File::B));
767    /// ```
768    pub const B6: Square = Square(41);
769
770    /// The C6 square on the chess board
771    ///
772    /// ```
773    /// use chess::{Square, Rank, File};
774    ///
775    /// assert_eq!(Square::C6, Square::make_square(Rank::Sixth, File::C));
776    /// ```
777    pub const C6: Square = Square(42);
778
779    /// The D6 square on the chess board
780    ///
781    /// ```
782    /// use chess::{Square, Rank, File};
783    ///
784    /// assert_eq!(Square::D6, Square::make_square(Rank::Sixth, File::D));
785    /// ```
786    pub const D6: Square = Square(43);
787
788    /// The E6 square on the chess board
789    ///
790    /// ```
791    /// use chess::{Square, Rank, File};
792    ///
793    /// assert_eq!(Square::E6, Square::make_square(Rank::Sixth, File::E));
794    /// ```
795    pub const E6: Square = Square(44);
796
797    /// The F6 square on the chess board
798    ///
799    /// ```
800    /// use chess::{Square, Rank, File};
801    ///
802    /// assert_eq!(Square::F6, Square::make_square(Rank::Sixth, File::F));
803    /// ```
804    pub const F6: Square = Square(45);
805
806    /// The G6 square on the chess board
807    ///
808    /// ```
809    /// use chess::{Square, Rank, File};
810    ///
811    /// assert_eq!(Square::G6, Square::make_square(Rank::Sixth, File::G));
812    /// ```
813    pub const G6: Square = Square(46);
814
815    /// The H6 square on the chess board
816    ///
817    /// ```
818    /// use chess::{Square, Rank, File};
819    ///
820    /// assert_eq!(Square::H6, Square::make_square(Rank::Sixth, File::H));
821    /// ```
822    pub const H6: Square = Square(47);
823
824    /// The A7 square on the chess board
825    ///
826    /// ```
827    /// use chess::{Square, Rank, File};
828    ///
829    /// assert_eq!(Square::A7, Square::make_square(Rank::Seventh, File::A));
830    /// ```
831    pub const A7: Square = Square(48);
832
833    /// The B7 square on the chess board
834    ///
835    /// ```
836    /// use chess::{Square, Rank, File};
837    ///
838    /// assert_eq!(Square::B7, Square::make_square(Rank::Seventh, File::B));
839    /// ```
840    pub const B7: Square = Square(49);
841
842    /// The C7 square on the chess board
843    ///
844    /// ```
845    /// use chess::{Square, Rank, File};
846    ///
847    /// assert_eq!(Square::C7, Square::make_square(Rank::Seventh, File::C));
848    /// ```
849    pub const C7: Square = Square(50);
850
851    /// The D7 square on the chess board
852    ///
853    /// ```
854    /// use chess::{Square, Rank, File};
855    ///
856    /// assert_eq!(Square::D7, Square::make_square(Rank::Seventh, File::D));
857    /// ```
858    pub const D7: Square = Square(51);
859
860    /// The E7 square on the chess board
861    ///
862    /// ```
863    /// use chess::{Square, Rank, File};
864    ///
865    /// assert_eq!(Square::E7, Square::make_square(Rank::Seventh, File::E));
866    /// ```
867    pub const E7: Square = Square(52);
868
869    /// The F7 square on the chess board
870    ///
871    /// ```
872    /// use chess::{Square, Rank, File};
873    ///
874    /// assert_eq!(Square::F7, Square::make_square(Rank::Seventh, File::F));
875    /// ```
876    pub const F7: Square = Square(53);
877
878    /// The G7 square on the chess board
879    ///
880    /// ```
881    /// use chess::{Square, Rank, File};
882    ///
883    /// assert_eq!(Square::G7, Square::make_square(Rank::Seventh, File::G));
884    /// ```
885    pub const G7: Square = Square(54);
886
887    /// The H7 square on the chess board
888    ///
889    /// ```
890    /// use chess::{Square, Rank, File};
891    ///
892    /// assert_eq!(Square::H7, Square::make_square(Rank::Seventh, File::H));
893    /// ```
894    pub const H7: Square = Square(55);
895
896    /// The A8 square on the chess board
897    ///
898    /// ```
899    /// use chess::{Square, Rank, File};
900    ///
901    /// assert_eq!(Square::A8, Square::make_square(Rank::Eighth, File::A));
902    /// ```
903    pub const A8: Square = Square(56);
904
905    /// The B8 square on the chess board
906    ///
907    /// ```
908    /// use chess::{Square, Rank, File};
909    ///
910    /// assert_eq!(Square::B8, Square::make_square(Rank::Eighth, File::B));
911    /// ```
912    pub const B8: Square = Square(57);
913
914    /// The C8 square on the chess board
915    ///
916    /// ```
917    /// use chess::{Square, Rank, File};
918    ///
919    /// assert_eq!(Square::C8, Square::make_square(Rank::Eighth, File::C));
920    /// ```
921    pub const C8: Square = Square(58);
922
923    /// The D8 square on the chess board
924    ///
925    /// ```
926    /// use chess::{Square, Rank, File};
927    ///
928    /// assert_eq!(Square::D8, Square::make_square(Rank::Eighth, File::D));
929    /// ```
930    pub const D8: Square = Square(59);
931
932    /// The E8 square on the chess board
933    ///
934    /// ```
935    /// use chess::{Square, Rank, File};
936    ///
937    /// assert_eq!(Square::E8, Square::make_square(Rank::Eighth, File::E));
938    /// ```
939    pub const E8: Square = Square(60);
940
941    /// The F8 square on the chess board
942    ///
943    /// ```
944    /// use chess::{Square, Rank, File};
945    ///
946    /// assert_eq!(Square::F8, Square::make_square(Rank::Eighth, File::F));
947    /// ```
948    pub const F8: Square = Square(61);
949
950    /// The G8 square on the chess board
951    ///
952    /// ```
953    /// use chess::{Square, Rank, File};
954    ///
955    /// assert_eq!(Square::G8, Square::make_square(Rank::Eighth, File::G));
956    /// ```
957    pub const G8: Square = Square(62);
958
959    /// The H8 square on the chess board
960    ///
961    /// ```
962    /// use chess::{Square, Rank, File};
963    ///
964    /// assert_eq!(Square::H8, Square::make_square(Rank::Eighth, File::H));
965    /// ```
966    pub const H8: Square = Square(63);
967}
968
969impl fmt::Display for Square {
970    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
971        write!(
972            f,
973            "{}{}",
974            (('a' as u8) + ((self.0 & 7) as u8)) as char,
975            (('1' as u8) + ((self.0 >> 3) as u8)) as char
976        )
977    }
978}
979
980impl FromStr for Square {
981    type Err = Error;
982
983    fn from_str(s: &str) -> Result<Self, Self::Err> {
984        if s.len() < 2 {
985            return Err(Error::InvalidSquare);
986        }
987        let ch: Vec<char> = s.chars().collect();
988        match ch[0] {
989            'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' => {}
990            _ => {
991                return Err(Error::InvalidSquare);
992            }
993        }
994        match ch[1] {
995            '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' => {}
996            _ => {
997                return Err(Error::InvalidSquare);
998            }
999        }
1000        Ok(Square::make_square(
1001            Rank::from_index((ch[1] as usize) - ('1' as usize)),
1002            File::from_index((ch[0] as usize) - ('a' as usize)),
1003        ))
1004    }
1005}
1006
1007/// A list of every square on the chessboard.
1008///
1009/// ```
1010/// use chess::{ALL_SQUARES, BitBoard, EMPTY};
1011///
1012/// let universe = !EMPTY;
1013///
1014/// let mut new_universe = EMPTY;
1015///
1016/// for sq in ALL_SQUARES.iter() {
1017///     new_universe ^= BitBoard::from_square(*sq);
1018/// }
1019///
1020/// assert_eq!(new_universe, universe);
1021/// ```
1022pub const ALL_SQUARES: [Square; 64] = [
1023    Square(0),
1024    Square(1),
1025    Square(2),
1026    Square(3),
1027    Square(4),
1028    Square(5),
1029    Square(6),
1030    Square(7),
1031    Square(8),
1032    Square(9),
1033    Square(10),
1034    Square(11),
1035    Square(12),
1036    Square(13),
1037    Square(14),
1038    Square(15),
1039    Square(16),
1040    Square(17),
1041    Square(18),
1042    Square(19),
1043    Square(20),
1044    Square(21),
1045    Square(22),
1046    Square(23),
1047    Square(24),
1048    Square(25),
1049    Square(26),
1050    Square(27),
1051    Square(28),
1052    Square(29),
1053    Square(30),
1054    Square(31),
1055    Square(32),
1056    Square(33),
1057    Square(34),
1058    Square(35),
1059    Square(36),
1060    Square(37),
1061    Square(38),
1062    Square(39),
1063    Square(40),
1064    Square(41),
1065    Square(42),
1066    Square(43),
1067    Square(44),
1068    Square(45),
1069    Square(46),
1070    Square(47),
1071    Square(48),
1072    Square(49),
1073    Square(50),
1074    Square(51),
1075    Square(52),
1076    Square(53),
1077    Square(54),
1078    Square(55),
1079    Square(56),
1080    Square(57),
1081    Square(58),
1082    Square(59),
1083    Square(60),
1084    Square(61),
1085    Square(62),
1086    Square(63),
1087];