1 package nl.tudelft.jpacman.board;
2
3 import nl.tudelft.jpacman.sprite.Sprite;
4
5 /**
6 * A unit that can be placed on a {@link Square}.
7 *
8 * @author Jeroen Roosen
9 */
10 public abstract class Unit {
11
12 /**
13 * The square this unit is currently occupying.
14 */
15 private Square square;
16
17 /**
18 * The direction this unit is facing.
19 */
20 private Direction direction;
21
22 /**
23 * Creates a unit that is facing east.
24 */
25 protected Unit() {
26 this.direction = Direction.EAST;
27 }
28
29 /**
30 * Sets this unit to face the new direction.
31 * @param newDirection The new direction this unit is facing.
32 */
33 public void setDirection(Direction newDirection) {
34 this.direction = newDirection;
35 }
36
37 /**
38 * Returns the current direction this unit is facing.
39 * @return The current direction this unit is facing.
40 */
41 public Direction getDirection() {
42 return this.direction;
43 }
44
45 /**
46 * Returns the square this unit is currently occupying.
47 * Precondition: <code>hasSquare()</code>.
48 *
49 * @return The square this unit is currently occupying.
50 */
51 public Square getSquare() {
52 assert invariant();
53 assert square != null;
54 return square;
55 }
56
57 /**
58 * Returns whether this unit is currently on a square.
59 *
60 * @return True iff the unit is occupying a square at the moment.
61 */
62 public boolean hasSquare() {
63 return square != null;
64 }
65
66 /**
67 * Occupies the target square iff this unit is allowed to as decided by
68 * {@link Square#isAccessibleTo(Unit)}.
69 *
70 * @param target
71 * The square to occupy.
72 */
73 public void occupy(Square target) {
74 assert target != null;
75
76 if (square != null) {
77 square.remove(this);
78 }
79 square = target;
80 target.put(this);
81 assert invariant();
82 }
83
84 /**
85 * Leaves the currently occupying square, thus removing this unit from the board.
86 */
87 public void leaveSquare() {
88 if (square != null) {
89 square.remove(this);
90 square = null;
91 }
92 assert invariant();
93 }
94
95 /**
96 * Tests whether the square this unit is occupying has this unit listed as
97 * one of its occupiers.
98 *
99 * @return <code>true</code> if the square this unit is occupying has this
100 * unit listed as one of its occupiers, or if this unit is currently
101 * not occupying any square.
102 */
103 protected boolean invariant() {
104 return square == null || square.getOccupants().contains(this);
105 }
106
107 /**
108 * Returns the sprite of this unit.
109 *
110 * @return The sprite of this unit.
111 */
112 public abstract Sprite getSprite();
113
114 /**
115 * A utility method for implementing the ghost AI.
116 *
117 * @param amountToLookAhead the amount of squares to follow this units direction in.
118 * @return The square amountToLookAhead spaces in front of this unit.
119 */
120 public Square squaresAheadOf(int amountToLookAhead) {
121 Direction targetDirection = this.getDirection();
122 Square destination = this.getSquare();
123 for (int i = 0; i < amountToLookAhead; i++) {
124 destination = destination.getSquareAt(targetDirection);
125 }
126
127 return destination;
128 }
129 }