update RunMatch helper to allow for remote bots
This commit is contained in:
parent
5ee66c9c9b
commit
a376698073
5 changed files with 50 additions and 22 deletions
|
@ -25,7 +25,7 @@ pub struct NewMatchPlayer {
|
||||||
/// player id within the match
|
/// player id within the match
|
||||||
pub player_id: i32,
|
pub player_id: i32,
|
||||||
/// id of the bot behind this player
|
/// id of the bot behind this player
|
||||||
pub code_bundle_id: i32,
|
pub code_bundle_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable)]
|
#[derive(Queryable, Identifiable)]
|
||||||
|
@ -48,7 +48,7 @@ pub struct MatchPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MatchPlayerData {
|
pub struct MatchPlayerData {
|
||||||
pub code_bundle_id: i32,
|
pub code_bundle_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_match(
|
pub fn create_match(
|
||||||
|
|
|
@ -16,32 +16,54 @@ use crate::{
|
||||||
|
|
||||||
const PYTHON_IMAGE: &str = "python:3.10-slim-buster";
|
const PYTHON_IMAGE: &str = "python:3.10-slim-buster";
|
||||||
|
|
||||||
pub struct RunMatch<'a> {
|
pub struct RunMatch {
|
||||||
log_file_name: String,
|
log_file_name: String,
|
||||||
player_code_bundles: Vec<&'a db::bots::CodeBundle>,
|
players: Vec<MatchPlayer>,
|
||||||
match_id: Option<i32>,
|
match_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RunMatch<'a> {
|
pub struct MatchPlayer {
|
||||||
pub fn from_players(player_code_bundles: Vec<&'a db::bots::CodeBundle>) -> Self {
|
bot_spec: Box<dyn BotSpec>,
|
||||||
|
// meta that will be passed on to database
|
||||||
|
code_bundle_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MatchPlayer {
|
||||||
|
pub fn from_code_bundle(code_bundle: &db::bots::CodeBundle) -> Self {
|
||||||
|
MatchPlayer {
|
||||||
|
bot_spec: code_bundle_to_botspec(code_bundle),
|
||||||
|
code_bundle_id: Some(code_bundle.id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bot_spec(bot_spec: Box<dyn BotSpec>) -> Self {
|
||||||
|
MatchPlayer {
|
||||||
|
bot_spec,
|
||||||
|
code_bundle_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RunMatch {
|
||||||
|
pub fn from_players(players: Vec<MatchPlayer>) -> Self {
|
||||||
let log_file_name = format!("{}.log", gen_alphanumeric(16));
|
let log_file_name = format!("{}.log", gen_alphanumeric(16));
|
||||||
RunMatch {
|
RunMatch {
|
||||||
log_file_name,
|
log_file_name,
|
||||||
player_code_bundles,
|
players,
|
||||||
match_id: None,
|
match_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn runner_config(&self) -> runner::MatchConfig {
|
pub fn into_runner_config(self) -> runner::MatchConfig {
|
||||||
runner::MatchConfig {
|
runner::MatchConfig {
|
||||||
map_path: PathBuf::from(MAPS_DIR).join("hex.json"),
|
map_path: PathBuf::from(MAPS_DIR).join("hex.json"),
|
||||||
map_name: "hex".to_string(),
|
map_name: "hex".to_string(),
|
||||||
log_path: PathBuf::from(MATCHES_DIR).join(&self.log_file_name),
|
log_path: PathBuf::from(MATCHES_DIR).join(&self.log_file_name),
|
||||||
players: self
|
players: self
|
||||||
.player_code_bundles
|
.players
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(|b| runner::MatchPlayer {
|
.map(|player| runner::MatchPlayer {
|
||||||
bot_spec: code_bundle_to_botspec(b),
|
bot_spec: player.bot_spec,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
|
@ -56,10 +78,10 @@ impl<'a> RunMatch<'a> {
|
||||||
log_path: &self.log_file_name,
|
log_path: &self.log_file_name,
|
||||||
};
|
};
|
||||||
let new_match_players = self
|
let new_match_players = self
|
||||||
.player_code_bundles
|
.players
|
||||||
.iter()
|
.iter()
|
||||||
.map(|b| db::matches::MatchPlayerData {
|
.map(|p| db::matches::MatchPlayerData {
|
||||||
code_bundle_id: b.id,
|
code_bundle_id: p.code_bundle_id,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -70,7 +92,7 @@ impl<'a> RunMatch<'a> {
|
||||||
|
|
||||||
pub fn spawn(self, pool: ConnectionPool) -> JoinHandle<MatchOutcome> {
|
pub fn spawn(self, pool: ConnectionPool) -> JoinHandle<MatchOutcome> {
|
||||||
let match_id = self.match_id.expect("match must be saved before running");
|
let match_id = self.match_id.expect("match must be saved before running");
|
||||||
let runner_config = self.runner_config();
|
let runner_config = self.into_runner_config();
|
||||||
tokio::spawn(run_match_task(pool, runner_config, match_id))
|
tokio::spawn(run_match_task(pool, runner_config, match_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{db::bots::Bot, DbPool};
|
use crate::{db::bots::Bot, DbPool};
|
||||||
|
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::modules::matches::RunMatch;
|
use crate::modules::matches::{MatchPlayer, RunMatch};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio;
|
use tokio;
|
||||||
|
@ -43,9 +43,12 @@ async fn play_ranking_match(selected_bots: Vec<Bot>, db_pool: DbPool) {
|
||||||
code_bundles.push(code_bundle);
|
code_bundles.push(code_bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
let code_bundle_refs = code_bundles.iter().map(|b| b).collect::<Vec<_>>();
|
let players = code_bundles
|
||||||
|
.iter()
|
||||||
|
.map(MatchPlayer::from_code_bundle)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut run_match = RunMatch::from_players(code_bundle_refs);
|
let mut run_match = RunMatch::from_players(players);
|
||||||
run_match
|
run_match
|
||||||
.store_in_database(&db_conn)
|
.store_in_database(&db_conn)
|
||||||
.expect("could not store match in db");
|
.expect("could not store match in db");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::db::matches::{FullMatchData, FullMatchPlayerData};
|
use crate::db::matches::{FullMatchData, FullMatchPlayerData};
|
||||||
use crate::modules::bots::save_code_bundle;
|
use crate::modules::bots::save_code_bundle;
|
||||||
use crate::modules::matches::RunMatch;
|
use crate::modules::matches::{MatchPlayer, RunMatch};
|
||||||
use crate::ConnectionPool;
|
use crate::ConnectionPool;
|
||||||
use axum::extract::Extension;
|
use axum::extract::Extension;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
|
@ -46,7 +46,10 @@ pub async fn submit_bot(
|
||||||
// TODO: can we recover from this?
|
// TODO: can we recover from this?
|
||||||
.expect("could not save bot code");
|
.expect("could not save bot code");
|
||||||
|
|
||||||
let mut run_match = RunMatch::from_players(vec![&player_code_bundle, &opponent_code_bundle]);
|
let mut run_match = RunMatch::from_players(vec![
|
||||||
|
MatchPlayer::from_code_bundle(&player_code_bundle),
|
||||||
|
MatchPlayer::from_code_bundle(&opponent_code_bundle),
|
||||||
|
]);
|
||||||
let match_data = run_match
|
let match_data = run_match
|
||||||
.store_in_database(&conn)
|
.store_in_database(&conn)
|
||||||
.expect("failed to save match");
|
.expect("failed to save match");
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub async fn play_match(
|
||||||
});
|
});
|
||||||
|
|
||||||
bot_ids.push(matches::MatchPlayerData {
|
bot_ids.push(matches::MatchPlayerData {
|
||||||
code_bundle_id: code_bundle.id,
|
code_bundle_id: Some(code_bundle.id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue