chess-vector-engine 0.5.1

Open source chess engine with hybrid vector-based position analysis, advanced tactical search, and NNUE neural network evaluation
Documentation
use chess::Board;
use chess_vector_engine::{TacticalSearch, TacticalConfig};
use std::str::FromStr;
use std::time::Instant;

fn main() {
    println!("Tactical Search Optimization Benchmark");
    println!("=====================================");

    // Test positions with varying complexity
    let test_positions = vec![
        ("Starting Position", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"),
        ("Sicilian Defense", "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2"),
        ("Middle Game", "r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4"),
        ("Complex Tactical", "r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1"),
        ("Endgame", "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1"),
    ];

    // Test configurations
    let configs = vec![
        ("Standard", TacticalConfig::default()),
        ("Fast", TacticalConfig::fast()),
        ("Ultra Fast", TacticalConfig::ultra_fast()),
        ("Optimized", TacticalConfig::ultra_optimized()),
    ];

    for (config_name, config) in &configs {
        println!("\n=== {} Configuration ===", config_name);
        println!("Max depth: {}, Time limit: {}ms", config.max_depth, config.max_time_ms);
        
        let mut total_nodes = 0u64;
        let mut total_time = 0u128;
        let mut search_engine = TacticalSearch::new(config.clone());
        
        for (name, fen) in &test_positions {
            let board = Board::from_str(fen).unwrap();
            
            // Warm up
            for _ in 0..3 {
                let _ = search_engine.search(&board);
            }
            
            // Benchmark standard search
            let start = Instant::now();
            let result = search_engine.search(&board);
            let duration = start.elapsed();
            
            // Benchmark optimized search
            let start_opt = Instant::now();
            let result_opt = search_engine.search_optimized(&board);
            let duration_opt = start_opt.elapsed();
            
            println!("  {}", name);
            println!("    Standard: {} nodes, {}ms, eval: {:.2}", 
                     result.nodes_searched, duration.as_millis(), result.evaluation);
            println!("    Optimized: {} nodes, {}ms, eval: {:.2}", 
                     result_opt.nodes_searched, duration_opt.as_millis(), result_opt.evaluation);
            
            if duration.as_millis() > 0 {
                let standard_nps = (result.nodes_searched as f64) / (duration.as_millis() as f64) * 1000.0;
                let optimized_nps = (result_opt.nodes_searched as f64) / (duration_opt.as_millis() as f64) * 1000.0;
                println!("    Performance: {:.0} vs {:.0} nodes/sec ({:.1}x speedup)", 
                         standard_nps, optimized_nps, optimized_nps / standard_nps.max(1.0));
            }
            
            total_nodes += result_opt.nodes_searched;
            total_time += duration_opt.as_millis();
        }
        
        if total_time > 0 {
            let avg_nps = (total_nodes as f64) / (total_time as f64) * 1000.0;
            println!("  Average performance: {:.0} nodes/sec", avg_nps);
        }
    }

    // Performance comparison between different search methods
    println!("\n=== Search Method Comparison ===");
    let test_board = Board::from_str("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4").unwrap();
    let mut search_engine = TacticalSearch::new(TacticalConfig::fast());
    
    // Compare single-threaded vs parallel
    let start = Instant::now();
    let standard_result = search_engine.search(&test_board);
    let standard_time = start.elapsed();
    
    let start = Instant::now();
    let parallel_result = search_engine.search_parallel(&test_board);
    let parallel_time = start.elapsed();
    
    let start = Instant::now();
    let optimized_result = search_engine.search_optimized(&test_board);
    let optimized_time = start.elapsed();
    
    println!("Standard search: {} nodes in {}ms", standard_result.nodes_searched, standard_time.as_millis());
    println!("Parallel search: {} nodes in {}ms", parallel_result.nodes_searched, parallel_time.as_millis());
    println!("Optimized search: {} nodes in {}ms", optimized_result.nodes_searched, optimized_time.as_millis());
    
    if standard_time.as_millis() > 0 {
        let speedup = standard_time.as_millis() as f64 / optimized_time.as_millis().max(1) as f64;
        println!("Optimization speedup: {:.2}x", speedup);
    }
    
    println!("\n=== Tactical Search Optimization Complete ===");
    println!("✅ Enhanced move ordering with MVV-LVA and killer moves");
    println!("✅ Optimized minimax with advanced pruning techniques");
    println!("✅ Game phase-aware evaluation and time management");
    println!("✅ Improved transposition table utilization");
    println!("🚀 Ready for production use with enhanced performance");
}