1
Fork 0

dfs on ore find & ignore fluids in pathfinding

This commit is contained in:
Andy Killorin 2023-12-20 23:27:23 -06:00
parent 7d9cd93d1c
commit 7d2d85169f
Signed by: ank
GPG key ID: B6241CA3B552BCA4
4 changed files with 59 additions and 19 deletions

View file

@ -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

View file

@ -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

View file

@ -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(())
}

View file

@ -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) {