hexe_core 0.0.5

The core components of the hexe chess engine crate.
Documentation
use super::{Piece, PieceMap};

use test::{Bencher, black_box};
use rand;

use castle::Right;
use iter::All;
use square::Square;

macro_rules! piece_map {
    ($($s:expr => $p:expr),* $(,)*) => {
        {
            #[allow(unused_mut)]
            let mut map = PieceMap::new();
            $(map.insert($s, $p);)*
            map
        }
    }
}

fn find_naive_impl(piece: Piece, map: &PieceMap) -> Option<Square> {
    for (i, &slot) in map.as_bytes().iter().enumerate() {
        if slot == piece as u8 {
            return Some(i.into())
        }
    }
    None
}

fn contains_helper<F: Fn(&PieceMap, Piece) -> bool>(b: &mut Bencher, f: F) {
    let pc  = Piece::BlackKing;
    let map = piece_map! { Square::H8 => pc };
    b.iter(|| {
        black_box(f(black_box(&map), black_box(pc)));
    });
}

#[bench]
fn contains_piece(b: &mut Bencher) {
    contains_helper(b, |map, pc| map.contains(pc));
}

#[bench]
fn contains_piece_naive(b: &mut Bencher) {
    contains_helper(b, |map, pc| map.as_bytes().contains(&(pc as u8)));
}

#[bench]
fn find(b: &mut Bencher) {
    let piece = Piece::WhiteRook;
    let map = piece_map! { Square::H8 => piece };

    b.iter(|| {
        black_box(black_box(&map).find(black_box(piece)));
    });
}

#[bench]
fn find_naive(b: &mut Bencher) {
    let piece = Piece::WhiteRook;
    let map = piece_map! { Square::H8 => piece };

    b.iter(|| {
        black_box(find_naive_impl(black_box(piece), black_box(&map)));
    });
}

#[bench]
fn rfind(b: &mut Bencher) {
    let piece = Piece::WhiteRook;
    let map = piece_map! { Square::A1 => piece };

    b.iter(|| {
        black_box(black_box(&map).rfind(black_box(piece)));
    });
}

#[bench]
fn iter_len(b: &mut Bencher) {
    let map = PieceMap::STANDARD;
    let mut iter = map.iter();

    iter.next();
    iter.next_back();

    b.iter(|| {
        black_box(black_box(&iter).len());
    });
}

#[bench]
fn len_1000(b: &mut Bencher) {
    let mut map = PieceMap::STANDARD;
    map.shuffle(&mut rand::thread_rng());
    b.iter(|| {
        for _ in 0..1000 {
            black_box(black_box(&map).len());
        }
    });
}

#[bench]
fn len_naive_1000(b: &mut Bencher) {
    fn len(map: &PieceMap) -> usize {
        map.as_bytes().iter().fold(64, |len, &pc| {
            len - (pc == 12) as usize
        })
    }

    let mut map = PieceMap::STANDARD;
    map.shuffle(&mut rand::thread_rng());

    assert_eq!(map.len(), len(&map));

    b.iter(|| {
        for _ in 0..1000 {
            black_box(len(black_box(&map)));
        }
    });
}

#[bench]
fn is_empty_1000(b: &mut Bencher) {
    let map = piece_map!();
    b.iter(|| {
        for _ in 0..1000 {
            black_box(black_box(&map).is_empty());
        }
    });
}

#[bench]
fn eq(b: &mut Bencher) {
    let x = piece_map!();
    let y = piece_map!();
    b.iter(|| {
        black_box(black_box(&x) == black_box(&y));
    });
}

#[bench]
fn fen(b: &mut Bencher) {
    let map = PieceMap::STANDARD;
    b.iter(|| {
        black_box(&map).map_str(|s| {
            black_box(s);
        });
    });
}

#[bench]
fn castle_all(b: &mut Bencher) {
    b.iter(|| {
        let mut map = PieceMap::EMPTY;
        for right in Right::ALL {
            black_box(&mut map).castle(right);
        }
        black_box(&map);
    });
}