diff --git a/core/src/ai/search.rs b/core/src/ai/search.rs index def90f1..b26fb4c 100644 --- a/core/src/ai/search.rs +++ b/core/src/ai/search.rs @@ -5,6 +5,7 @@ use crate::rules; use crate::types::{Color, Position}; /// Alpha-Beta AI 引擎 +#[derive(Clone)] pub struct AlphaBetaAi { depth: usize, } diff --git a/gui/src/commands.rs b/gui/src/commands.rs index b1ba63a..8a002b1 100644 --- a/gui/src/commands.rs +++ b/gui/src/commands.rs @@ -121,13 +121,24 @@ pub fn undo(steps: u32, state: State) -> Result<(), String> { #[tauri::command] pub fn ai_move(state: State) -> Result, String> { - let board_opt = state.board.lock().map_err(|e| e.to_string())?; - let board = board_opt.as_ref().ok_or("游戏未开始")?; - let color = *state.current_color.lock().map_err(|e| e.to_string())?; - let ai = state.ai_engine.lock().map_err(|e| e.to_string())?; - let ai = ai.as_ref().ok_or("AI 未初始化")?; + let (board_clone, color, ai_clone) = { + let board_opt = state.board.lock().map_err(|e| e.to_string())?; + let board = board_opt.as_ref().ok_or("游戏未开始")?.clone(); + let color = *state.current_color.lock().map_err(|e| e.to_string())?; + let ai_guard = state.ai_engine.lock().map_err(|e| e.to_string())?; + let ai = ai_guard.as_ref().ok_or("AI 未初始化")?.clone(); + (board, color, ai) + }; - Ok(ai.best_move(board, color).map(|p| (p.x, p.y))) + let (tx, rx) = std::sync::mpsc::channel(); + std::thread::spawn(move || { + let result = ai_clone.best_move(&board_clone, color); + let _ = tx.send(result); + }); + + rx.recv_timeout(std::time::Duration::from_secs(30)) + .map_err(|_| "AI 计算超时".to_string()) + .map(|r| r.map(|p| (p.x, p.y))) } #[tauri::command]