improve score condition
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
Max Känner 2025-04-25 14:59:21 +02:00
parent bad4d916b8
commit 99acd4ad1f
2 changed files with 31 additions and 10 deletions

View File

@ -69,6 +69,7 @@ async fn start(request: Json<Request>) {
async fn get_move(request: Json<Request>) -> response::Json<Response> { async fn get_move(request: Json<Request>) -> response::Json<Response> {
let start = Instant::now(); let start = Instant::now();
let board = Board::from(&*request); let board = Board::from(&*request);
let timeout = Duration::from_millis(u64::from(request.game.timeout));
let id = board.get_id(&request.you.id).unwrap_or_else(|| { let id = board.get_id(&request.you.id).unwrap_or_else(|| {
error!("My id is not in the simulation board"); error!("My id is not in the simulation board");
0 0
@ -88,33 +89,36 @@ async fn get_move(request: Json<Request>) -> response::Json<Response> {
info!("valid actions: {actions:?}"); info!("valid actions: {actions:?}");
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
if start.elapsed() > Duration::from_millis(10) {
error!(
"The calculation started late ({}ms)",
start.elapsed().as_millis()
);
}
let base_turns = board.turn(); let base_turns = board.turn();
let rolling_horizon = (u32::from(request.you.length) * 3).max(32);
let last_turn = base_turns + rolling_horizon;
let end_condition: &dyn Fn(&Board) -> Option<_> = match &*request.game.ruleset.name { let end_condition: &dyn Fn(&Board) -> Option<_> = match &*request.game.ruleset.name {
"solo" => &|board| { "solo" => &|board| {
if board.num_snakes() == 0 if board.valid_actions(0).count() == 0 || board.turn() > last_turn {
|| board.turn() > base_turns + (u32::from(request.you.length) * 3).min(32)
{
Some(()) Some(())
} else { } else {
None None
} }
}, },
_ => &|board| { _ => &|board| {
if board.num_snakes() <= 1 if board.num_snakes() <= 1 || board.turn() > last_turn {
|| board.turn() > base_turns + (u32::from(request.you.length) * 3).min(32)
{
Some(()) Some(())
} else { } else {
None None
} }
}, },
}; };
let start_snakes = u32::try_from(board.num_snakes()).unwrap_or(0);
let score_fn: &dyn Fn(&Board, u8) -> u32 = match &*request.game.ruleset.name { let score_fn: &dyn Fn(&Board, u8) -> u32 = match &*request.game.ruleset.name {
"solo" => &|board, _| board.turn(), "solo" => &|board, id| u32::try_from(board.length(id)).unwrap_or(0),
_ => &|board, id| { _ => &|board, id| {
if board.alive(id) { if board.alive(id) {
1 + start_snakes - u32::try_from(board.num_snakes()).unwrap_or(start_snakes) 1 + u32::from(board.max_length() == board.length(id))
} else { } else {
0 0
} }
@ -125,7 +129,7 @@ async fn get_move(request: Json<Request>) -> response::Json<Response> {
.map(|id| MctsManager::new(u8::try_from(id).unwrap())) .map(|id| MctsManager::new(u8::try_from(id).unwrap()))
.collect(); .collect();
let c = f32::sqrt(2.0); let c = f32::sqrt(2.0);
while start.elapsed() < Duration::from_millis(250) { while start.elapsed() < timeout * 4 / 5 {
let mut board = board.clone(); let mut board = board.clone();
while end_condition(&board).is_none() { while end_condition(&board).is_none() {
let actions: Vec<_> = mcts_managers let actions: Vec<_> = mcts_managers

View File

@ -210,6 +210,23 @@ impl Board {
self.id_to_index(id).is_some() self.id_to_index(id).is_some()
} }
#[must_use]
pub fn length(&self, id: u8) -> usize {
let Some(index) = self.id_to_index(id) else {
return 0;
};
self.snakes[index].body.len()
}
#[must_use]
pub fn max_length(&self) -> usize {
self.snakes
.iter()
.map(|snake| snake.body.len())
.max()
.unwrap_or(0)
}
#[must_use] #[must_use]
pub fn is_food(&self, tile: Coord) -> bool { pub fn is_food(&self, tile: Coord) -> bool {
let index = self.coord_to_linear(tile); let index = self.coord_to_linear(tile);