c4_e5_chess/eval/
simple.rs1use super::{constants::*, evaluation::Evaluation, helpers::*};
2use crate::misc::types::*;
3use cozy_chess::{Board, Color, Piece};
4
5#[derive(Default)]
6pub struct Simple {}
7
8impl Evaluation for Simple {
9 fn evaluate(b: &Board) -> MoveScore {
12 let mut value: MoveScore = 0;
13 let pieces_count = b.occupied().len();
14
15 let b_open_files = open_files(b);
16 let b_half_open_files = half_open_files(b);
17
18 let (color_attack, color_defend, rank1, rank2, rank3, rank6, rank7, rank8) =
19 if b.side_to_move() == Color::White {
20 (
21 Color::White,
22 Color::Black,
23 CB_RANK_1,
24 CB_RANK_2,
25 CB_RANK_3,
26 CB_RANK_6,
27 CB_RANK_7,
28 CB_RANK_8,
29 )
30 } else {
31 (
32 Color::Black,
33 Color::White,
34 CB_RANK_8,
35 CB_RANK_7,
36 CB_RANK_6,
37 CB_RANK_3,
38 CB_RANK_2,
39 CB_RANK_1,
40 )
41 };
42
43 value += (b.colored_pieces(color_attack, Piece::Pawn).0.count_ones() * 200) as MoveScore;
45 value -= (b.colored_pieces(color_defend, Piece::Pawn).0.count_ones() * 200) as MoveScore;
46
47 value += ((b.colored_pieces(color_attack, Piece::Pawn).0 & CB_CENTER_0_GOOD).count_ones()
48 * 15) as MoveScore;
49 value -= ((b.colored_pieces(color_defend, Piece::Pawn).0 & CB_CENTER_0_GOOD).count_ones()
50 * 15) as MoveScore;
51
52 value += ((b.colored_pieces(color_attack, Piece::Pawn).0 & CB_CENTER_1).count_ones() * 30)
53 as MoveScore;
54 value -= ((b.colored_pieces(color_defend, Piece::Pawn).0 & CB_CENTER_1).count_ones() * 30)
55 as MoveScore;
56
57 value += ((b.colored_pieces(color_attack, Piece::Pawn).0 & rank6).count_ones() * 50)
58 as MoveScore;
59 value -= ((b.colored_pieces(color_defend, Piece::Pawn).0 & rank3).count_ones() * 50)
60 as MoveScore;
61
62 value += ((b.colored_pieces(color_attack, Piece::Pawn).0 & rank7).count_ones() * 650)
63 as MoveScore;
64 value -= ((b.colored_pieces(color_defend, Piece::Pawn).0 & rank2).count_ones() * 650)
65 as MoveScore;
66
67 value -=
68 (multiple_on_file(b.colored_pieces(color_attack, Piece::Pawn).0) * 30) as MoveScore;
69 value +=
70 (multiple_on_file(b.colored_pieces(color_defend, Piece::Pawn).0) * 30) as MoveScore;
71
72 value += (b.colored_pieces(color_attack, Piece::Knight).0.count_ones() * 600) as MoveScore;
74 value -= (b.colored_pieces(color_defend, Piece::Knight).0.count_ones() * 600) as MoveScore;
75
76 value -= ((b.colored_pieces(color_attack, Piece::Knight).0 & CB_BOARD_0).count_ones() * 29)
77 as MoveScore;
78 value += ((b.colored_pieces(color_defend, Piece::Knight).0 & CB_BOARD_0).count_ones() * 29)
79 as MoveScore;
80
81 value += (b.colored_pieces(color_attack, Piece::Bishop).0.count_ones() * 620) as MoveScore;
83 value -= (b.colored_pieces(color_defend, Piece::Bishop).0.count_ones() * 620) as MoveScore;
84
85 value += (b.colored_pieces(color_attack, Piece::Rook).0.count_ones() * 950) as MoveScore;
87 value -= (b.colored_pieces(color_defend, Piece::Rook).0.count_ones() * 950) as MoveScore;
88
89 value += ((b.colored_pieces(color_attack, Piece::Rook).0 & b_open_files).count_ones() * 40)
90 as MoveScore;
91 value -= ((b.colored_pieces(color_defend, Piece::Rook).0 & b_open_files).count_ones() * 40)
92 as MoveScore;
93
94 value += ((b.colored_pieces(color_attack, Piece::Rook).0 & b_half_open_files).count_ones()
95 * 10) as MoveScore;
96 value -= ((b.colored_pieces(color_defend, Piece::Rook).0 & b_half_open_files).count_ones()
97 * 10) as MoveScore;
98
99 value += ((b.colored_pieces(color_attack, Piece::Rook).0 & rank7).count_ones() * 80)
100 as MoveScore;
101 value -= ((b.colored_pieces(color_defend, Piece::Rook).0 & rank2).count_ones() * 80)
102 as MoveScore;
103
104 value += (b.colored_pieces(color_attack, Piece::Queen).0.count_ones() * 1800) as MoveScore;
106 value -= (b.colored_pieces(color_defend, Piece::Queen).0.count_ones() * 1800) as MoveScore;
107
108 value -= ((b.colored_pieces(color_attack, Piece::Queen).0 & CB_CENTER).count_ones() * 30)
109 as MoveScore;
110 value += ((b.colored_pieces(color_defend, Piece::Queen).0 & CB_CENTER).count_ones() * 30)
111 as MoveScore;
112
113 if pieces_count > 20 {
114 value -= ((b.colored_pieces(color_attack, Piece::Knight).0 & rank1).count_ones() * 51)
115 as MoveScore;
116 value += ((b.colored_pieces(color_defend, Piece::Knight).0 & rank8).count_ones() * 51)
117 as MoveScore;
118
119 value -= ((b.colored_pieces(color_attack, Piece::Bishop).0 & rank1).count_ones() * 100)
120 as MoveScore;
121 value += ((b.colored_pieces(color_defend, Piece::Bishop).0 & rank8).count_ones() * 100)
122 as MoveScore;
123
124 value += ((b.colored_pieces(color_attack, Piece::Bishop).0 & CB_GOOD_BISHOP)
125 .count_ones()
126 * 20) as MoveScore;
127 value -= ((b.colored_pieces(color_defend, Piece::Bishop).0 & CB_GOOD_BISHOP)
128 .count_ones()
129 * 20) as MoveScore;
130
131 value += ((b.colored_pieces(color_attack, Piece::Queen).0 & CB_GOOD_QUEEN).count_ones()
132 * 30) as MoveScore;
133 value -= ((b.colored_pieces(color_defend, Piece::Queen).0 & CB_GOOD_QUEEN).count_ones()
134 * 30) as MoveScore;
135
136 value += ((b.colored_pieces(color_attack, Piece::King).0 & CB_SAFE_KING).count_ones()
137 * 150) as MoveScore;
138 value -= ((b.colored_pieces(color_defend, Piece::King).0 & CB_SAFE_KING).count_ones()
139 * 150) as MoveScore;
140 }
141
142 if pieces_count < 8 {
143 let mut kings_value: MoveScore = kings_distance(b) * -10;
144 kings_value -= defending_kings_moves_count(b) as MoveScore * 10;
145 kings_value -= ((b.colored_pieces(color_defend, Piece::King).0 & CB_CENTER_0)
146 .count_ones()
147 * 80) as MoveScore;
148 kings_value -= ((b.colored_pieces(color_defend, Piece::King).0 & CB_CENTER_1)
149 .count_ones()
150 * 40) as MoveScore;
151 kings_value -= ((b.colored_pieces(color_defend, Piece::King).0 & CB_BOARD_1)
152 .count_ones()
153 * 10) as MoveScore;
154 kings_value += ((b.colored_pieces(color_defend, Piece::King).0 & CB_BOARD_0)
155 .count_ones()
156 * 50) as MoveScore;
157 value += kings_value;
158 }
159
160 value
161 }
162}
163#[cfg(test)]
164mod tests {
165 use super::*;
166 use cozy_chess::Board;
167 use std::str::FromStr;
168
169 #[test]
170 fn test_evaluate() {
171 let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
172 let board = Board::from_str(fen).unwrap();
173 let score = Simple::evaluate(&board);
174 assert_eq!(score, 0); let fen = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1";
177 let board = Board::from_str(fen).unwrap();
178 let score = Simple::evaluate(&board);
179 assert_eq!(score, -30); let fen = "rnbqkbnr/ppp1pppp/8/8/3Pp3/8/PPP2PPP/RNBQKBNR w KQkq - 0 1";
182 let board = Board::from_str(fen).unwrap();
183 let score = Simple::evaluate(&board);
184 assert!(score < 0); let fen = "rn1qk1nr/pppbbppp/8/3pp3/3PP3/1P4P1/PBP2PBP/RN1QK1NR w KQkq - 0 1";
187 let board = Board::from_str(fen).unwrap();
188 let score = Simple::evaluate(&board);
189 assert!(score > 0); let fen = "rn1qk1nr/pppbbppp/8/3pp3/3PP3/1P4P1/PBP2PBP/RN1QK1NR b KQkq - 0 1";
192 let board = Board::from_str(fen).unwrap();
193 let score = Simple::evaluate(&board);
194 assert!(score < 0); let fen = "rn1qk1nr/pbp2pbp/1p4p1/3pp3/3PP3/8/PPPBBPPP/RN1QK1NR w KQkq - 0 1";
197 let board = Board::from_str(fen).unwrap();
198 let score = Simple::evaluate(&board);
199 assert!(score < 0); let fen = "rn1qk1nr/pbp2pbp/1p4p1/3pp3/3PP3/8/PPPBBPPP/RN1QK1NR b KQkq - 0 1";
202 let board = Board::from_str(fen).unwrap();
203 let score = Simple::evaluate(&board);
204 assert!(score > 0); let fen_n = "8/8/4k3/8/3R4/4K3/8/8 w - - 0 1";
207 let fen_f = "8/8/4k3/8/3R4/8/8/4K3 w - - 0 1";
208 let board_n = Board::from_str(fen_n).unwrap();
209 let board_f = Board::from_str(fen_f).unwrap();
210 let score_n = Simple::evaluate(&board_n);
211 let score_f = Simple::evaluate(&board_f);
212 assert!(score_n > score_f); let fen_n = "8/8/4k3/8/3R4/4K3/8/8 b - - 0 1";
215 let fen_f = "8/8/4k3/8/3R4/8/8/4K3 b - - 0 1";
216 let board_n = Board::from_str(fen_n).unwrap();
217 let board_f = Board::from_str(fen_f).unwrap();
218 let score_n = Simple::evaluate(&board_n);
219 let score_f = Simple::evaluate(&board_f);
220 assert!(score_n < score_f); let fen_n = "8/8/5b2/5b2/5k2/8/8/5K2 b - - 0 1";
223 let fen_f = "8/5k2/5b2/5b2/8/8/8/5K2 b - - 0 1";
224 let board_n = Board::from_str(fen_n).unwrap();
225 let board_f = Board::from_str(fen_f).unwrap();
226 let score_n = Simple::evaluate(&board_n);
227 let score_f = Simple::evaluate(&board_f);
228 assert!(score_n > score_f); let fen_n = "8/8/5b2/5b2/5k2/8/8/5K2 w - - 0 1";
231 let fen_f = "8/5k2/5b2/5b2/8/8/8/5K2 w - - 0 1";
232 let board_n = Board::from_str(fen_n).unwrap();
233 let board_f = Board::from_str(fen_f).unwrap();
234 let score_n = Simple::evaluate(&board_n);
235 let score_f = Simple::evaluate(&board_f);
236 assert!(score_n < score_f); }
238}