summaryrefslogtreecommitdiffstats
path: root/src/jrummikub
diff options
context:
space:
mode:
Diffstat (limited to 'src/jrummikub')
-rw-r--r--src/jrummikub/model/StoneTray.java146
1 files changed, 133 insertions, 13 deletions
diff --git a/src/jrummikub/model/StoneTray.java b/src/jrummikub/model/StoneTray.java
index 6691a45..1eb3b0e 100644
--- a/src/jrummikub/model/StoneTray.java
+++ b/src/jrummikub/model/StoneTray.java
@@ -1,15 +1,19 @@
package jrummikub.model;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import jrummikub.util.Pair;
-/** A StoneTray is a collection of positioned objects (for example {@link Stone}s or {@link StoneSet}s. */
-public class StoneTray<E extends Sizeable> implements Iterable<Pair<E, Position>> {
- protected List<E> objects;
- protected List<Position> positions;
-
+/**
+ * A StoneTray is a collection of positioned objects (for example {@link Stone}s
+ * or {@link StoneSet}s.
+ */
+public class StoneTray<E extends Sizeable> implements
+ Iterable<Pair<E, Position>> {
+ protected List<Pair<E, Position>> objects = new ArrayList<Pair<E, Position>>();
+
/**
* Removes object from tray and returns it
*
@@ -17,9 +21,30 @@ public class StoneTray<E extends Sizeable> implements Iterable<Pair<E, Position>
* position of the object that will be removed
*/
public E pickUp(Position position) {
-
+ for (Pair<E, Position> i : objects) {
+ Position currentPosition = i.getSecond();
+ E currentObject = i.getFirst();
+ // Tests if position is left of, above ... the current object
+ if (position.getX() < currentPosition.getX()) {
+ continue;
+ }
+ if (position.getY() < currentPosition.getY()) {
+ continue;
+ }
+ if (position.getX() > currentPosition.getX()
+ + currentObject.getWidth()) {
+ continue;
+ }
+ if (position.getY() > currentPosition.getY()
+ + currentObject.getHeight()) {
+ continue;
+ }
+ // Position is inside the current object
+ objects.remove(i);
+ return currentObject;
+ }
+ return null;
}
-
/**
* Adds object to the tray
@@ -30,20 +55,115 @@ public class StoneTray<E extends Sizeable> implements Iterable<Pair<E, Position>
* {@link Position} to put the object
*/
public void drop(E object, Position position) {
-
+ drop(object, position, null);
}
+ private void drop(E object, Position position, Direction direction) {
+ for (Pair<E, Position> i : objects) {
+ Position currentPosition = i.getSecond();
+ E currentObject = i.getFirst();
+ // Tests if position is left of, above ... the current object
+ if (position.getX() + object.getWidth() <= currentPosition.getX()) {
+ continue;
+ }
+ if (position.getY() + object.getHeight() <= currentPosition.getY()) {
+ continue;
+ }
+ if (position.getX() >= currentPosition.getX()
+ + currentObject.getWidth()) {
+ continue;
+ }
+ if (position.getY() >= currentPosition.getY()
+ + currentObject.getHeight()) {
+ continue;
+ }
+ // Object would be placed inside the current object
+ if (direction == null) {
+ direction = getMoveDirection(object, position, i);
+ }
+ Position newPosition = null;
+ // TODO dinge bewegen
+ switch (direction) {
+ case TOP:
+ newPosition = new Position(i.getSecond().getX(),
+ position.getY() - currentObject.getHeight());
+ break;
+ case BOTTOM:
+ newPosition = new Position(currentPosition.getX(),
+ position.getY() + object.getHeight());
+ break;
+ case LEFT:
+ newPosition = new Position(position.getX()
+ - currentObject.getWidth(), currentPosition.getY());
+ break;
+ case RIGHT:
+ newPosition = new Position(position.getX() + object.getWidth(),
+ currentPosition.getY());
+ break;
+ }
+ objects.remove(i);
+ drop(currentObject, newPosition, direction);
+ }
+ objects.add(new Pair<E, Position>(object, position));
+ }
- public Position getPosition (E object) {
+ private Direction getMoveDirection(E object, Position position,
+ Pair<E, Position> blocking) {
+ boolean isVertical = getMoveOrientationn(object, position, blocking);
+ float objectMidpointX = position.getX() + object.getWidth() / 2;
+ float objectMidpointY = position.getY() + object.getHeight() / 2;
+ float blockingMidpointX = blocking.getSecond().getX()
+ + blocking.getFirst().getWidth() / 2;
+ float blockingMidpointY = blocking.getSecond().getY()
+ + blocking.getFirst().getHeight() / 2;
+ if (isVertical) {
+ if (objectMidpointY < blockingMidpointY) {
+ return Direction.BOTTOM;
+ } else {
+ return Direction.TOP;
+ }
+ } else {
+ if (objectMidpointX < blockingMidpointX) {
+ return Direction.RIGHT;
+ } else {
+ return Direction.LEFT;
+ }
+ }
+ }
-
+ private boolean getMoveOrientationn(E object, Position position,
+ Pair<E, Position> blocking) {
+ float objectRight = position.getX() + object.getWidth();
+ float blockingRight = blocking.getSecond().getX()
+ + blocking.getFirst().getWidth();
+ float overlapRight = Math.min(objectRight, blockingRight);
+ float overlapLeft = Math.max(position.getX(), blocking.getSecond()
+ .getX());
+ float overlapX = overlapRight - overlapLeft;
+ float objectBottom = position.getY() + object.getHeight();
+ float blockingBottom = blocking.getSecond().getY()
+ + blocking.getFirst().getHeight();
+ float overlapBottom = Math.min(objectBottom, blockingBottom);
+ float overlapTop = Math.max(position.getY(), blocking.getSecond()
+ .getY());
+ float overlapY = overlapBottom - overlapTop;
+ // vertical or horizontal Shift
+ // TODO magic factor
+ return overlapX > overlapY;
}
+ public Position getPosition(E object) {
+ for (Pair<E, Position> i : objects) {
+ if (object.equals(i.getFirst())) {
+ return i.getSecond();
+ }
+ }
+ return null;
+ }
@Override
public Iterator<Pair<E, Position>> iterator() {
- // TODO Auto-generated method stub
- return null;
+ return objects.iterator();
}
-
+
}