use std::env; use std::fs::File; use std::io::{self, BufRead, Write}; use std::process::{Command, Stdio}; fn read_game_log(log_file: &str) -> Option> { if let Ok(file) = File::open(log_file) { let lines: Result, _> = io::BufReader::new(file).lines().collect(); return lines.ok(); } None } fn main() { let args: Vec = env::args().collect(); if args.len() != 2 { eprintln!("Usage: ./anomaly-searcher game.log"); std::process::exit(1); } let game_log_file = &args[1]; if let Some(lines) = read_game_log(game_log_file) { let mut engine_process = Command::new("./target/release/chessnost") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("Failed to start the engine process"); let mut engine_stdin = engine_process .stdin .take() .expect("Failed to open engine STDIN"); let mut engine_stdout = io::BufReader::new( engine_process .stdout .take() .expect("Failed to open engine STDOUT"), ); for line in lines.iter().filter(|l| !l.contains("info string")) { if line.starts_with("<<") { // Send the line to the engine without printing it writeln!(engine_stdin, "{}", &line[3..]).expect("Failed to write to engine STDIN"); println!("{}", line); } else if line.starts_with(">>") { // Wait for the engine's output let mut response = String::new(); while response.is_empty() || response.contains("info string") { response = String::new(); engine_stdout .read_line(&mut response) .expect("Failed to read from engine STDOUT"); } // Print the engine's response print!(">> {}", response); // Compare the engine's response to the original log let original_response = line[3..].trim(); // Remove the ">> " prefix if response.trim() != original_response { println!("** {}\n", original_response); } } } // Close the engine's STDIN to signal that we're done sending commands drop(engine_stdin); // Wait for the engine process to finish let _ = engine_process.wait(); } else { eprintln!("Error reading the game log."); std::process::exit(1); } }