-
Notifications
You must be signed in to change notification settings - Fork 0
/
Elevator.java
212 lines (191 loc) · 7.04 KB
/
Elevator.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import java.util.*;
/**
* Elevator class modeled real world elevator.
* It stores its status information and also passenger objects
* who are on board.
*
* @author Min Kim
*
*/
public class Elevator {
public final static int WAITING = 0;
public final static int MOVING = 1;
public final static int DOOROPENING = 2;
public final static int DISEMBARKING = 3;
public final static int BOARDING = 4;
public final static int DOORCLOSING = 5;
public final static String [] STATUS = {"WAITING", "MOVING", "DOOROPENING", "DISEMBARKING", "BOARDING", "DOORCLOSING"};
private int currentStatus;
private int [] timeSpent = new int [6];
private ArrayList<Passenger> boardedPassenger ;
private boolean [] targetFloor;
private int direction;
private int id;
private int currentFloor;
private Building building;
private int nextDestination;
/**
* Constructs new empty elevator. Default status is WAITING and
* default floor is 1.
* Note that elevator WAITING is idle.
*
* @param b building where elevator resides
* @param newId elevator ID
* @param newCapacity elevator capacity
*/
public Elevator (Building b, int newId) {
building = b;
currentStatus = WAITING;
id = newId;
currentFloor = 1;
direction = 0;
nextDestination = 0;
this.boardedPassenger = new ArrayList<Passenger> ();
this.targetFloor = new boolean [Settings.numOfFloors() + 1];
for (int i=0; i < Settings.numOfFloors(); i++) {
targetFloor[i] = false;
}
}
/**
* Get elevator's nextDestination
* @return nextDestination
*/
public int nextDestination () { return nextDestination; }
/**
* Get elevator's current floor
* @return currentFloor
*/
public int currentFloor() { return currentFloor; }
/**
* Get elevator's current status.
* Check the static final variables to match number and status
* @return current status
*/
public int currentStatus() { return currentStatus; }
/**
* Elevator moving direction.
* @return moving direction. 1 for up, 0 for stay, -1 for down
*/
public int direction() { return direction; }
/**
* Get elevator's id
* @return elevator's identification number
*/
public int id() { return id; }
/**
* Get passengers boarded in the elevator
* @return ArrayList of passengers boarded
*/
public ArrayList<Passenger> boardedPassenger() { return boardedPassenger;}
/**
* Get the time statistics this elevator spent
* @return an array of time spent
*/
public int[] timeSpent() { return timeSpent; }
/**
* Board a passenger to this elevator. Boarding is possible only
* when its current status is BOARDING. On success, passenger is
* added to elevator's ArrayList.
* @param p Passenger who want to board
* @return true if succeeded
*/
public boolean boardPassenger(Passenger p) {
if (currentStatus != Elevator.BOARDING) return false;
if (boardedPassenger.size() >= Settings.elevatorMaxCapacity()) return false;
boardedPassenger.add(p);
setTarget(p.targetFloor());
return true;
}
/**
* Elevator wait for call. When there is call, it moves,
* open door, release passengers and get new passengers,
* and move to where passengers want.
*/
public void elevatorAct() {
timeSpent[currentStatus] ++;
switch (currentStatus) {
case WAITING:
nextDestination = setNextDestination();
if (nextDestination != currentFloor || boardedPassenger.size() >0) {
currentStatus = MOVING;
} else if (nextDestination == currentFloor
&& building.isWaitingAtFloor(currentFloor))
currentStatus = DOOROPENING;
break;
case MOVING:
if (currentFloor == nextDestination) {
currentStatus = DOOROPENING;
break;
}
if ((currentFloor == Settings.numOfFloors() && direction ==1)
|| (currentFloor == 0 && direction ==-1)) {
direction = -direction;
}
currentFloor += direction;
break;
case DOOROPENING:
if (boardedPassenger == null) currentStatus = BOARDING;
else currentStatus = DISEMBARKING;
break;
case DISEMBARKING:
currentStatus = BOARDING;
break;
case BOARDING:
currentStatus = DOORCLOSING;
break;
case DOORCLOSING:
targetFloor [currentFloor] = false;
nextDestination = setNextDestination();
currentStatus = (nextDestination==currentFloor
&& !building.isWaitingAtFloor(currentFloor)) ? WAITING : MOVING;
}
}
/**
* Add elevator's target floor and reset next stop
* in case the new added floor is nearer
* @param target
*/
public void setTarget(int target) {
targetFloor[target] = true;
nextDestination = setNextDestination();
}
/**
* Calculate elevator's nearest destination based on the
* distance and elevator's direction. If there is no available
* destination then it change its status to WAIT.
*
* @return elevator's new nearest destination.
*/
private int setNextDestination() {
int newDestination = -1;
int minDistance = 100;
for (int i=0; i<Settings.numOfFloors(); i++) {
if (targetFloor[i]) {
int distance = i - currentFloor ;
if ((distance > 0 && direction == -1) || (distance < 0 && direction == 1)) {
distance = Math.abs(distance) + Settings.numOfFloors();
} else distance = Math.abs(distance);
if (minDistance > distance) {
minDistance = distance;
newDestination = i;
}
}
}
if (newDestination == -1 ) {
newDestination = currentFloor;
direction = 0;
currentStatus = WAITING;
} else {
direction = (newDestination > currentFloor) ? 1 : -1;
}
return newDestination;
}
/**
* unboard the passenger from elevator, and put passenger into the building
* @param p
*/
public void unboard (Passenger p) {
boardedPassenger.remove(p);
building.passengerEnters(p);
}
}