This commit is contained in:
parent
bad4d916b8
commit
99acd4ad1f
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user