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