~bfiedler/rschess

fb57937b3b793c64a93ca11a6d1742424df3a311 — Ben Fiedler 1 year, 7 months ago 359c8e6
Move perft and verbose_perft to search.rs
6 files changed, 67 insertions(+), 48 deletions(-)

M benches/perft.rs
M src/lib.rs
M src/main.rs
M src/position.rs
A src/search.rs
M tests/perft.rs
M benches/perft.rs => benches/perft.rs +3 -1
@@ 4,6 4,7 @@ extern crate bencher;
use bencher::Bencher;

use rschess::parse::parse_fen;
use rschess::search::Node;

macro_rules! perft_bench {
    ($name:ident, $fen:expr, $depth:expr) => {


@@ 12,7 13,8 @@ macro_rules! perft_bench {
    ($name:ident, $fen:expr, $depth:expr, $sample_size:expr) => {
        fn $name(b: &mut Bencher) {
            let p = parse_fen($fen);
            b.iter(|| p.perft($depth))
            let n = Node { pos: p };
            b.iter(|| n.perft($depth))
        }
    };
}

M src/lib.rs => src/lib.rs +1 -0
@@ 4,4 4,5 @@ extern crate bitflags;
pub mod bitboard;
pub mod parse;
pub mod position;
pub mod search;
pub mod types;

M src/main.rs => src/main.rs +4 -1
@@ 7,9 7,11 @@ mod bitboard;
mod parse;
mod position;
mod types;
mod search;

use parse::*;
use types::*;
use search::*;

fn main() {
    let args: Vec<String> = env::args().collect();


@@ 57,7 59,8 @@ fn main() {
        p.make_move(newmv);
    }
    dbg!(p);
    let (cnt, mvs) = p.verbose_perft(depth);
    let n = Node { pos: p };
    let (cnt, mvs) = n.verbose_perft(depth);
    for mv in mvs {
        println!("{}", mv);
    }

M src/position.rs => src/position.rs +1 -44
@@ 5,19 5,7 @@ use crate::types::*;

use lazy_static::lazy_static;

const INITIAL_MOVE_NUM: usize = 64;

#[derive(Copy, Clone)]
pub struct DivideMove {
    mv: Move,
    cnt: u64,
}

impl fmt::Display for DivideMove {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{} {}", self.mv, self.cnt)
    }
}
pub const INITIAL_MOVE_NUM: usize = 64;

#[derive(Copy, Clone)]
pub struct Move(u16);


@@ 194,37 182,6 @@ impl Position {
        self.bb_by_color[c as usize] & self.bb_by_type[pt as usize]
    }

    pub fn perft(&self, depth: u32) -> u64 {
        if depth == 0 {
            return 1;
        } else if depth == 1 {
            return self.generate_legal_moves().len() as u64;
        }

        let mut cnt: u64 = 0;
        for mv in self.generate_legal_moves() {
            let mut copy = self.clone();
            copy.make_move(mv);
            cnt += copy.perft(depth - 1);
        }
        cnt
    }

    pub fn verbose_perft(&self, depth: u32) -> (u64, Vec<DivideMove>) {
        let mut moves = Vec::with_capacity(INITIAL_MOVE_NUM);
        let mut cnt: u64 = 0;

        for mv in self.generate_legal_moves() {
            let mut copy = self.clone();
            copy.make_move(mv);
            let num = copy.perft(depth - 1);
            cnt += num;
            moves.push(DivideMove { mv: mv, cnt: num })
        }

        (cnt, moves)
    }

    pub fn make_move(&mut self, mv: Move) {
        let (from, to) = mv.from_to();
        let pc = self.get_piece(from);

A src/search.rs => src/search.rs +53 -0
@@ 0,0 1,53 @@
use crate::position::*;

use std::fmt;

#[derive(Copy, Clone)]
pub struct PerftMove {
    mv: Move,
    cnt: u64,
}

impl fmt::Display for PerftMove {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{} {}", self.mv, self.cnt)
    }
}

#[derive(Debug, Copy, Clone)]
pub struct Node {
    pub pos: Position,
}

impl Node {
    pub fn perft(&self, depth: u32) -> u64 {
        if depth == 0 {
            return 1;
        } else if depth == 1 {
            return self.pos.generate_legal_moves().len() as u64;
        }

        let mut cnt: u64 = 0;
        for mv in self.pos.generate_legal_moves() {
            let mut copy = self.clone();
            copy.pos.make_move(mv);
            cnt += copy.perft(depth - 1);
        }
        cnt
    }

    pub fn verbose_perft(&self, depth: u32) -> (u64, Vec<PerftMove>) {
        let mut moves = Vec::with_capacity(INITIAL_MOVE_NUM);
        let mut cnt: u64 = 0;

        for mv in self.pos.generate_legal_moves() {
            let mut copy = self.clone();
            copy.pos.make_move(mv);
            let num = copy.perft(depth - 1);
            cnt += num;
            moves.push(PerftMove { mv: mv, cnt: num })
        }

        (cnt, moves)
    }
}

M tests/perft.rs => tests/perft.rs +5 -2
@@ 1,11 1,13 @@
use rschess::parse::parse_fen;
use rschess::search::Node;

macro_rules! perft_test {
    ($name:ident, $fen:expr, $depth:expr, $exp:expr)  => {
        #[test]
        fn $name() {
            let p = parse_fen($fen);
            assert_eq!(p.perft($depth), $exp);
            let n = Node { pos: p };
            assert_eq!(n.perft($depth), $exp);
        }
    };
    ($name:ident, $fen:expr, $depth:expr, $exp:expr, true)  => {


@@ 13,7 15,8 @@ macro_rules! perft_test {
        #[ignore]
        fn $name() {
            let p = parse_fen($fen);
            assert_eq!(p.perft($depth), $exp);
            let n = Node { pos: p };
            assert_eq!(n.perft($depth), $exp);
        }
    };
}