c4_e5_chess/misc/
helpers.rs

1use cozy_chess::{util, Board};
2use std::str::FromStr;
3
4/// Parse EPD (Extended Position Description)
5/// EPD parsing is not comprehensive, but it is enough to be used in some tests.
6#[allow(dead_code)]
7pub fn parse_epd(epd: String) -> (String, Vec<String>, bool) {
8    // remove everything from the string after the first semicolon
9    let epd = epd.split(';').next().expect("Cannot parse EPD.");
10    let find_best_move: bool = epd.contains("bm");
11    let delimiter = if find_best_move { " bm " } else { " am " };
12    let mut s = epd.split(delimiter);
13    let fen = s.next().expect("Cannot parse EPD.");
14    let fen = format!("{} 0 1", fen);
15    let board = Board::from_str(&fen).expect("Invalid board.");
16
17    let expected_moves_s = s.next().expect("Cannot parse EPD.");
18    let expected_moved: Vec<&str> = expected_moves_s.split(' ').collect();
19    let mut valid_best_moves = Vec::new();
20
21    for best_move in expected_moved {
22        let best_move = best_move.trim();
23        let mv = util::parse_san_move(&board, best_move).expect("Invalid move.");
24        valid_best_moves.push(mv.to_string());
25    }
26    (fen.to_string(), valid_best_moves, find_best_move)
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn test_parse_epd() {
35        let epd =
36            "r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - bm Bxh6; id \"11.IQ.1263\";";
37        let (fen, expected_moves, find_best_move) = parse_epd(epd.to_string());
38        assert_eq!(
39            fen,
40            "r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - 0 1"
41        );
42        assert_eq!(expected_moves, vec!["c1h6".to_string()]);
43        assert_eq!(find_best_move, true);
44
45        let epd = "r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - bm Bxh6";
46        let (fen, expected_moves, find_best_move) = parse_epd(epd.to_string());
47        assert_eq!(
48            fen,
49            "r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - 0 1"
50        );
51        assert_eq!(expected_moves, vec!["c1h6".to_string()]);
52        assert_eq!(find_best_move, true);
53
54        let epd = "r1b2rk1/ppp3p1/4p2p/4Qpq1/3P4/2PB4/PPK2PPP/R6R b - - am Qxg2";
55        let (fen, expected_moves, find_best_move) = parse_epd(epd.to_string());
56        assert_eq!(
57            fen,
58            "r1b2rk1/ppp3p1/4p2p/4Qpq1/3P4/2PB4/PPK2PPP/R6R b - - 0 1"
59        );
60        assert_eq!(expected_moves, vec!["g5g2".to_string()]);
61        assert_eq!(find_best_move, false);
62
63        let epd = "r1b2k1r/1p4pp/p4B2/2bpN3/8/q2n4/P1P2PPP/1R1QR1K1 w - - bm Bxg7+ Qh5; id \"5.IQ.1244\";";
64        let (fen, expected_moves, find_best_move) = parse_epd(epd.to_string());
65        assert_eq!(
66            fen,
67            "r1b2k1r/1p4pp/p4B2/2bpN3/8/q2n4/P1P2PPP/1R1QR1K1 w - - 0 1"
68        );
69        assert!(
70            expected_moves == vec!["f6g7".to_string(), "d1h5".to_string()]
71                || expected_moves == vec!["d1h5".to_string(), "f6g7".to_string()]
72        );
73        assert_eq!(find_best_move, true);
74    }
75}