Powering Devices

One reactor can power one light... for now...

Motivation

Welcome on briefing of next mission, cadet! The introductory warm-up round is successfully behind you and together with our tactical and strategic team we expect you are quite well warmed-up by controlling reactor.

However, several skills which you obtain during today's training will come in handy when fulfilling various missions in the field. It concerns especially a skill of using reference data types as methods parameters. This unostentatious ability saved life of multitude of object-oriented programmers, so do not underestimate it!

Good luck with achieving goals of today's mission! From the operation center greets Manager.

Warning

Before you commence with work on today's lab, update the game library that you use in your project to version 2.0.2 by following this procedure.

Objectives

  • Using keyword this in your code.
  • Creating parametrized constructors.
  • Reference as method parameter.

Postup

Step 1: First tools

As you may have noticed, working with nuclear reactor is no joke, especially when it starts overheating and there is no way to repair it...

Class diagram presenting the relationship between classes Hammer and AbstractActor.
Obr. 1: Class diagram presenting the relationship between classes Hammer and AbstractActor.

Task 1.1

In package sk.tuke.kpi.oop.game create class Hammer which will represent a hammer.

Animation representing hammer on the game map is stored in file hammer.png. Hammer will have an instance variable (field) for number of its uses which you initialize through constructor to value 1. Properly set visibility of the variable and provide access to it with respective get method.

Animation hammer.png (sprite dimensions: _16x16_)
Obr. 2: Animation hammer.png (sprite dimensions: 16x16)

Task 1.2

In class Hammer add method use() which will represent hammer's usage.

Each use of hammer should update the amount of remaining usages. When it reaches 0 remove the hammer from game scene (hammer broke).

Comment

Each actor displayed in the game is part of active game scene, to which actor has a reference. Scene can add actors and also remove them. Use functionalities of development environment to find a way for obtaining reference to game scene and use it for removing used hammer from the game.

Step 2: If all you have is a hammer, everything looks like a nail

In this step we will try to repair damaged reactor with just the right tool: a hammer.

Class diagram representing relationship between Reactor and Hammer.
Obr. 3: Class diagram representing relationship between Reactor and Hammer.

Task 2.1

In class Reactor create method repairWith() which will enable repairing the reactor.

The method will return no value and will have one parameter of type Hammer. Its behaviour should be implemented as follows:

  • The method will work only if its parameter is a reference to instance of class Hammer (it is not null) and value of reactor's damage is above 0% but reactor is not yet completely broken.
  • Using the hammer will decrease reactor's damage by 50 but resulting value of damage can not drop below 0. Therefore, if reactor's damage is, let's say, 92%, after using hammer the value of damage will decrease to value 42%. If reactor's damage is 35% it will be completely repaired after using hammer (damage will be 0%).

Comment

Since damage grows linearly with increasing temperature, it's also necessary to correspondingly decrease temperature after decreasing damage. You will return to this part of the task later in additional tasks.

Comment

When implementing the functionality, keep in mind that besides updating temperature and damage you need to update the animation that graphically represents state of reactor as well. Beware of code duplication!

Task 2.2

Verify correctness of your implementation.

Create instance of reactor and several hammers in the game map. Next, overheat the reactor so that it damages (but does not break) and try to repair it by using hammer.

Step 3: Shutting Down Reactor

Splendid! Now we can manage to repair reactor even when it overheats (too bad a hammer will not do the work in real life). Now it would be great to find means by which reactor could be put into inactive state, or contrariwise, started up.

Task 3.1

In class Reactor create methods turnOn() and turnOff() which will allow to start and shutdown the reactor.

When implementing the functionality, keep in mind that reactor can work only if it's turned on (if it's off, it won't be possible to increase or decrease its temperature - the methods should have no effect). Also ensure that a newly created instance of reactor is turned off by default. When reactor breaks, ensure that it turns off. Adjust your implementation so that it conforms with these conditions.

Task 3.2

To represent reactor in its off state, use image reactor.png for animation.

Prepare the required object of animation beforehand in reactor's constructor and properly adjust method for updating current animation and methods turnOn() and turnOff().

Comment

In case reactor turns off due to breaking, ensure that its animation stays represented by image reactor_broken.png.

Task 3.3

In class Reactor create method isRunning() which will find out whether reactor is on (returns value true) or off (returns value false).

Step 4: Gaining Control

Managing overheated rector can be really dangerous business. That is why we will now try to create a remote controller that should allow us to turn reactor on or off without direct physical contact with it.

Class diagram representing relationship between Reactor and Controller.
Obr. 4: Class diagram representing relationship between Reactor and Controller.

Task 4.1

Create class Controller which will represent a controller for particular reactor.

Image of controller is in file switch.png. The class will have only one instance variable reactor which will hold reference to controlled reactor. Initialise its value in constructor which will obtain the reference to reactor through parameter.

Animation switch.png (sprite dimensions: _16x16_)
Fig. 5: Animation switch.png (sprite dimensions: 16x16)

Task 4.2

In controller create method toggle() which will turn on/turn off the controlled reactor.

Task 4.3

Verify correctness of your implementation.

By using Inspector tool create several instances of reactor and each of them connect with one controller. Verify functionality of controllers.

Four reactors managed by four controllers. However, which controls which?
Fig. 6: Four reactors managed by four controllers. However, which controls which?

Step 5: Powering Light

Reactor which you implemented last week and repaired today creates electric energy. In this step you will create an electric appliance which will be connected to reactor. Naturally, it will work only if reactor produces electricity.

Class diagram representing relationship between Light, Reactor and AbstractActor.
Obr. 7: Class diagram representing relationship between Light, Reactor and AbstractActor.

Task 5.1

Based on the class diagram above, in package sk.tuke.kpi.oop.game create class Light which will represent light and test your implementation.

The class will have two methods:

  • toggle() - Method will change light's state from on to off and vice-versa. However, light will actually shine (its animation will be light_on.png) only when powered with electricity.
  • setElectricityFlow() - Method will have one parameter of type boolean which will specify whether electricity is provided to light or not.

For animation of shining light use image from file light_on.png and for animation of light off use file light_off.png.

Animation light_on.png (sprite dimensions: _16x16_).
Fig. 8: Animation light_on.png (sprite dimensions: 16x16).
Animation light_off.png (sprite dimensions: _16x16_).
Fig. 9: Animation light_off.png (sprite dimensions: 16x16).

Comment

Do not forget that light should start shining also when its state is on and you just connect it to electricity source!

Task 5.2

In reactor's class create methods addLight() and removeLight() with which you will be able to connect/disconnect light to/from reactor.

Current model of reactor will be able to power only one electric appliance at the same time - in our case it is just one light. Obtain reference to light as parameter in method addLight().

Do not forget that when calling methods addLight() and removeLight() you need to update state of the electric appliance according to the state of reactor - if reactor is turned on and it's not broken then it produces electricity. Also, do not forget to adjust all the other methods that are involved in the change of reactor's state.

Task 5.3

Verify correctness of your implementation by creating two instances of reactor and connecting two instances of light to them.

To verify your functionality you can use the following truth table which illustrates behaviour of light:

isOn isPowered light' state
true true shining
true false not shining
false true not shining
false false not shining
Each reactor powers one light (one of them is obviously done powering).
Fig. 10: Each reactor powers one light (one of them is obviously done powering).

Additional tasks

Task A.1

As part of repairing reactor with hammer in method repairWith() properly update also reactor's temperature.

Go back to task 4.1 from last week's scenario and notice the graph of dependence of damage from temperature. When we invert the graph of this relationship to get dependence of temperature from damage, its behaviour in the area of 0% damage is ambiguous for calculation of temperature (it's not a function). Therefore adjust the calculation of temperature when repairing reactor as follows:

  • first, determine dependence of temperature from damage based on the area of graph where their relationship is linear (formulate an equation),
  • define a helper local variable for new value of damage (initial value before the repair decreased by 50) regardless of whether the result will be positive or negative number,
  • use value of the helper variable in formulated equation and set the resulting temperature as new value of temperature after the repair, but only if this new temperature is lower than before the repair.

Task A.2

Create class for Thor's hammer called Mjolnir, derived from class Hammer.

Mjolnir will last 4 usages (complete repair of two reactors) after which it will, as the original hammer, also break.

Task A.3

Create class FireExtinguisher for fire extinguisher with which it will be possible to extinguish burning broken reactor.

This class will be a subclass of class AbstractActor and will have instance variable for number of usages, visibility of which should be properly specified, together with respective get method. The class should also have method use() for counting down the remaining amount of usages. When fire extinguisher is used up it should disappear from game scene. Animation representing fire extinguisher should be produced with image extinguisher.png.

To extinguish reactor implement in its class Reactor method extinguishWith() which will require reference to object of type FireExtinguisher as parameter. Fire extinguisher will last one usage with which reactor's temperature will decrease to 4000 degrees and reactor's animation will change to image reactor_extinguished.png. Damage of reactor will remain unchanged after extinguishing.

Additional links