import java.io.File
interface NextRepetitionsRepository {
fun read(): Repetitions?
fun write(repetitions: Repetitions)
}
class FileNextRepetitionsRepository: NextRepetitionsRepository {
private val store = File("next_repetitions.txt")
override fun read(): Repetitions? {
if (!store.exists()) return null
val content = store.readLines()
val firstRound = content.getOrNull(0)?.toIntOrNull()
?: return null
val secondRound = content.getOrNull(1)?.toIntOrNull()
?: return null
return Repetitions(
firstRound = firstRound,
secondRound = secondRound,
)
}
override fun write(repetitions: Repetitions) {
if (!store.exists()) store.createNewFile()
store.writeText("${repetitions.firstRound}\n"+
"${repetitions.secondRound}")
}
}
data class Repetitions(val firstRound: Int, val secondRound: Int)
class WorkoutManager {
fun nextRepetitions(
firstRoundDone: Int,
secondRoundDone: Int,
thirdRoundDone: Int,
repetitions: Repetitions,
): Repetitions = when {
firstRoundDone < repetitions.firstRound -> {
// Could not do enough push-ups in the first round
repetitions.copy(
firstRound = repetitions.firstRound - 1,
secondRound = repetitions.secondRound - 1
)
}
secondRoundDone < repetitions.secondRound -> {
// Could not do enough push-ups in the second round
repetitions.copy(
secondRound = repetitions.secondRound - 1
)
}
thirdRoundDone > repetitions.firstRound -> {
// The third round is above the first round,
// so we increase the repetitions for both rounds
repetitions.copy(
firstRound = repetitions.firstRound + 1,
secondRound = repetitions.secondRound + 1,
)
}
thirdRoundDone > repetitions.secondRound -> {
// The third round is below the first round,
// but above the second round, so we increase
// the repetitions for the second round
repetitions.copy(
secondRound = repetitions.secondRound + 1,
)
}
else -> repetitions
}
}
class WorkoutInteractor(
val manager: WorkoutManager,
val nextRepetitionsRepository: NextRepetitionsRepository
) {
fun start() {
println("Hello, I am your push-ups workout assistant!")
val repetitions = nextRepetitionsRepository.read()
?: Repetitions(5, 5)
println("Now do ${repetitions.firstRound} push-ups")
val firstRoundDone = getValidIntInput(
"How many push-ups did you do?"
)
println("Now rest for 1 minute")
Thread.sleep(1000 * 60)
println("Now do ${repetitions.secondRound} push-ups")
val secondRoundDone = getValidIntInput(
"How many push-ups did you do?"
)
println("Now rest for 1 minute")
Thread.sleep(1000 * 60)
println("Now do as many push-ups as you can!")
val thirdRoundDone = getValidIntInput(
"How many push-ups did you do?"
)
val next = manager.nextRepetitions(
firstRoundDone = firstRoundDone,
secondRoundDone = secondRoundDone,
thirdRoundDone = thirdRoundDone,
repetitions = repetitions,
)
nextRepetitionsRepository.write(next)
println("Your next repetitions will be: "+
"${next.firstRound} and ${next.secondRound}")
}
private fun getValidIntInput(prompt: String): Int {
while (true) {
println(prompt)
val input = readlnOrNull()?.toIntOrNull()
if (input != null && input >= 0) {
return input
}
println("Please enter a valid number.")
}
}
}
fun main() {
val interactor = WorkoutInteractor(
manager = WorkoutManager(),
nextRepetitionsRepository =
FileNextRepetitionsRepository(),
)
interactor.start()
}