cleanup minmax impl
This commit is contained in:
parent
9342760d82
commit
111ce718da
@ -30,7 +30,7 @@ pub fn run() {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let configs = [2, 4, 6, 8]
|
||||
let configs = [2, 4, 6]
|
||||
.into_iter()
|
||||
.map(move |d| FutureMoveConfig {
|
||||
max_depth: d,
|
||||
|
||||
@ -213,18 +213,7 @@ impl FutureMoves {
|
||||
}
|
||||
|
||||
fn create_move(&self, coord: MoveCoord, board: Board, color: Piece) -> Move {
|
||||
Move::new(
|
||||
coord,
|
||||
board,
|
||||
color,
|
||||
self.agent_color,
|
||||
MoveValueConfig {
|
||||
self_value_raw: matches!(
|
||||
self.config.children_eval_method,
|
||||
ChildrenEvalMethod::MinMaxProb
|
||||
),
|
||||
},
|
||||
)
|
||||
Move::new(coord, board, color, self.agent_color, MoveValueConfig {})
|
||||
}
|
||||
|
||||
fn generate_children_raw(&self, parent_idx: usize) -> Vec<Move> {
|
||||
@ -307,38 +296,27 @@ impl FutureMoves {
|
||||
.iter()
|
||||
.map(|&child| self.arena[child].value)
|
||||
.collect::<Vec<_>>();
|
||||
let child_value = if self.arena[idx].color == self.agent_color {
|
||||
// get best (for the adversary) enemy play
|
||||
// this assumes the adversary is playing optimally
|
||||
|
||||
children_values.iter().min()
|
||||
} else {
|
||||
children_values.iter().max()
|
||||
}
|
||||
.cloned()
|
||||
.unwrap_or(Default::default());
|
||||
self.arena[idx].value = self.arena[idx].self_value;
|
||||
|
||||
match self.config.children_eval_method {
|
||||
ChildrenEvalMethod::MinMax => {
|
||||
let child_value = if self.arena[idx].color == self.agent_color {
|
||||
// get best (for the adversary) enemy play
|
||||
// this assumes the adversary is playing optimally
|
||||
|
||||
children_values.into_iter().map(|x| x.value).min()
|
||||
} else {
|
||||
children_values.into_iter().map(|x| x.value).max()
|
||||
}
|
||||
.unwrap_or(0);
|
||||
|
||||
self.arena[idx].value.value =
|
||||
self.arena[idx].self_value.value + child_value;
|
||||
self.arena[idx].value.value += child_value.value;
|
||||
}
|
||||
ChildrenEvalMethod::MinMaxProb => {
|
||||
let child_value = if self.arena[idx].color == self.agent_color {
|
||||
// get best (for the adversary) enemy play
|
||||
// this assumes the adversary is playing optimally
|
||||
|
||||
children_values.iter().min()
|
||||
} else {
|
||||
children_values.iter().max()
|
||||
}
|
||||
.cloned()
|
||||
.unwrap_or(Default::default());
|
||||
|
||||
self.arena[idx].value = self.arena[idx].self_value;
|
||||
self.arena[idx]
|
||||
.value
|
||||
.populate_self_from_children(&children_values);
|
||||
|
||||
self.arena[idx].value.value += child_value.value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,9 +38,7 @@ pub struct Move {
|
||||
pub is_trimmed: bool,
|
||||
}
|
||||
|
||||
pub struct MoveValueConfig {
|
||||
pub self_value_raw: bool,
|
||||
}
|
||||
pub struct MoveValueConfig {}
|
||||
|
||||
impl Move {
|
||||
pub fn new(
|
||||
@ -48,7 +46,7 @@ impl Move {
|
||||
board: Board,
|
||||
color: Piece,
|
||||
agent_color: Piece,
|
||||
mvc: MoveValueConfig,
|
||||
_: MoveValueConfig,
|
||||
) -> Self {
|
||||
let mut m = Move {
|
||||
coord,
|
||||
@ -76,30 +74,11 @@ impl Move {
|
||||
Winner::None => {}
|
||||
}
|
||||
|
||||
if mvc.self_value_raw {
|
||||
m.self_value.value =
|
||||
const { BoardValueMap::weighted() }.board_value(&board, agent_color) as i32;
|
||||
} else {
|
||||
m.self_value.value = m.compute_self_value(agent_color, &board, mvc) as i32;
|
||||
}
|
||||
m.self_value.value =
|
||||
const { BoardValueMap::weighted() }.board_value(&board, agent_color) as i32;
|
||||
m
|
||||
}
|
||||
|
||||
fn compute_self_value(&self, agent_color: Piece, board: &Board, _mvc: MoveValueConfig) -> i16 {
|
||||
if self.winner == Winner::Player(!agent_color) {
|
||||
// if this board results in the opponent winning, MAJORLY negatively weigh this move
|
||||
// NOTE! this branch isn't completely deleted because if so, the bot wouldn't make a move.
|
||||
// We shouldn't prune branches because we still need to always react to the opponent's moves
|
||||
return i16::MIN + 1;
|
||||
} else if self.winner == Winner::Player(agent_color) {
|
||||
// results in a win for the agent
|
||||
return i16::MAX - 1;
|
||||
}
|
||||
|
||||
// I guess ignore Ties here, don't give them an explicit value,
|
||||
const { BoardValueMap::weighted() }.board_value(board, agent_color)
|
||||
}
|
||||
|
||||
/// Sort children of the [`Move`] by their self_value in `arena`
|
||||
pub fn sort_children(&mut self, arena: &[Move]) {
|
||||
self.children.sort_by(|&a, &b| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user