diff --git a/src/main/kotlin/racingcar/Racing.kt b/src/main/kotlin/racingcar/Racing.kt new file mode 100644 index 0000000000..3ad3db1299 --- /dev/null +++ b/src/main/kotlin/racingcar/Racing.kt @@ -0,0 +1,37 @@ +package racingcar + +import racingcar.car.Runnable +import racingcar.view.InputView +import racingcar.view.ResultView + +class Racing(private val racingCarFactory: () -> T) { + fun race() { + val carCount = InputView.getCarCount() + val racingCount = InputView.getRacingCount() + + doRacing(carCount, racingCount) + } + + fun doRacing(carCount: Int, racingCount: Int) { + val racingCars = getRacingCars(carCount) + val doRacingEachRound = racingEachRound(racingCount) + + doRacingEachRound(racingCars, 0) + } + + private fun getRacingCars(carCount: Int): List { + return Array(carCount) {it + 1}.map { racingCarFactory() } + } + + private fun racingEachRound(totalRound: Int): (List, Int) -> Unit { + return { cars, round -> + if (round == totalRound) { + // over the recursion + } else { + val nextCars = cars.map { it.run() } + ResultView.printPositions(nextCars.map { it.position }) + racingEachRound(totalRound)(nextCars, round + 1) + } + } + } +} diff --git a/src/main/kotlin/racingcar/car/RacingCar.kt b/src/main/kotlin/racingcar/car/RacingCar.kt new file mode 100644 index 0000000000..9f107c14fd --- /dev/null +++ b/src/main/kotlin/racingcar/car/RacingCar.kt @@ -0,0 +1,18 @@ +package racingcar.car + +import racingcar.utils.RandomGenerator + +class RacingCar(override val position: Int = 0) : Runnable { + companion object { + private const val RANDOM_THRESHOLD = 10 + } + + override fun run(): RacingCar { + return RacingCar(move()) + } + + override fun getDistance(): Int { + val randomNumber = RandomGenerator.getRandomIntNumber(RANDOM_THRESHOLD) + return if (randomNumber >= 4) 1 else 0 + } +} diff --git a/src/main/kotlin/racingcar/car/Runnable.kt b/src/main/kotlin/racingcar/car/Runnable.kt new file mode 100644 index 0000000000..814ebf209b --- /dev/null +++ b/src/main/kotlin/racingcar/car/Runnable.kt @@ -0,0 +1,13 @@ +package racingcar.car + +interface Runnable { + val position: Int + + fun run(): Runnable + + fun move(): Int { + return position + getDistance() + } + + fun getDistance(): Int +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/utils/RandomGenerator.kt b/src/main/kotlin/racingcar/utils/RandomGenerator.kt new file mode 100644 index 0000000000..19d4271469 --- /dev/null +++ b/src/main/kotlin/racingcar/utils/RandomGenerator.kt @@ -0,0 +1,9 @@ +package racingcar.utils + +import java.util.* + +object RandomGenerator { + fun getRandomIntNumber(threshold: Int): Int { + return Random().nextInt(threshold) + } +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/view/InputView.kt b/src/main/kotlin/racingcar/view/InputView.kt new file mode 100644 index 0000000000..ebb780ea60 --- /dev/null +++ b/src/main/kotlin/racingcar/view/InputView.kt @@ -0,0 +1,13 @@ +package racingcar.view + +object InputView { + fun getCarCount(): Int { + println("자동차 대수는 몇 대 인가요?") + return readln().toInt() + } + + fun getRacingCount(): Int { + println("경주 횟수는 몇 대 인가요?") + return readln().toInt() + } +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/view/ResultView.kt b/src/main/kotlin/racingcar/view/ResultView.kt new file mode 100644 index 0000000000..eb966ed4f7 --- /dev/null +++ b/src/main/kotlin/racingcar/view/ResultView.kt @@ -0,0 +1,15 @@ +package racingcar.view + +object ResultView { + fun printResult() { + println("주행 결과") + } + + fun printPosition(position: Int) { + println("-".repeat(position)) + } + fun printPositions(positions: List) { + positions.forEach { printPosition(it) } + println() + } +} \ No newline at end of file diff --git a/src/test/kotlin/calculator/operator/SimpleFourBasicOperationTest.kt b/src/test/kotlin/calculator/operator/SimpleFourBasicOperationTest.kt index 00cb29d0a6..abe6bea98c 100644 --- a/src/test/kotlin/calculator/operator/SimpleFourBasicOperationTest.kt +++ b/src/test/kotlin/calculator/operator/SimpleFourBasicOperationTest.kt @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test internal class SimpleFourBasicOperationTest { private val operation = SimpleFourBasicOperation + @Test fun addTest() { assertThat(operation.add(3.0, 4.0)).isEqualTo(7.0) diff --git a/src/test/kotlin/racingcar/RacingTest.kt b/src/test/kotlin/racingcar/RacingTest.kt new file mode 100644 index 0000000000..5ccfeb308d --- /dev/null +++ b/src/test/kotlin/racingcar/RacingTest.kt @@ -0,0 +1,12 @@ +package racingcar + +import io.kotest.core.spec.style.FunSpec +import racingcar.car.RacingCar + +class RacingTest: FunSpec({ + // SystemOutExtension을 사용하여 콘솔 출력을 캡처 + context("racing 통합 테스트") { + val racing = Racing { RacingCar() } + racing.doRacing(3, 5) + } +}) \ No newline at end of file diff --git a/src/test/kotlin/racingcar/car/CarTest.kt b/src/test/kotlin/racingcar/car/CarTest.kt new file mode 100644 index 0000000000..74a113b9d5 --- /dev/null +++ b/src/test/kotlin/racingcar/car/CarTest.kt @@ -0,0 +1,17 @@ +package racingcar.car + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldBeIn +import io.kotest.matchers.shouldBe + +class CarTest: FunSpec({ + context("자동차의 초기 위치는 0이다.") { + val car = RacingCar() + car.position shouldBe 0 + } + + context("한번 움직인 자동차의 위치는 0 아니면 1이어야 한다.") { + val car = RacingCar().run() + car.position shouldBeIn listOf(0, 1) + } +}) \ No newline at end of file diff --git a/src/test/kotlin/racingcar/utils/RandomGeneratorTest.kt b/src/test/kotlin/racingcar/utils/RandomGeneratorTest.kt new file mode 100644 index 0000000000..fd0723b19b --- /dev/null +++ b/src/test/kotlin/racingcar/utils/RandomGeneratorTest.kt @@ -0,0 +1,12 @@ +package racingcar.utils + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldBeIn + +class RandomGeneratorTest : FunSpec({ + context("랜덤 값은 0이상, 지정한 값 이하여야 한다.") { + val threshold = 10 + val randomIntNumbers = RandomGenerator.getRandomIntNumber(threshold) + randomIntNumbers shouldBeIn (0..threshold).toList().toTypedArray() + } +})