aboutsummaryrefslogtreecommitdiff
path: root/src/bot/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bot/mod.rs')
-rw-r--r--src/bot/mod.rs49
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:?; "");
+ }
+ }
+}