Spaces:
Sleeping
Sleeping
File size: 4,065 Bytes
463f868 9bd4ce5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | use engine_rust::core::heuristics::OriginalHeuristic;
use engine_rust::core::logic::{GameState, Phase, CardDatabase};
use rand::SeedableRng;
use rand::rngs::SmallRng;
use engine_rust::core::mcts::{SearchHorizon, MCTS};
use engine_rust::test_helpers::load_real_db;
use rand::Rng;
fn main() {
println!("=== Face-off: Random (P0) vs MCTS AlphaZero Heuristic (P1) ===");
let db = load_real_db();
// Decks
let p_main: Vec<i32> = db.members.keys().take(50).cloned().collect();
let energy_ids: Vec<i32> = db.energy_db.keys().take(10).cloned().collect();
let mut wins_random = 0;
let mut wins_mcts = 0;
let mut draws = 0;
let num_games = 10;
let timeout_sec = 0.1;
for game_idx in 0..num_games {
println!("\n--- Game {} ---", game_idx + 1);
let mut sim = GameState::default();
sim.initialize_game(
p_main.clone(),
p_main.clone(),
energy_ids.clone(),
energy_ids.clone(),
Vec::new(),
Vec::new(),
);
sim.ui.silent = true;
sim.phase = Phase::Main;
let mut mcts = MCTS::new();
let heuristic = OriginalHeuristic::default();
let mut steps = 0;
let mut rng = rand::rngs::SmallRng::from_os_rng();
while !sim.is_terminal() && steps < 500 {
let current_player = sim.current_player;
let action = if current_player == 0 {
// Player 0: Random
let mut mask = vec![false; engine_rust::core::logic::ACTION_SPACE];
sim.get_legal_actions_into(&db, 0, &mut mask);
let valid_actions: Vec<i32> = mask
.iter()
.enumerate()
.filter_map(|(i, &b)| if b { Some(i as i32) } else { None })
.collect();
if valid_actions.is_empty() {
println!("No legal actions for Random! Phase: {:?}", sim.phase);
break;
}
let idx = rng.random_range(0..valid_actions.len());
valid_actions[idx]
} else {
// Player 1: MCTS (0.1s)
let (stats, _) = mcts.search(
&sim,
&db,
0,
timeout_sec,
SearchHorizon::GameEnd(),
&heuristic,
);
if stats.is_empty() {
println!("No legal actions for MCTS! Phase: {:?}", sim.phase);
break;
}
stats[0].0
};
let _ = sim.step(&db, action);
if steps % 20 == 0 {
print!(".");
use std::io::Write;
std::io::stdout().flush().unwrap();
}
steps += 1;
}
println!("\nGame {} finished in {} steps.", game_idx + 1, steps);
let winner = sim.get_winner();
match winner {
0 => {
println!(
"Winner: Random (P0) - Score: {} vs {}",
sim.players[0].score, sim.players[1].score
);
wins_random += 1;
}
1 => {
println!(
"Winner: MCTS (P1) - Score: {} vs {}",
sim.players[1].score, sim.players[0].score
);
wins_mcts += 1;
}
_ => {
println!(
"Draw - Score: {} vs {}",
sim.players[0].score, sim.players[1].score
);
draws += 1;
}
}
}
println!("\n=== Final Results ===");
println!("Total Games: {}", num_games);
println!("Random (P0) Wins: {}", wins_random);
println!("MCTS (P1) Wins: {}", wins_mcts);
println!("Draws: {}", draws);
} |