Skip to main content

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