forked from RepoMirrors/baritone
tenor comms integration, and priority allocation caching
This commit is contained in:
parent
3b7e1adf24
commit
c79f40a5f1
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package tenor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class QuantizedTaskPriorityAllocationCache extends QuantizedTaskNode {
|
||||
|
||||
private final Map<Integer, Allocation> allocationByQuantity;
|
||||
|
||||
public QuantizedTaskPriorityAllocationCache(Bot bot, DependencyType type) {
|
||||
super(bot, type);
|
||||
this.allocationByQuantity = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
|
||||
return allocationByQuantity.computeIfAbsent(quantity, this::allocationStrategy).allocatedTo(child);
|
||||
}
|
||||
|
||||
protected Allocation allocationStrategy(int quantity) { // overridable
|
||||
double amount = effectiveAllocationSize(quantity);
|
||||
Allocation alloc = new Allocation(amount);
|
||||
List<IQuantizedParentTaskRelationship> children = childTasks();
|
||||
if (children.size() < 2) {
|
||||
return new Allocation(amount).distributeEqually(); // 0 or 1 cannot be anything but equal distribution
|
||||
}
|
||||
double[] costs = new double[children.size()];
|
||||
for (int i = 0; i < costs.length; i++) {
|
||||
costs[i] = children.get(i).cost().value(quantity);
|
||||
}
|
||||
switch (type) {
|
||||
case ANY_ONE_OF:
|
||||
// by default, give it all to the lowest cost
|
||||
// this is stable
|
||||
int lowestInd = 0;
|
||||
for (int i = 1; i < costs.length; i++) {
|
||||
if (costs[i] < costs[lowestInd]) {
|
||||
lowestInd = i;
|
||||
}
|
||||
}
|
||||
alloc.givePriority(lowestInd, alloc.unallocated());
|
||||
return alloc;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
}
|
||||
|
||||
protected double effectiveAllocationSize(int quantity) { // overridable
|
||||
return priority().value(quantity);
|
||||
}
|
||||
|
||||
protected class Allocation {
|
||||
private final double[] priorities;
|
||||
private final double total;
|
||||
|
||||
public Allocation(double total) {
|
||||
this.priorities = new double[childTasks().size()];
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public double unallocated() {
|
||||
return total - allocated();
|
||||
}
|
||||
|
||||
public double allocated() {
|
||||
double sum = 0;
|
||||
for (double d : priorities) {
|
||||
sum += d;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public Allocation distributeEqually() {
|
||||
int count = priorities.length;
|
||||
double toDistribute = unallocated();
|
||||
double priorityToEach = toDistribute / count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
priorities[i] += priorityToEach;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void givePriority(int childTaskIndex, double amount) {
|
||||
if (amount > unallocated()) {
|
||||
throw new IllegalStateException("not enough space");
|
||||
}
|
||||
priorities[childTaskIndex] += amount;
|
||||
}
|
||||
|
||||
public double allocatedTo(IQuantizedParentTaskRelationship childRelationship) {
|
||||
return priorities[childTasks().indexOf(childRelationship)];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,9 @@ public abstract class TaskNode<T extends IChildTaskRelationship & ITaskRelations
|
|||
public TaskNode(Bot bot, DependencyType type) {
|
||||
super(bot);
|
||||
this.type = type;
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,9 +21,8 @@ import tenor.*;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider, IQuantizedDependentCostCalculator {
|
||||
public class AquireItemTask extends QuantizedTaskPriorityAllocationCache implements IClaimProvider, IQuantizedDependentCostCalculator {
|
||||
|
||||
HashMap<IQuantizedChildTaskRelationship, Integer> allocation; // allocation of what tasks have claim over what items in our inventory i guess
|
||||
String item;
|
||||
|
@ -62,7 +61,7 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider,
|
|||
}
|
||||
|
||||
public int cachedCurrentQuantity() {
|
||||
return allocation.entrySet().stream().mapToInt(Map.Entry::getValue).sum();
|
||||
return allocation.values().stream().mapToInt(x -> x).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,7 +70,7 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider,
|
|||
}
|
||||
|
||||
@Override
|
||||
public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
|
||||
public double effectiveAllocationSize(int quantity) {
|
||||
// how much of our priority would go to this child if it could provide us with quantity of the item we need
|
||||
|
||||
// here's the thing honey, we *already have* some, so you're really asking what's the priority of getting quantity MORE
|
||||
|
|
|
@ -20,7 +20,7 @@ package tenor.game;
|
|||
import tenor.ISingleParentSingularPriorityAllocator;
|
||||
import tenor.SingularTaskLeaf;
|
||||
|
||||
public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPriorityAllocator {
|
||||
public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPriorityAllocator { // TODO this should be quantized!
|
||||
|
||||
public final CraftingTask parent;
|
||||
|
||||
|
@ -32,6 +32,8 @@ public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPr
|
|||
|
||||
@Override
|
||||
public double cost() {
|
||||
return 420;
|
||||
// this is a dummy task to represent actually completing the crafting, given that we have all the ingredients and are at a crafting table
|
||||
// it's effectively free, so let's say it takes 1 second (20 ticks)
|
||||
return 20D;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ import tenor.ISingleParentQuantizedPriorityAllocator;
|
|||
import tenor.QuantizedTaskLeaf;
|
||||
|
||||
public class DoMine extends QuantizedTaskLeaf implements ISingleParentQuantizedPriorityAllocator {
|
||||
final MineTask parent;
|
||||
final MineWithToolTask parent;
|
||||
|
||||
public DoMine(MineTask parent) {
|
||||
public DoMine(MineWithToolTask parent) {
|
||||
super(parent.bot);
|
||||
this.parent = parent;
|
||||
addParent(parent);
|
||||
|
|
|
@ -17,20 +17,26 @@
|
|||
|
||||
package tenor.game;
|
||||
|
||||
import tenor.Bot;
|
||||
import tenor.ISingularChildTaskRelationship;
|
||||
import tenor.SingularTaskLeaf;
|
||||
import tenor.*;
|
||||
|
||||
public class GetToCraftingTableTask extends SingularTaskLeaf {
|
||||
|
||||
private final ComputationRequest craftingTable;
|
||||
|
||||
public GetToCraftingTableTask(Bot bot) {
|
||||
super(bot);
|
||||
registry().registerSingleton(this);
|
||||
this.craftingTable = ComputationRequestManager.INSTANCE.getByGoal(this, "GoalGetToBlock crafting_table"); // idk
|
||||
}
|
||||
|
||||
@Override
|
||||
public double cost() {
|
||||
return 69;
|
||||
Double d = craftingTable.cost();
|
||||
if (d == null) {
|
||||
// unknown, has not been calculated yet either way
|
||||
return 1000D; // estimate
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,31 +17,41 @@
|
|||
|
||||
package tenor.game;
|
||||
|
||||
import tenor.*;
|
||||
import tenor.DependencyType;
|
||||
import tenor.IQuantizedDependentCostCalculator;
|
||||
import tenor.ISingleParentQuantizedPriorityAllocator;
|
||||
import tenor.QuantizedTaskPriorityAllocationCache;
|
||||
|
||||
public class MineTask extends QuantizedTaskNode implements ISingleParentQuantizedPriorityAllocator {
|
||||
public class MineTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
|
||||
|
||||
// TODO shared claims of block locations in the world across all mine tasks across all bots
|
||||
|
||||
final AquireItemTask parent;
|
||||
|
||||
final DoMine doMine;
|
||||
final MineWithToolTask[] children;
|
||||
|
||||
|
||||
public MineTask(AquireItemTask parent) {
|
||||
super(parent.bot, DependencyType.ANY_ONE_OF);
|
||||
this.parent = parent;
|
||||
addParent(parent);
|
||||
this.doMine = new DoMine(this);
|
||||
String[] tools = getToolsCapableOfMining(parent.item);
|
||||
children = new MineWithToolTask[tools.length];
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
children[i] = new MineWithToolTask(this, tools[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuantityRelationship cost() {
|
||||
return x -> x * 324232;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
|
||||
return 0;
|
||||
static String[] getToolsCapableOfMining(String block) {
|
||||
switch (block) {
|
||||
case "iron_ore":
|
||||
return new String[]{"stone_pickaxe"};
|
||||
case "stone":
|
||||
case "cobblestone":
|
||||
return new String[]{"wooden_pickaxe"};
|
||||
case "log":
|
||||
return new String[]{"hand"};
|
||||
default:
|
||||
throw new IllegalStateException(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,5 +17,28 @@
|
|||
|
||||
package tenor.game;
|
||||
|
||||
public class MineWithToolTask {
|
||||
import tenor.DependencyType;
|
||||
import tenor.IQuantizedDependentCostCalculator;
|
||||
import tenor.ISingleParentQuantizedPriorityAllocator;
|
||||
import tenor.QuantizedTaskPriorityAllocationCache;
|
||||
|
||||
public class MineWithToolTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
|
||||
|
||||
public final String tool;
|
||||
MineTask parent;
|
||||
|
||||
AquireItemTask aquireTool;
|
||||
// TODO locate task?
|
||||
DoMine doMine;
|
||||
|
||||
|
||||
public MineWithToolTask(MineTask parent, String tool) {
|
||||
super(parent.bot, DependencyType.SERIAL);
|
||||
this.tool = tool;
|
||||
this.parent = parent;
|
||||
addParent(parent);
|
||||
this.aquireTool = registry().getItemBased(AquireItemTask.class, tool);
|
||||
aquireTool.addParent(this); // we aren't constructing this, so need to add us as a parent manually
|
||||
this.doMine = new DoMine(this);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue