6. 📚 Home Task
The home task should be done using TypeScript.
info
The starter code for the home task is located in docs/3-building-blocks-of-oop-part-2/hometask folder
Check the UML representation of a set of classes that represent the inventory and various types of items.
The classes and methods in italics are abstract. The concrete child classes must implement all methods from the abstract parent classes. Item
, Consumable
, and Weapon
are the abstract classes.
The line from Item
to Comparable
indicates that Item
must implement the Comparable
interface. Similarly, the ItemWeightComparator
class must implement the ItemComparator
interface, which extends the Comparator
interface. ItemWeightComparator
compares items based on their weight.
Specific Steps​
The Item
class is the common ancestor to the various types of items that can exist in this fantasy game.
All instances of
Item
are given a unique number id. These are to be assigned by theItem
constructor. The first instance of an item is assigned an id of 0 (zero); the next is assigned 1, etc. Note that you have available a class variable that will help with the implementation of the constructor (and there is a staticreset()
method).compareTo(other: Item)
: TheItem
class implements theComparable
interface. This requires adding thecompareTo(other: Item)
method to the class. ThecompareTo(other: Item)
method takes in another instance ofItem
and compares it to the current instance. If the current instance's value field is greater than other's value field then the method should return a positive integer (convention is 1). If the current instance's value field is less than other's value field then the method should return a negative integer (convention is -1). If both items are equal, then compare the name field of the items lexicographically (meaning, compare each character in the strings based on its value, ignoring case. i.e.A == a
), returning the appropriate value.Item.toString()
: for anItem
with the name of "ring", a value of 3000, and a weight of 0.013, the method must return a string in the following format (excluding the quotes):"ring − Value: 3000, Weight: 0.01"
The ItemWeightComparator
class implements the ItemComparator
interface, meaning instances of it can be passed to methods requiring a comparator for objects of type Item
.
- The
compare(first: Item, second: Item)
method ofItemWeightComparator
should function similarly to thecompareTo(other: Item)
method of theItem
class, but for the weight field of theItems
. If the weights are equal, this method should call thecompareTo(other: Item)
method of the firstItem
and return the resulting value.
The Weapon
class is an abstract implementation of Item
and describes items that can deal damage and break from use. All instances of Weapon
have a base damage value baseDamage
and a modifier to that value damageModifier
. The sum of these two values determines the effective damage that this Weapon
can do on a single use. In addition, Weapons
have a base durability value baseDurability
, and a modifier to that value durabilityModifier
. The sum of these two values determines the effective durability of the Weapon
. When this sum reaches zero or less, the effective durability is zero and the Weapon
is considered to be broken and cannot be used.
You need to implement the next methods:
Weapon.getDamage()
: Returns the effectiveWeapon
damage.Weapon.getDurability()
: Returns the effective durability of the Weapon.Weapon.toString()
: for aWeapon
with the name of "hammer", a value of 300, a weight of 2.032, abaseDamage
value of 30.4219, adamageModifier
of 0.05, abaseDurability
of 0.7893, and adurabilityModifier
of 0.05, the method returns a string in the following format:"hammer − Value: 300, Weight: 2.03, Damage: 30.47, Durability: 83.93%"
Weapon.use()
: This method returns a string describing what happens when aWeapon
is used. For aWeapon
with the name of "hammer", and an effective damage of 30.4725, the method should return the following:"You use the hammer, dealing 30.47 points of damage."
"Using" a
Weapon
lowers (subtracts) its effective durability byWeapon.MODIFIER_CHANGE_RATE
. If the effective durability of theWeapon
hits or drops below 0, theWeapon
will "break". If theWeapon
"breaks", the method should output the previous string, but additionally with a newline character and the additional text "The hammer breaks.":"You use the hammer, dealing 34.05 points of damage. The hammer breaks."
For a
Weapon
with the name of "hammer", if it is "broken" (The effective durability is 0 or less), calling itsuse()
method returns the following:"You can't use the hammer, it is broken."
In this case, there is no change to durabilityModifier
.
The Sword
class is a concrete implementation of Weapon
that you must provide.
- All instances of the
Sword
class have the name "sword". Sword.polish()
: This method increases the instance's damageModifier by addingWeapon.MODIFIER_CHANGE_RATE
each timepolish()
is called, up to 25% of thebaseDamage
value. If the base damage of a sword were to be 100, then the maximum that the effective damage could be increased to would be 125.
The Bow
class is a concrete implementation of Weapon
that you must provide.
- All instances of the
Bow
class have the name "bow". Bow.polish()
: This method increases the instance'sdurabilityModifier
by addingWeapon.MODIFIER_CHANGE_RATE
. Any changes are capped such that effective durability is no larger than one (1).
The Inventory
class is a container for items in this fantasy game. You need to add the following methods:
Inventory.sort()
: This sorts the items in theInventory
instance based on their value.Inventory.sort(comparator: ItemComparator)
: This sorts the items in theInventory
instance based on their weight.Inventory.toString()
: returns string representation of the item list (.join(', ')
).
The Consumable
class describes those items that can be eaten by the player. Consumables
can be marked as consumed, and can be spoiled. These properties are stored in the instance variables consumed and spoiled, respectively. A newly-created Consumable
object should have its consumed field set to false.
Consumable.use()
: If aConsumable
is not spoiled and is not consumed, calling this simply returns the value from a call toConsumable.eat()
. For aConsumable
with the name of "bread" that has already been consumed, this method returns the following:"There is nothing left of the bread to consume."
Assuming for this Consumable
named "bread" that the value returned by a call to its eat()
method is the following:
"You eat the bread."
If this "bread" were to be spoiled, the method returns this string, appended with a newline and the text "You feel sick.":
"You eat the bread.
You feel sick."
Specific instructions​
- Start from creating
Item
,Consumable
, andInventory
classes. - Create the
Sword
,Bow
andItemWeightComparator
classes
Implementation details​
- both int/float types in the UML diagram represents "number" type in Typescript;
Item
class:numberOfItems
is static getter property which returnscounter
(keep it outside class declaration and increment every time class constructor is executed)reset()
method should assign 0 to thecounter
compareTo(other: Item)
- see description above
Consumable
class:- consumed is
false
when create new instance
- consumed is
Inventory
class:items
-Item[]
sort()
method is polymorphic and has 2 declarations:sort()
andsort(comparator: ItemComparator)
Weapon
class:- don't forget to use
super
inconstructor
(note that parent classes can require extra fields, such asname
)
- don't forget to use
Pizza
class:- example of
eat()
method:
- example of
Evaluation criteria​
- Only some classes were implemented.
- Some classes were not implemented.
- Some required methods are missing.
- All tasks are implemented to a full extend.