dfs on ore find & ignore fluids in pathfinding
This commit is contained in:
parent
7d9cd93d1c
commit
7d2d85169f
4 changed files with 59 additions and 19 deletions
|
@ -5,7 +5,7 @@ use rstar::{self, PointDistance, RTree, RTreeObject, AABB};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::{RwLock, RwLockReadGuard, OwnedRwLockReadGuard};
|
||||
|
||||
use crate::{turtle::TurtleCommand, paths};
|
||||
use crate::{turtle::TurtleCommand, paths::{self, TRANSPARENT}};
|
||||
|
||||
pub type WorldReadLock = OwnedRwLockReadGuard<RTree<Block>>;
|
||||
|
||||
|
@ -30,9 +30,9 @@ impl World {
|
|||
self.state.write().await.insert(block);
|
||||
}
|
||||
|
||||
/// Returns true if a known non-air block exists at the point
|
||||
/// Returns true if a known non-traversable block exists at the point
|
||||
pub async fn occupied(&self, block: Vec3) -> bool {
|
||||
self.state.read().await.locate_at_point(&block.into()).is_some_and(|b| b.name != "minecraft:air")
|
||||
self.state.read().await.locate_at_point(&block.into()).is_some_and(|b| !TRANSPARENT.contains(&b.name.as_str()))
|
||||
}
|
||||
|
||||
/// Returns true if a "garbage" block exists at the given point which you are free to destroy
|
||||
|
|
|
@ -212,11 +212,12 @@ async fn run_command(
|
|||
async fn dig(
|
||||
Path(id): Path<u32>,
|
||||
State(state): State<SharedControl>,
|
||||
Json(req): Json<Vec3>,
|
||||
Json(req): Json<(Vec3, Position, Position)>,
|
||||
) -> &'static str {
|
||||
let turtle = state.read().await.get_turtle(id).await.unwrap();
|
||||
let fuel = Position::new(Vec3::new(-19, 93, 73), blocks::Direction::East);
|
||||
let inventory = Position::new(Vec3::new(-19, 92, 73), blocks::Direction::East);
|
||||
let (req, fuel, inventory) = req;
|
||||
//let fuel = Position::new(Vec3::new(-19, 93, 73), blocks::Direction::East);
|
||||
//let inventory = Position::new(Vec3::new(-19, 92, 73), blocks::Direction::East);
|
||||
tokio::spawn(
|
||||
async move {
|
||||
mine::mine(turtle.clone(), req, fuel, inventory).await
|
||||
|
|
|
@ -130,8 +130,9 @@ impl TurtleTask for TurtleMineJob {
|
|||
use TurtleCommand::*;
|
||||
|
||||
/// Things to leave in the field (not worth fuel)
|
||||
const USELESS: [&str; 4] = [
|
||||
const USELESS: [&str; 5] = [
|
||||
"minecraft:dirt",
|
||||
"minecraft:gravel",
|
||||
"minecraft:cobblestone",
|
||||
"minecraft:cobbled_deepslate",
|
||||
"minecraft:diorite",
|
||||
|
@ -150,17 +151,13 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
|||
loop {
|
||||
mine_chunk(turtle.clone(), pos, chunk).await?;
|
||||
|
||||
turtle.world().lock().await
|
||||
.locate_within_distance(pos.into(), chunk.map(|n| n.pow(2)).sum())
|
||||
.filter(|n| n.name != "minecraft:air")
|
||||
.filter(|n| VALUABLE.iter().any(|v| n.name.contains(v)))
|
||||
.map(|b|b.pos).collect_into(&mut valuables);
|
||||
|
||||
dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await;
|
||||
valuables.append(&mut near_valuables(&turtle, pos, chunk).await);
|
||||
|
||||
while let Some(block) = valuables.pop() {
|
||||
let near = turtle.goto_adjacent(block).await?;
|
||||
turtle.execute(dbg!(near.dig(block))?).await;
|
||||
observe(turtle.clone(), block).await;
|
||||
valuables.append(&mut near_valuables(&turtle, near.pos, Vec3::new(2,2,2)).await);
|
||||
}
|
||||
|
||||
if (turtle.fuel().await as f64) < (volume + (fuel.pos-turtle.pos().await.pos).abs().sum()) as f64 * 1.1 {
|
||||
|
@ -169,7 +166,7 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
|||
refuel(turtle.clone()).await;
|
||||
}
|
||||
|
||||
if let turtle::TurtleCommandResponse::Item(_) = turtle.execute(ItemInfo(13)).await.ret {
|
||||
if dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await > 13 {
|
||||
println!("storage rtb");
|
||||
turtle.goto(storage).await?;
|
||||
dump(turtle.clone()).await;
|
||||
|
@ -179,6 +176,14 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
|||
}
|
||||
}
|
||||
|
||||
async fn near_valuables(turtle: &TurtleCommander, pos: Vec3, chunk: Vec3) -> Vec<Vec3> {
|
||||
turtle.world().lock().await
|
||||
.locate_within_distance(pos.into(), chunk.map(|n| n.pow(2)).sum())
|
||||
.filter(|n| n.name != "minecraft:air")
|
||||
.filter(|n| VALUABLE.iter().any(|v| n.name.contains(v)))
|
||||
.map(|b|b.pos).collect()
|
||||
}
|
||||
|
||||
pub async fn mine_chunk(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
|
||||
let turtle = turtle.clone();
|
||||
let volume = chunk.x * chunk.y * chunk.z;
|
||||
|
@ -224,15 +229,20 @@ async fn dump(turtle: TurtleCommander) {
|
|||
}
|
||||
|
||||
/// Dump all items that match the predicate
|
||||
async fn dump_filter<F>(turtle: TurtleCommander, mut filter: F)
|
||||
/// Returns the number of slots still full after the operation
|
||||
async fn dump_filter<F>(turtle: TurtleCommander, mut filter: F) -> u32
|
||||
where F: FnMut(InventorySlot) -> bool {
|
||||
let mut counter = 0;
|
||||
for i in 1..=16 {
|
||||
if let TurtleCommandResponse::Item(item) = turtle.execute(Select(i)).await.ret {
|
||||
if filter(item) {
|
||||
turtle.execute(DropFront(64)).await;
|
||||
} else {
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
counter
|
||||
}
|
||||
|
||||
/// zig from 0 to x and back, stopping on each end
|
||||
|
@ -255,3 +265,26 @@ fn fill(scale: Vec3, n: i32) -> Vec3 {
|
|||
step(n/scale.x/scale.y, scale.z)
|
||||
)
|
||||
}
|
||||
|
||||
/// Looks at all the blocks around the given pos
|
||||
/// destructive
|
||||
async fn observe(turtle: TurtleCommander, pos: Vec3) -> Option<()> {
|
||||
let adjacent = [
|
||||
pos,
|
||||
pos + Vec3::y(),
|
||||
pos + Vec3::x(),
|
||||
pos + Vec3::z(),
|
||||
pos - Vec3::x(),
|
||||
pos - Vec3::z(),
|
||||
pos - Vec3::y(),
|
||||
];
|
||||
|
||||
for pos in adjacent {
|
||||
if turtle.world().get(pos).await.is_none() {
|
||||
turtle.goto_adjacent(pos).await?;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
|
|
@ -35,8 +35,7 @@ where D: FnMut(&Position) -> bool {
|
|||
move |p| next(p, &world),
|
||||
|p1| (p1.pos - &to).abs().sum() as u32,
|
||||
done,
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
Some(route.0)
|
||||
}
|
||||
|
||||
|
@ -74,6 +73,13 @@ fn next(from: &Position, world: &WorldReadLock) -> Vec<(Position, u32)> {
|
|||
vec
|
||||
}
|
||||
|
||||
/// Blocks that you can go through without a pickaxe
|
||||
pub const TRANSPARENT: [&str; 3] = [
|
||||
"minecraft:air",
|
||||
"minecraft:water",
|
||||
"minecraft:lava",
|
||||
];
|
||||
|
||||
/// Blocks that are fine to tunnel through
|
||||
const GARBAGE: [&str; 6] = [
|
||||
"minecraft:stone",
|
||||
|
@ -89,7 +95,7 @@ const UNKNOWN: Option<u32> = Some(2);
|
|||
|
||||
// time to go somewhere
|
||||
pub fn difficulty(name: &str) -> Option<u32> {
|
||||
if name == "minecraft:air" {
|
||||
if TRANSPARENT.contains(&name) {
|
||||
return Some(1);
|
||||
};
|
||||
if GARBAGE.contains(&name) {
|
||||
|
|
Loading…
Reference in a new issue