Перейти к содержанию

🗒 Задача

В компьютерной игре танк может подбирать разные виды патронов. Патроны различаются силой удара. Синие – 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()