use game::*; use bitboard::*; use movegen::*; use std::f32::*; pub type PosValue = f32; pub const MIN_VALUE: PosValue = -1000000.0f32; pub const MAX_VALUE: PosValue = 1000000.0f32; fn value_castling_rights(game: &Game, side: Side) -> PosValue { let mut val: PosValue = 0.0f32; for i in 0..2 { if game.castling_rights[i] { val += 12.0f32; } } for i in 2..4 { if game.castling_rights[i] { val -= 12.0f32; } } if side == BLACK { return -val; } else { return val; } } fn side_value(game: &Game, side: Side) -> u32 { let knights = game.get_piece(KNIGHT, side); let ks = BitboardIterator(knights); let mut k_attacks: u32 = 0; for k in ks { let targets = get_knight_targets(square(k)); k_attacks += targets.count_ones() * 4; } let adv_pawn_mask = match side { WHITE => ROW_7, BLACK => ROW_2 }; let advanced_pawns = (game.get_piece(PAWN, side) & adv_pawn_mask).count_ones() * 200; advanced_pawns + k_attacks } fn material_value(game: &Game, side: Side) -> PosValue { (game.get_piece(PAWN, side).count_ones() * 100 + game.get_piece(KNIGHT, side).count_ones() * 300 + game.get_piece(BISHOP, side).count_ones() * 320 + game.get_piece(ROOK, side).count_ones() * 400 + game.get_piece(QUEEN, side).count_ones() * 700) as PosValue } pub fn evaluate(game: &Game) -> PosValue { let sv = side_value(game, game.turn) as PosValue - side_value(game, !game.turn) as PosValue; let material_value_us = material_value(game, game.turn); let material_value_them = material_value(game, !game.turn); let mat_val = material_value_us.powf(0.995f32) - material_value_them.powf(0.995f32); return mat_val + value_castling_rights(game, game.turn); }