168 lines
2.9 KiB
Java
168 lines
2.9 KiB
Java
package net.minecraft.world.level.pathfinder;
|
|
|
|
import java.util.Arrays;
|
|
|
|
public class BinaryHeap {
|
|
private Node[] heap = new Node[128];
|
|
private int size;
|
|
|
|
/**
|
|
* Adds a point to the path
|
|
*/
|
|
public Node insert(Node point) {
|
|
if (point.heapIdx >= 0) {
|
|
throw new IllegalStateException("OW KNOWS!");
|
|
} else {
|
|
if (this.size == this.heap.length) {
|
|
Node[] nodes = new Node[this.size << 1];
|
|
System.arraycopy(this.heap, 0, nodes, 0, this.size);
|
|
this.heap = nodes;
|
|
}
|
|
|
|
this.heap[this.size] = point;
|
|
point.heapIdx = this.size;
|
|
this.upHeap(this.size++);
|
|
return point;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clears the path
|
|
*/
|
|
public void clear() {
|
|
this.size = 0;
|
|
}
|
|
|
|
public Node peek() {
|
|
return this.heap[0];
|
|
}
|
|
|
|
/**
|
|
* Returns and removes the first point in the path
|
|
*/
|
|
public Node pop() {
|
|
Node node = this.heap[0];
|
|
this.heap[0] = this.heap[--this.size];
|
|
this.heap[this.size] = null;
|
|
if (this.size > 0) {
|
|
this.downHeap(0);
|
|
}
|
|
|
|
node.heapIdx = -1;
|
|
return node;
|
|
}
|
|
|
|
public void remove(Node node) {
|
|
this.heap[node.heapIdx] = this.heap[--this.size];
|
|
this.heap[this.size] = null;
|
|
if (this.size > node.heapIdx) {
|
|
if (this.heap[node.heapIdx].f < node.f) {
|
|
this.upHeap(node.heapIdx);
|
|
} else {
|
|
this.downHeap(node.heapIdx);
|
|
}
|
|
}
|
|
|
|
node.heapIdx = -1;
|
|
}
|
|
|
|
/**
|
|
* Changes the provided point's total cost if costIn is smaller
|
|
*/
|
|
public void changeCost(Node point, float cost) {
|
|
float f = point.f;
|
|
point.f = cost;
|
|
if (cost < f) {
|
|
this.upHeap(point.heapIdx);
|
|
} else {
|
|
this.downHeap(point.heapIdx);
|
|
}
|
|
}
|
|
|
|
public int size() {
|
|
return this.size;
|
|
}
|
|
|
|
/**
|
|
* Sorts a point to the left
|
|
*/
|
|
private void upHeap(int index) {
|
|
Node node = this.heap[index];
|
|
float f = node.f;
|
|
|
|
while (index > 0) {
|
|
int i = index - 1 >> 1;
|
|
Node node2 = this.heap[i];
|
|
if (!(f < node2.f)) {
|
|
break;
|
|
}
|
|
|
|
this.heap[index] = node2;
|
|
node2.heapIdx = index;
|
|
index = i;
|
|
}
|
|
|
|
this.heap[index] = node;
|
|
node.heapIdx = index;
|
|
}
|
|
|
|
/**
|
|
* Sorts a point to the right
|
|
*/
|
|
private void downHeap(int index) {
|
|
Node node = this.heap[index];
|
|
float f = node.f;
|
|
|
|
while (true) {
|
|
int i = 1 + (index << 1);
|
|
int j = i + 1;
|
|
if (i >= this.size) {
|
|
break;
|
|
}
|
|
|
|
Node node2 = this.heap[i];
|
|
float g = node2.f;
|
|
Node node3;
|
|
float h;
|
|
if (j >= this.size) {
|
|
node3 = null;
|
|
h = Float.POSITIVE_INFINITY;
|
|
} else {
|
|
node3 = this.heap[j];
|
|
h = node3.f;
|
|
}
|
|
|
|
if (g < h) {
|
|
if (!(g < f)) {
|
|
break;
|
|
}
|
|
|
|
this.heap[index] = node2;
|
|
node2.heapIdx = index;
|
|
index = i;
|
|
} else {
|
|
if (!(h < f)) {
|
|
break;
|
|
}
|
|
|
|
this.heap[index] = node3;
|
|
node3.heapIdx = index;
|
|
index = j;
|
|
}
|
|
}
|
|
|
|
this.heap[index] = node;
|
|
node.heapIdx = index;
|
|
}
|
|
|
|
/**
|
|
* Returns {@code true} if this path contains no points
|
|
*/
|
|
public boolean isEmpty() {
|
|
return this.size == 0;
|
|
}
|
|
|
|
public Node[] getHeap() {
|
|
return (Node[])Arrays.copyOf(this.heap, this.size);
|
|
}
|
|
}
|