package me.stieglmaier.sphereMiners.model.util; import javafx.scene.paint.Color; import me.stieglmaier.sphereMiners.main.Constants; import me.stieglmaier.sphereMiners.model.ai.Player; /** * Be careful sphere is a mutable class. Only an * immutable view should be passed to AIs. * */ public class MutableSphere implements Sphere { private final Constants constants; private Position position; private Position direction = new Position(); private int size; private Color color; private final Player owner; /** * Creatae a new Mutable sphere with the relevant constants * * @param owner the player who owns this sphere * @param constants the constants to use for this sphere */ public MutableSphere(Constants constants, Player owner) { this.constants = constants; this.owner = owner; size = constants.getInitialSphereSize(); } /** * Creatae a new Mutable sphere with the relevant constants * * @param owner the player who owns this sphere * @param constants the constants to use for this sphere */ public MutableSphere(Constants constants) { this.constants = constants; this.owner = null; size = constants.getInitialSphereSize(); } /** * {@inheritDoc} */ @Override public Player getOwner() { return owner; } /** * {@inheritDoc} */ @Override public void setDirection(Position direction) { this.direction = direction; } /** * {@inheritDoc} */ @Override public Position getDirection() { return direction; } /** * {@inheritDoc} */ @Override public void setPosition(Position position) { this.position = position; } /** * {@inheritDoc} */ @Override public Position getPosition() { return position; } /** * {@inheritDoc} */ @Override public double getRadius() { return Math.sqrt(size / Math.PI); } /** * {@inheritDoc} */ @Override public Color getColor() { return color; } /** * {@inheritDoc} */ @Override public void setColor(Color color) { this.color = color; } /** * {@inheritDoc} */ @Override public void setSize(int size) { this.size = size; } /** * {@inheritDoc} */ @Override public int getSize() { return this.size; } /** * {@inheritDoc} */ @Override public MutableSphere split() { if (size >= constants.getMinSplittingsize()) { MutableSphere newSphere = new MutableSphere(constants, owner); newSphere.size = size / 2; newSphere.direction = direction; newSphere.position = position; size = (size + 1) / 2; return newSphere; } else { return null; } } /** * {@inheritDoc} */ @Override public void merge(Sphere sphere) { if (canBeMergedWidth(sphere)) { size += sphere.getSize(); sphere.setSize(0); } } /** * {@inheritDoc} */ @Override public boolean canBeMergedWidth(Sphere otherSphere) { return position.dist(otherSphere.getPosition()) - (getRadius() + otherSphere.getRadius()) <= constants.getMinMergeDist() // TODO more constraints on size? && size > otherSphere.getSize(); } /** * Create an immutable view of this sphere object. * * @return an immutable view of the sphere */ public Sphere toImmutableSphere() { return new ImmutableSphere(this); } /** * Creates an immutable copy of this sphere object. * * @return an immutable copy of this sphere */ public Sphere immutableCopy() { MutableSphere newSphere = new MutableSphere(constants, owner); newSphere.size = size; newSphere.direction = direction; newSphere.position = position; newSphere.color = color; return newSphere.toImmutableSphere(); } /** * {@inheritDoc} */ public String toString() { return "Sphere (" + size + ") at " + position; } private static class ImmutableSphere implements Sphere { Sphere sphere; private ImmutableSphere(Sphere sphere) { this.sphere = sphere; } /** * {@inheritDoc} */ @Override public Player getOwner() { return sphere.getOwner(); } /** * {@inheritDoc} */ @Override public Position getDirection() { return sphere.getDirection(); } /** * {@inheritDoc} */ @Override public Position getPosition() { return sphere.getPosition(); } /** * {@inheritDoc} */ public double getRadius() { return sphere.getRadius(); } /** * {@inheritDoc} */ @Override public int getSize() { return sphere.getSize(); } /** * {@inheritDoc} */ @Override public Color getColor() { return sphere.getColor(); } /** * {@inheritDoc} */ @Override public void setColor(Color color) { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public void setSize(int size) { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public void setDirection(Position direction) { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public void setPosition(Position position) { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public MutableSphere split() { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public void merge(Sphere sphere) { throw new UnsupportedOperationException("This object is immutable!"); } /** * {@inheritDoc} */ @Override public boolean canBeMergedWidth(Sphere sphere2) { return sphere.canBeMergedWidth(sphere2); } public String toString() { return "Sphere (" + sphere.getSize() + ") at " + sphere.getPosition(); } } }