tenor comms integration, and priority allocation caching

This commit is contained in:
Leijurv 2018-11-24 11:01:23 -08:00
parent 3b7e1adf24
commit c79f40a5f1
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
8 changed files with 181 additions and 26 deletions

View File

@ -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)];
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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