summaryrefslogtreecommitdiff
path: root/server/bot
diff options
context:
space:
mode:
Diffstat (limited to 'server/bot')
-rw-r--r--server/bot/src/algos/simple.rs92
1 files changed, 84 insertions, 8 deletions
diff --git a/server/bot/src/algos/simple.rs b/server/bot/src/algos/simple.rs
index 99f75780..af02f81e 100644
--- a/server/bot/src/algos/simple.rs
+++ b/server/bot/src/algos/simple.rs
@@ -6,7 +6,7 @@ use hurrycurry_client_lib::Game;
use hurrycurry_protocol::{
glam::IVec2, ItemIndex, Message, PlayerID, Recipe, RecipeIndex, TileIndex,
};
-use log::warn;
+use log::{info, warn};
#[derive(Default)]
pub struct Simple {
@@ -61,6 +61,7 @@ impl BotAlgo for Simple {
}
.update()
.ok();
+ info!("target={:?}", self.path.as_ref().map(|a| a.1));
BotInput::default()
}
@@ -73,6 +74,13 @@ impl SimpleContext<'_> {
.get(&self.me)
.map_or(false, |p| p.item.as_ref().map_or(false, |i| i.kind == item))
}
+ pub fn is_hand_occupied(&self) -> bool {
+ self.game
+ .players
+ .get(&self.me)
+ .map(|p| p.item.is_some())
+ .unwrap_or(false)
+ }
fn find_demand(&self) -> Option<(ItemIndex, IVec2)> {
self.game
.players
@@ -118,17 +126,44 @@ impl SimpleContext<'_> {
.map(|(p, _)| *p)
}
fn find_empty_interactable_tile(&self) -> Option<IVec2> {
+ if let Some(t) = self
+ .game
+ .tiles
+ .iter()
+ .find(|(_, t)| {
+ self.game.data.tile_interact[t.kind.0]
+ && t.item.is_none()
+ && self.game.data.tile_names[t.kind.0] == "counter"
+ })
+ .map(|(p, _)| *p)
+ {
+ return Some(t);
+ }
self.game
.tiles
.iter()
.find(|(_, t)| self.game.data.tile_interact[t.kind.0] && t.item.is_none())
.map(|(p, _)| *p)
}
- pub fn aquire_placed_item(&mut self, item: ItemIndex) -> LogicRes<IVec2> {
- if let Some(pos) = self.find_item_on_map(item) {
- return Ok(pos);
+ fn is_tile_occupied(&self, pos: IVec2) -> bool {
+ self.game
+ .tiles
+ .get(&pos)
+ .map(|t| t.item.is_some())
+ .unwrap_or(true)
+ }
+ fn clear_tile(&mut self, pos: IVec2) -> LogicRes {
+ self.dispose_hand()?;
+ self.interact_with(pos, 0.)
+ }
+ fn assert_tile_is_clear(&mut self, pos: IVec2) -> LogicRes {
+ if self.is_tile_occupied(pos) {
+ self.clear_tile(pos)?;
}
- self.aquire_item(item)?;
+ Ok(())
+ }
+
+ pub fn dispose_hand(&mut self) -> LogicRes<IVec2> {
if let Some(pos) = self.find_empty_interactable_tile() {
if let Err(()) = self.interact_with(pos, 0.) {
return Ok(pos);
@@ -141,10 +176,20 @@ impl SimpleContext<'_> {
Err(())
}
}
+ pub fn aquire_placed_item(&mut self, item: ItemIndex) -> LogicRes<IVec2> {
+ if let Some(pos) = self.find_item_on_map(item) {
+ return Ok(pos);
+ }
+ self.aquire_item(item)?;
+ self.dispose_hand()
+ }
pub fn aquire_item(&mut self, item: ItemIndex) -> LogicRes {
if self.is_hand_item(item) {
return Ok(());
}
+ if self.is_hand_occupied() {
+ self.dispose_hand()?;
+ }
if let Some(pos) = self.find_item_on_map(item) {
self.interact_with(pos, 0.)?;
return Ok(());
@@ -155,10 +200,10 @@ impl SimpleContext<'_> {
Recipe::Instant {
tile: Some(tile),
inputs: [None, None],
- outputs: [Some(_), None],
..
} => {
if let Some(pos) = self.find_tile(*tile) {
+ self.assert_tile_is_clear(pos)?;
self.interact_with(pos, 0.)?;
}
}
@@ -171,14 +216,27 @@ impl SimpleContext<'_> {
self.aquire_item(*b)?;
self.interact_with(apos, 0.)?;
}
+ Recipe::Instant {
+ tile: None,
+ inputs: [Some(input), None],
+ ..
+ } => {
+ self.aquire_item(*input)?;
+ if let Some(pos) = self.find_empty_interactable_tile() {
+ self.interact_with(pos, 0.)?;
+ } else {
+ warn!("no empty space left")
+ }
+ }
Recipe::Active {
tile: Some(tile),
input,
duration,
..
} => {
- self.aquire_item(*input)?;
if let Some(pos) = self.find_tile(*tile) {
+ self.assert_tile_is_clear(pos)?;
+ self.aquire_item(*input)?;
self.interact_with(pos, duration + 0.5)?;
}
}
@@ -187,7 +245,24 @@ impl SimpleContext<'_> {
input,
..
} => {
-
+ if let Some(pos) = self.find_tile(*tile) {
+ if let Some(item) = &self.game.tiles.get(&pos).unwrap().item {
+ if item.kind == *input {
+ info!("waiting for passive to finish at {pos}");
+ return Err(()); // waiting for it to finish
+ // TODO check progress
+ }
+ }
+ self.aquire_item(*input)?;
+ self.interact_with(pos, 0.)?;
+ }
+ }
+ Recipe::Passive {
+ tile: None, input, ..
+ } => {
+ self.aquire_placed_item(*input)?;
+ info!("waiting for passive to finish");
+ return Err(());
}
_ => warn!("recipe too hard {r:?}"),
}
@@ -208,6 +283,7 @@ impl SimpleContext<'_> {
}
pub fn update(&mut self) -> LogicRes {
if let Some((item, table)) = self.find_demand() {
+ self.assert_tile_is_clear(table)?;
self.aquire_item(item)?;
self.interact_with(table, 0.)?;
}