chess_move_gen/mv_list/
mv_vec.rs1use crate::bb::{BB, END_ROWS};
2use crate::castle::Castle;
3use crate::mv::Move;
4use crate::mv_list::MoveAdder;
5use crate::piece::*;
6use crate::square::{Square, SquareInternal};
7use std;
8use std::fmt;
9
10#[derive(Clone)]
13pub struct MoveVec {
14 moves: Vec<Move>,
15}
16
17impl fmt::Display for MoveVec {
18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19 write!(
20 f,
21 "{}",
22 self.iter()
23 .map(|mv: &Move| mv.to_string())
24 .collect::<Vec<String>>()
25 .join(", ")
26 )
27 }
28}
29
30impl fmt::Debug for MoveVec {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 write!(
33 f,
34 "{}",
35 self.iter()
36 .map(|mv: &Move| mv.to_string())
37 .collect::<Vec<String>>()
38 .join(", ")
39 )
40 }
41}
42
43impl MoveAdder for MoveVec {
44 fn add_captures(&mut self, from: Square, targets: BB) {
45 self.insert_moves(from, targets, Move::new_capture);
46 }
47
48 fn add_non_captures(&mut self, from: Square, targets: BB) {
49 self.insert_moves(from, targets, Move::new_push);
50 }
51
52 fn add_castle(&mut self, castle: Castle) {
53 self.moves.push(Move::new_castle(castle));
54 }
55
56 fn add_pawn_ep_capture(&mut self, from: Square, to: Square) {
57 self.moves.push(Move::new_ep_capture(from, to));
58 }
59
60 fn add_pawn_pushes(&mut self, shift: usize, targets: BB) {
61 self.insert_promos_by_shift(shift, targets & END_ROWS, Move::new_promotion);
62 self.insert_moves_by_shift(shift, targets & !END_ROWS, Move::new_push);
63 }
64
65 fn add_pawn_captures(&mut self, shift: usize, targets: BB) {
66 self.insert_promos_by_shift(shift, targets & END_ROWS, Move::new_capture_promotion);
67 self.insert_moves_by_shift(shift, targets & !END_ROWS, Move::new_capture);
68 }
69}
70
71impl Default for MoveVec {
72 fn default() -> Self {
73 Self::new()
74 }
75}
76
77impl MoveVec {
78 pub fn new() -> MoveVec {
79 MoveVec {
80 moves: Vec::with_capacity(60),
81 }
82 }
83
84 pub fn iter(&self) -> std::slice::Iter<Move> {
85 self.moves.iter()
86 }
87
88 fn insert_moves<F: Fn(Square, Square) -> Move>(&mut self, from: Square, targets: BB, f: F) {
89 for (to, _) in targets.iter() {
90 self.moves.push(f(from, to));
91 }
92 }
93
94 fn insert_moves_by_shift<F: Fn(Square, Square) -> Move>(
95 &mut self,
96 shift: usize,
97 targets: BB,
98 f: F,
99 ) {
100 for (to, _) in targets.iter() {
101 let from = to.rotate_right(shift as SquareInternal);
102 self.moves.push(f(from, to));
103 }
104 }
105
106 pub fn len(&self) -> usize {
107 self.moves.len()
108 }
109
110 #[allow(dead_code)]
111 pub fn is_empty(&self) -> bool {
112 self.len() == 0
113 }
114
115 fn insert_promos_by_shift<F: Fn(Square, Square, Kind) -> Move>(
116 &mut self,
117 shift: usize,
118 targets: BB,
119 f: F,
120 ) {
121 for (to, _) in targets.iter() {
122 let from = to.rotate_right(shift as SquareInternal);
123 self.moves.push(f(from, to, QUEEN));
124 self.moves.push(f(from, to, KNIGHT));
125 self.moves.push(f(from, to, BISHOP));
126 self.moves.push(f(from, to, ROOK));
127 }
128 }
129}
130
131#[cfg(test)]
132mod test {
133 use super::*;
134 use crate::generation::*;
135 use crate::position::*;
136
137 #[test]
138 fn test_move_vec() {
139 let position = &Position::from_fen(STARTING_POSITION_FEN).unwrap();
140 let mut list = MoveVec::new();
141
142 legal_moves(&position, &mut list);
143
144 assert_eq!(list.len(), 20);
145 }
146}