summaryrefslogtreecommitdiff
path: root/server/bot/src/algos/simple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/bot/src/algos/simple.rs')
-rw-r--r--server/bot/src/algos/simple.rs108
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> {}