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