feat: implemented Graph
This commit is contained in:
parent
bbcba20499
commit
35b6644dd0
129
api/src/main/java/ru/dragonestia/msb3/api/debug/Graph.java
Normal file
129
api/src/main/java/ru/dragonestia/msb3/api/debug/Graph.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package ru.dragonestia.msb3.api.debug;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class Graph {
|
||||||
|
|
||||||
|
private final static AtomicInteger freeId = new AtomicInteger(1);
|
||||||
|
|
||||||
|
private final Map<Integer, Node> nodes = new HashMap<>();
|
||||||
|
|
||||||
|
public Node addNode(Vec pos) {
|
||||||
|
var node = new Node(pos);
|
||||||
|
nodes.put(node.getId(), node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addNodeLink(Node from, Node to) {
|
||||||
|
return from.addLink(to) && to.addLink(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLink(Node from, Node to) {
|
||||||
|
from.removeLink(to);
|
||||||
|
to.removeLink(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeNode(Node node) {
|
||||||
|
nodes.remove(node.getId());
|
||||||
|
node.getLinks().forEach(other -> removeLink(other, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Node> getNodes() {
|
||||||
|
return nodes.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Node> findNode(int id) {
|
||||||
|
return Optional.ofNullable(nodes.get(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializedGraph serialize() {
|
||||||
|
var nodes = new ArrayList<SerializedNode>();
|
||||||
|
var links = new HashSet<IntPair>();
|
||||||
|
|
||||||
|
for (var node: getNodes()) {
|
||||||
|
nodes.add(new SerializedNode(node.id, node.position.x(), node.position.y(), node.position.z()));
|
||||||
|
|
||||||
|
for (var otherNode: node.getLinks()) {
|
||||||
|
if (links.contains(new IntPair(otherNode.getId(), node.getId()))) continue;
|
||||||
|
links.add(new IntPair(node.getId(), otherNode.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SerializedGraph(nodes, links);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Graph deserialize(SerializedGraph serializedGraph) {
|
||||||
|
var graph = new Graph();
|
||||||
|
for (var node: serializedGraph.nodes) {
|
||||||
|
graph.addNode(new Vec(node.x(), node.y(), node.z()));
|
||||||
|
}
|
||||||
|
for (var link: serializedGraph.links) {
|
||||||
|
graph.addNodeLink(graph.findNode(link.a).orElseThrow(), graph.findNode(link.b).orElseThrow());
|
||||||
|
}
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public static class Node {
|
||||||
|
|
||||||
|
@Getter private final int id = freeId.getAndIncrement();
|
||||||
|
@Getter private final Vec position;
|
||||||
|
private final Map<Node, Double> links = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean addLink(Node node) {
|
||||||
|
if (id == node.getId()) return false;
|
||||||
|
return links.put(node, position.distance(node.position)) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeLink(Node node) {
|
||||||
|
links.remove(node);
|
||||||
|
node.links.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLink(Node node) {
|
||||||
|
if (id == node.getId()) return true;
|
||||||
|
return links.containsKey(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Node> getLinks() {
|
||||||
|
return links.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<DistancePair> getLinksWithDistance() {
|
||||||
|
return links.entrySet().stream()
|
||||||
|
.map(entry -> new DistancePair(entry.getKey(), entry.getValue()))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDistanceTo(Node node) {
|
||||||
|
return links.getOrDefault(node, Double.NaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null) return false;
|
||||||
|
if (obj instanceof Node other) {
|
||||||
|
return id == other.id;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SerializedGraph(List<SerializedNode> nodes, Set<IntPair> links) {}
|
||||||
|
|
||||||
|
public record SerializedNode(int id, double x, double y, double z) {}
|
||||||
|
|
||||||
|
public record IntPair(int a, int b) {}
|
||||||
|
|
||||||
|
public record DistancePair(Node node, double distance) {}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user