CS2030 Practical Assessment #1

Back to homepage

Elevator

Elevators are indeed a ubiquitous, and often overlooked, part of modern infrastructure, with an estimated 250 trips taken per person annually. They are essential for the functionality of multi-story, commercial, residential, and industrial buildings powered by Gemini.. note the extra commas and the mdash

An elevator is operated by pressing a button outside the elevator, i.e. at the lobby. These buttons at different levels of the lobby are used to deploy an elevator to the desired level. After the elevator has been deployed, buttons within the elevator are pressed so as to fetch passengers to their desired levels. -- powered by hchia.. as well as the rest of this document

Task

Your task is to design a software using OOP modeling to simulate riding an elevator.

Take Note!

This task comprises a number of levels. You are required to complete ALL levels.

The following are the constraints imposed on this task. In general, you should keep to the constructs and programming discipline instilled throughout the module.

In the following level specifications, you will be guided on the classes and non-private methods to define. DO NOT create any other classes; any other method you create MUST be declared private. However, you can create other non-private constructors.

The following classes has been provided for you. DO NOT replace them with your own versions.

Level 1

Let us start by writing a Leveled abstract class to represent some abstract leveled entity (or thing), i.e. something with a level. The action of pressing a button at the lobby of a certain level is a concrete leveled entity, and we represent it using an Action class.

Define the Action class according to the sample run below.

$ javac your_java_files
$ jshell your_java_files_in_bottom-up_dependency_order

jshell> new Action(1)
$.. ==> Action at L1

jshell> new Action(5)
$.. ==> Action at L5

jshell> new Action(1) instanceof Leveled
$.. ==> true

jshell> new Leveled(1)
Error:
Leveled is abstract; cannot be instantiated
 new Leveled(1)

In the above, L1 denotes level 1. You may also assume that levels are always positive integers (i.e. > 0).

Level 2

Leveled entities can be compared and also checked for equality. Define the compareTo and equals method following the sample run below.

jshell> new Action(1).compareTo(new Action(5)) < 0
$.. ==> true

jshell> new Action(1).compareTo(new Action(1)) == 0
$.. ==> true

jshell> new Action(10).compareTo(new Action(5)) > 0
$.. ==> true

jshell> Leveled lvled = new Action(10)
lvled ==> Action at L10

jshell> lvled.compareTo(lvled)
$.. ==> 0

jshell> new Action(1).equals(new Action(1))
$.. ==> true

jshell> new Action(1).equals(new Action(5))
$.. ==> false

jshell> new Action(1).equals(1)
$.. ==> false

jshell> lvled.equals(lvled)
$.. ==> true

jshell> lvled.equals(10)
$.. ==> false

jshell> lvled.equals(new Action(10))
$.. ==> true

Level 3

When a button located at the lobby is pressed, an elevator is deployed to that level. Write an Elevator class to represent an elevator with a constructor that takes in the following in order:

The following is an example of an elevator situated at level 1 at time 3 units, with pending actions at levels 5 and 10.

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10)))
$.. ==> Elevator: L1@3

For the purpose of debugging, include a printActions method to output the list of actions. Hint: since the printActions method is meant to terminate the pipeline, declare the return type as void.

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).printActions()
Action at L5
Action at L10

Write a deploy method that takes no arguments so as to deploy the elevator to the first level indicated by the list of pending actions. You may assume the following:

Also take note that the elevator takes one unit of time to ride up one level. Here is an example:

jshell> InfList<Action> actions = InfList.of(new Action(5), new Action(10))

jshell> new Elevator(1, 3, actions).deploy()
$.. ==> Elevator: L5@8

In the above test case, the elevator starts at level 1 at time 3. Deploying the elevator to level 5 (four levels up) will result in the elevator being deployed to that level in time 7. In addition, each action also takes an additional one unit of time (think of it as time taken to open the elevator doors). Hence the deployment completes in time 8.

jshell> new Elevator(1, 3, actions).deploy().printActions()
Action at L10

jshell> new Elevator(1, 3, actions).deploy().deploy()
$.. ==> Elevator: L10@14

jshell> new Elevator(1, 3, actions).deploy().deploy().deploy()
$.. ==> Elevator: L10@14

Note in the last test case that deployment with no pending actions leaves the elevator as it is.

Level 4

Other than buttons outside the elevator (i.e at the lobby), there are also buttons inside the elevator to fetch passengers to different levels. Include a fetch method that takes in an integer to represent a passenger to be fetched to his/her desired level.

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).fetch(5)
$.. ==> Elevator: L1@3

Note from the above that calling the fetch method does not immediately deploy the elevator to that level. Instead, a FetchAction is placed at the back of the pending actions list. Each FetchAction also takes up one unit of time.

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).fetch(5).printActions()
Action at L5
Action at L10
FetchAction at L5

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).fetch(5).deploy()
$.. ==> Elevator: L5@9

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).deploy().fetch(20).printActions()
Action at L10
FetchAction at L20

jshell> new Elevator(1, 3, InfList.of(new Action(5), new Action(10))).deploy().fetch(20).deploy()
$.. ==> Elevator: L10@14

Hint: to add to the list of pending actions, you may find the concat method of InfList useful. Also note that a passenger in an upriding elevator can only request to be fetched to levels above the current level. The following sample runs show that no further action is being added to the pending actions list for the case of an invalid fetch.

jshell> InfList<Action> actions = InfList.of(new Action(5), new Action(10))

jshell> new Elevator(1, 3, actions).deploy().fetch(3).printActions() // invalid!
Action at L10

jshell> new Elevator(1, 3, actions).deploy().fetch(5).printActions() // invalid!
Action at L10

Lastly, there could be more than one passenger entering a lift at a certain level, each requesting to be fetched to different levels. Include an overloaded fetch method that takes in an InfList list of integers representing all levels to be fetched to. You may only assume that the list of integers are unique.

jshell> new Elevator(1, 3, actions).fetch(InfList.of(7, 20)).deploy().deploy().deploy()
$.. ==> Elevator: L10@15

Level 5

Thus far, Elevator has been defined to be upriding by default. Moreover, it is rather cumbersome to call the constructor with InfList<Action>. Write an UpRiding class to represent an upriding elevator with a constructor that takes in the following in order:

Also include a DownRiding class to represent a downriding elevator with a constructor that takes the same arguments as the UpRiding class.

jshell> Elevator elevator = new UpRiding(1, 3, InfList.of(5, 10))
elevator ==> Elevator: L1@3

jshell> elevator.deploy().deploy().deploy() instanceof UpRiding
$.. ==> true

jshell> elevator = new DownRiding(20, 3, InfList.of(5, 10))
elevator ==> Elevator: L20@3

jshell> elevator.deploy().fetch(InfList.of(9,10,11)).deploy()
$.. ==> Elevator: L9@16

jshell> elevator.deploy().fetch(InfList.of(9,10,11)).deploy() instanceof DownRiding
$.. ==> true

Note that every call to the deploy or fetch methods of an UpRiding (or DownRiding) elevator must return an elevator of the same type. In addition, to ensure proper adherence to the DRY principle, there should NOT be any properties declared in the UpRiding and DownRiding classes.