🗒 Задача¶
В компьютерной игре танк может подбирать разные виды патронов. Патроны различаются силой удара. Синие – 5 единиц, зеленые – 10, красные – 20.
– создай enum класс для патронов и класс танка. У танка должны быть методы вооружения новым типом патронов и выстрела. При выстреле в консоль должен выводиться нанесенный урон;
– создай экземпляр танка и “произведи” несколько выстрелов разными патронами;
– экземпляр танка при создании ничем не заряжен;
– в решении должен использоваться enum.
❌ Ошибки¶
-
не делают нулябельным поле с вооружением в классе танка
-
используют оператор !! вместо .? (если инициализировать изначально амуницию null)
✏️ Комментарии¶
Предлагаю перенести поле с зарядом в основной конструктор, чтобы была опция создания с каким-либо снарядом. Так код будет более гибким.
При создании экземпляра танка поле со снарядами должно быть пустым, то есть лучше сделать его `null`
Не рекомендуется использовать оператор "это не null" - лучше поменять на оператор безопасного вызова. Иначе, если переменная weapon будет null, приложение упадет с ошибкой.
Возможно возникает вопрос почему переменная требует проверки на null, ведь строкой выше эта проверка производится. Из-за того, что weapon мутабельна, предполагается, что между выполнением 29 и 30 строки есть вероятность, что переменная изменится на null. Это называется **[race condition](https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%B3%D0%BE%D0%BD%D0%BA%D0%B8)**. В этом состоянии есть неопределенность. Поэтому лучшие варианты обезопасить вызов будет или let, или safety call оператор.
🧾 Решение¶
enum class AmmoType(val damage: Int) {
BLUE(5),
GREEN(10),
RED(20)
}
class Tank(private var ammo: AmmoType? = null) {
fun arm(ammoType: AmmoType) {
ammo = ammoType
println("Танк вооружен патронами типа ${ammoType.name} с уроном ${ammoType.damage}")
}
fun shoot() {
if (ammo != null) {
println("Танк выстрелил, нанеся урон ${ammo!!.damage}")
} else {
println("Танк не заряжен")
}
}
}
fun main() {
val tank = Tank()
tank.shoot(
tank.arm(AmmoType.BLUE)
tank.shoot()
tank.arm(AmmoType.GREEN)
tank.shoot()
tank.arm(AmmoType.RED)
tank.shoot()