KTB-05 Разработать меню тренажера¶
📝 Описание¶
Создание консольного меню тренажёра
В соответствии с техническим заданием, на 1 этапе разработки необходимо реализовать консольный тренажёр. Это предполагает вывод информации в консоль и считывание ввода пользователя.
Для упрощения навигации рекомендуется отображать пронумерованное меню и запрашивать у пользователя ввод номера пункта меню. Аналогичный метод будет использоваться при реализации функционала изучения слов с вариантами ответов.
Начать следует с разработки основного меню приложения.
Требования к меню
При запуске приложения должно отображаться меню следующего вида:
Реализация логики меню
Необходимо создать базовую структуру приложения с использованием бесконечного цикла, который будет ожидать ввод пользователя. В начале каждой итерации цикла необходимо будет обрабатывать ввод пользователя и в зависимости от него выводить новые сообщения в консоль или останавливать цикл (выходить из программы).
🗒 Задание¶
- Создать консольное меню тренажёра внутри бесконечного цикла с использованием
while(true). - На каждой итерации цикла:
- Выводить в консоль меню с пунктами 1, 2 и 0.
- Считывать ввод пользователя.
- Обрабатывать ввод с помощью конструкции
when, выполняя соответствующие действия:- При вводе "1": выводить сообщение о выборе пункта "Учить слова".
- При вводе "2": выводить сообщение о выборе пункта "Статистика".
- При вводе "0": прерывать цикл и останавливать программу.
- При вводе любого другого значения: выводить предупреждение с сообщением "Введите число 1, 2 или 0".
- Создать метод
loadDictionary()и вынести в него логику создания словаря. Метод должен возвращать список объектов классаWord. - Создать переменную
dictionaryв начале методаmain()и проинициализировать ее значением, которое будет возвращатьloadDictionary().
❌ Ошибки¶
✏️ Комментарии¶
Лучше сначала зачистить файл при помощи `writeText("")`, а потом добавлять слова по одному через `appendText()`.
Лучше не накапливать строку в памяти, как у тебя, а делать `appendText` в файл, предварительно его очистив.
extension’ы¶
Лучше не перебарщивать с extension-функциями. Для файла не применимо "сохранение словаря", это "засоряет" скоуп файла.
В целом проще перезаписывать файл целиком, это не сильно дороже по ресурсам. Можешь попробовать `RandomAccessFile`, если хочешь перезаписывать определенные строки.
Переписывать файл — это норма. Но если формировать строку заранее, она может стать слишком большой и вызвать ошибку `OutOfMemory`.
Ввод варианта ответа можно сделать с использованием `readln().toIntOrNull()`, а затем обрабатывать через `when`.
Файл по сути последовательность 1 и 0 записанных на накопитель. При этом если ты хочешь вставить что-то посередине файла, все что идет после нужно сдвигать. То есть, ты можешь идти по файлу до переноса строки и искать нужную, но проще перезаписывать файл целиком, к тому же по ресурсам это не сильно дороже.
Если же хочешь искать определенную строку – можешь попробовать [RandomAccessFile](https://devcolibri.com/%D1%83%D1%80%D0%BE%D0%BA-4-randomaccessfile-%D0%B8-%D0%B5%D0%B3%D0%BE-%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8/)
⌨️ Решение¶
val dictionary = loadDictionary()
while (true) {
println(
"""
Меню:
1 – Учить слова
2 – Статистика
0 – Выход
""".trimIndent()
)
val input = readln()
when (input) {
"1" -> {
println("Учить слова")
}
"2" -> {
println("Статистика")
}
"0" -> {
return
}
}
}
private fun loadDictionary(): List<Word> {
val dictionary = mutableListOf<Word>()
val wordsFile = File("words.txt")
for (string in wordsFile.readLines()) {
val split = string.split("|")
val word = Word(
original = split[0],
translate = split[1],
correctAnswersCount = split[2].toIntOrNull() ?: 0
)
dictionary.add(word)
}
return dictionary
}