diff options
Diffstat (limited to 'server/bot/src/algos/simple.rs')
-rw-r--r-- | server/bot/src/algos/simple.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/server/bot/src/algos/simple.rs b/server/bot/src/algos/simple.rs new file mode 100644 index 00000000..125f7e0b --- /dev/null +++ b/server/bot/src/algos/simple.rs @@ -0,0 +1,108 @@ +use crate::{ + pathfinding::{find_path_to_neighbour, Path}, + BotAlgo, BotInput, +}; +use hurrycurry_client_lib::Game; +use hurrycurry_protocol::{glam::IVec2, ItemIndex, Message, PlayerID}; + +#[derive(Default)] +pub struct Simple { + path: Option<(Path, IVec2)>, + cooldown: f32, +} + +struct SimpleContext<'a> { + game: &'a Game, + me: PlayerID, + own_position: IVec2, + state: &'a mut Simple, +} + +impl BotAlgo for Simple { + fn tick(&mut self, me: PlayerID, game: &Game, _dt: f32) -> BotInput { + let Some(player) = game.players.get(&me) else { + return BotInput::default(); + }; + let pos = player.movement.position; + + if self.cooldown > 0. { + self.cooldown -= _dt; + } + + if let Some((path, target)) = &mut self.path { + let direction = path.next_direction(pos); + let done = path.is_done(); + let target = *target; + if done { + self.path = None; + self.cooldown = 1.; + } + return BotInput { + direction, + boost: false, + interact: if done { Some(target) } else { None }, + }; + } + + SimpleContext { + game, + own_position: pos.as_ivec2(), + me, + state: self, + } + .update(); + + BotInput::default() + } +} + +impl SimpleContext<'_> { + pub fn is_hand_item(&self, item: ItemIndex) -> bool { + self.game + .players + .get(&self.me) + .map_or(false, |p| p.item.as_ref().map_or(false, |i| i.kind == item)) + } + fn find_demand(&self) -> Option<(ItemIndex, IVec2)> { + self.game + .players + .iter() + .find_map(|(_, pl)| match &pl.communicate_persist { + Some(Message::Item(item)) => { + let pos = pl.movement.position.as_ivec2(); + [IVec2::X, IVec2::Y, -IVec2::X, -IVec2::Y] + .into_iter() + .find(|off| { + self.game + .tiles + .get(&(pos + *off)) + .map_or(false, |t| self.game.data.tile_interact[t.kind.0]) + }) + .map(|off| pos + off) + .map(|pos| (*item, pos)) + } + _ => None, + }) + } + pub fn aquire_item(&mut self, item: ItemIndex) -> bool { + if self.is_hand_item(item) { + return true; + } + + false + } + pub fn update(&mut self) { + if let Some((item, table)) = self.find_demand() { + if !self.aquire_item(item) { + return; + } + if let Some(path) = + find_path_to_neighbour(&self.game.walkable, self.own_position, table) + { + self.state.path = Some((path, table)); + } + } + } +} + +// fn find_item_on_map(game: &Game, item: ItemIndex) -> Option<IVec2> {} |