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];