1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use super::{piece, position, sliding_attacks, sliding_moves};
use crate::{board, chessmove, color};
#[derive(Debug)]
pub struct Queen {
pub color: color::Color,
pub position: position::Position,
}
impl piece::Piece for Queen {
fn color(&self) -> &color::Color {
&self.color
}
fn position(&self) -> &position::Position {
&self.position
}
fn mut_position(&mut self) -> &mut position::Position {
&mut self.position
}
fn piece(&self) -> piece::PieceEnum {
piece::PieceEnum::QUEEN
}
fn moves_ignoring_pins(
&self,
board: &board::Board,
_en_passant: &Option<position::Position>,
_king_pos: position::Position,
) -> Vec<chessmove::ChessMove> {
let mut straight_moves = sliding_moves::straight_sliding(self, board);
let mut diagonal_moves = sliding_moves::diagonal_sliding(self, board);
straight_moves.append(&mut diagonal_moves);
straight_moves
}
fn attacks(
&self,
board: &board::Board,
enemy_king_pos: position::Position,
) -> Vec<position::Position> {
let mut straight_attacks =
sliding_attacks::straight_attacks(self.position, board, enemy_king_pos);
let mut diagonal_attacks =
sliding_attacks::diagonal_attacks(self.position, board, enemy_king_pos);
straight_attacks.append(&mut diagonal_attacks);
straight_attacks
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::iter;
#[test]
fn queen_bottom_left() {
let mut empty_board = board::Board::empty();
let position = position::Position(1, 1);
let queen = Queen {
color: color::Color::WHITE,
position,
};
empty_board.set_square(Some(Box::new(queen)), position);
let queen = match empty_board.get_square(position) {
None => panic!(),
Some(b) => b,
};
let attacked_positions = queen.attacks(&empty_board, position::Position(0, 0));
let mut count_file = 1;
let expected_attacked_positions = iter::from_fn(|| {
count_file += 1;
if count_file < 9 {
Some(position::Position(count_file, queen.position().1))
} else {
None
}
});
let mut count_rank = 1;
let expected_attacked_positions = expected_attacked_positions.chain(iter::from_fn(|| {
count_rank += 1;
if count_rank < 9 {
Some(position::Position(queen.position().0, count_rank))
} else {
None
}
}));
let mut count_diagonal = 1;
let expected_attacked_positions = expected_attacked_positions.chain(iter::from_fn(|| {
count_diagonal += 1;
if count_diagonal < 9 {
Some(position::Position(count_diagonal, count_diagonal))
} else {
None
}
}));
assert_eq!(
expected_attacked_positions.collect::<Vec<_>>(),
attacked_positions
);
}
}