-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOccupant.java
147 lines (133 loc) · 3.88 KB
/
Occupant.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* An abstract cell occupant in a Sokoban puzzle.
*
* @author Dr Mark C. Sinclair
* @version September 2021
*
*/
public abstract class Occupant {
public Occupant(Cell cell) {
/**
* Constructor with cell currently occupied
*
* @param cell the cell occupied by this actor (cannot be null)
*/
if (cell == null)
throw new IllegalArgumentException("cell cannot be null");
this.cell = cell;
}
/**
* Checks if this occupant is an actor (overridden by Actor)
*
* @return false
*/
public boolean isActor() {
return false;
}
/**
* Checks if this occupant is a box (overridden by Box)
*
* @return false
*/
public boolean isBox() {
return false;
}
/**
* Checks if this occupant is a wall (overridden by Wall)
*
* @return false
*/
public boolean isWall() {
return false;
}
/**
* Gets the character to use for display purposes for this cell
*
* @return character to use for display purposes for this cell
*/
public abstract char getDisplay();
/**
* Changes the cell for this occupant
*
* @param cell the cell occupied by this occupant (cannot be null)
*/
void setCell(Cell cell) {
if (cell == null)
throw new IllegalArgumentException("cell cannot be null");
this.cell = cell;
}
/**
* Check if this occupant is safe (from getting stuck to a box) if it moves in the given direction
* (overridden by Box)
*
* @param dir the direction to check
* @return false
*/
public boolean isStuckSafe(Direction dir) {
return false;
}
/**
* Checks if the occupant can move to the next cell in a given direction
* (overridden by Actor and Box)
*
* @param dir the direction to check
* @return false
*/
public boolean canMove(Direction dir) {
return false;
}
/**
* If it is safe, move the occupant to the next cell in a given direction
*
* @param dir the direction to move
*/
public void move(Direction dir) {
if (!canMove(dir))
throw new IllegalArgumentException("cannot move "+dir);
Cell next = cell.getCell(dir);
if (!next.isEmpty())
next.move(dir);
cell.setOccupant(null);
next.setOccupant(this);
}
/**
* Checks if this cell is a target occupied by a box
* (overridden by Box)
*
* @return false
*/
public boolean onTarget() {
return false;
}
/**
* A String representation of the Occupant
*
* @return the String representation
*/
@Override
public String toString() {
return ""+getDisplay();
}
/**
* A factory method to construct an Occupant based on the display character and cell to be occupied.
* The display character must be valid.
*
* @param display the display character
* @param cell the cell to be occupied
*/
public static Occupant getInstance(char display, Cell cell) {
if (!Sokoban.validDisplay(display))
throw new IllegalArgumentException("not valid display character for an Occupant");
if (cell == null)
throw new IllegalArgumentException("cell cannot be null");
if (cell.isTarget() && (display != Sokoban.TARGET_BOX) && (display != Sokoban.TARGET_ACTOR))
throw new IllegalArgumentException("if cell is target, display must be '"+Sokoban.TARGET_BOX+"' or '"+Sokoban.TARGET_ACTOR+"'");
if (display == Sokoban.WALL)
return new Wall(cell);
else if (display == Sokoban.BOX || display == Sokoban.TARGET_BOX)
return new Box(cell);
else // is ACTOR or TARGET_ACTOR
return new Actor(cell);
}
protected Cell cell = null;
}