use crate::{game::protocol::Direction, State}; use log::debug; use rand::{rng, seq::IteratorRandom}; 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) { for i in 0..config.amount { spawn(bot(config.clone(), state.clone(), format!("bot{i}"))); } } async fn bot(_config: Config, state: Arc, 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 rng()).unwrap_or(&Direction::Up); debug!(name:?, dir:?; ""); } } }