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
extern crate time;
use {Player, MoveResult};
use game_manager::{Game, State};
use gdl::{Move, Score};
pub struct CompDelibPlayer {
depth_limit: u32,
best_move: Option<Move>,
}
impl CompDelibPlayer {
pub fn new(depth: u32) -> CompDelibPlayer {
CompDelibPlayer { depth_limit: depth, best_move: None }
}
fn best_move(&mut self, game: &Game) -> MoveResult<Move> {
let cur_state = game.current_state();
let mut moves = game.legal_moves(cur_state, game.role());
assert!(moves.len() >= 1, "No legal moves");
if moves.len() == 1 {
return Ok(moves.swap_remove(0));
}
let mut max = 0;
let mut res = moves[0].clone();
self.best_move = Some(res.clone());
for m in moves {
let score = match self.max_score(game, &cur_state, &vec![m.clone()], 0) {
Ok(score) => score,
Err(m) => return Err(m)
};
if score == 100 {
return Ok(m);
}
if score > max {
max = score;
self.best_move = Some(m.clone());
res = m;
}
check_time_result!(self, game);
}
Ok(res)
}
fn max_score(&mut self, game: &Game, state: &State, moves: &[Move],
depth: u32) -> MoveResult<Score> {
if depth > self.depth_limit {
return Ok(game.goal(state, game.role()));
}
let cur_state = game.next_state(state, moves);
if game.is_terminal(&cur_state) {
return Ok(game.goal(&cur_state, game.role()));
}
let moves = game.legal_moves(&cur_state, game.role());
assert!(moves.len() >= 1, "No legal moves");
let mut max = 0;
for m in moves {
let score = match self.max_score(game, &cur_state, &vec![m], depth + 1) {
Ok(score) => score,
e @ Err(_) => return e
};
if score > max {
max = score
}
check_time_result!(self, game);
}
Ok(max)
}
}
impl Player for CompDelibPlayer {
fn name(&self) -> String {
"CompDelibPlayer".to_string()
}
fn select_move(&mut self, game: &Game) -> Move {
assert!(game.roles().len() == 1,
"CompDelibPlayer only works with single player games");
let m = match self.best_move(&game) {
Ok(m) => m,
Err(m) => { warn!("Out of time"); m }
};
info!("Selecting move {}", m.to_string());
m
}
fn out_of_time(&mut self, _: &Game) -> Move {
self.best_move.take().unwrap()
}
}