diff options
Diffstat (limited to 'src/bot/mod.rs')
-rw-r--r-- | src/bot/mod.rs | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 71c659f..17472d2 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -1 +1,48 @@ -pub async fn spawn_bots() {} +use crate::{game::protocol::Direction, State}; +use log::debug; +use rand::{seq::IteratorRandom, thread_rng}; +use serde::Deserialize; +use std::{ops::DerefMut, sync::Arc}; +use tokio::spawn; + +#[derive(Deserialize, Clone)] +pub struct Config { + amount: usize, +} + +pub async fn spawn_bots(config: Config, state: Arc<State>) { + for i in 0..config.amount { + spawn(bot(config.clone(), state.clone(), format!("bot{i}"))); + } +} + +async fn bot(_config: Config, state: Arc<State>, name: String) { + let mut ticks = state.tick.subscribe(); + let id = { + let mut g = state.players.write().await; + let mut id = 0; + while g.contains_key(&id) { + id += 1; + } + g.insert(id, name.clone()); + id + }; + let mut possible = Vec::new(); + while let Ok(_) = ticks.recv().await { + let mut g = state.game.write().await; + let g = g.deref_mut(); + if let Some((dir, head, _)) = g.heads.get_mut(&id) { + possible.clear(); + for d in Direction::ALL { + if g.map[*head + d.vector()].is_none() { + possible.push(d) + } + } + *dir = *possible + .iter() + .choose(&mut thread_rng()) + .unwrap_or(&Direction::Up); + debug!(name:?, dir:?; ""); + } + } +} |