diff --git a/README.md b/README.md index 62fa463c..02bdaec0 100644 --- a/README.md +++ b/README.md @@ -1 +1,27 @@ # kotlin-racingcar-precourse + +## 구현할 기능 목록 +- [x] 자동차 이름 분류 + - [x] (예외) 5자이상인경우 + - [x] (예외) 아무입력도 안했을 경우 + - [x] (예외) 자동차 이름이 중복인 경우 + - [x] 이름 양옆에 공백이 있을 경우 제거 +- [x] 이동할 횟수 + - [x] (예외) 정수가 아닌 경우 + +- [x] 랜덤 이동값 + - [x] 자동차 개수만큼 이동한 횟수 배열 생성 + - [x] 4이상일 경우 이동 + - [x] 실행 결과 출력 + +- [x] 최종 우승자 + - [x] 공동 우승자면 함께 + +- [x] depth 2이하 + +### 테스트 +- [x] 자동차 이름에 아무 입력 안했을 경우 +- [x] 자동차 이름이 중복인 경우 +- [x] 횟수에 문자를 입력하였을 경우 에러 +- [x] 횟수에 소수를 입력하였을 경우 에러 +- [x] 공동 우승일 경우 \ No newline at end of file diff --git a/src/main/kotlin/racingcar/Application.kt b/src/main/kotlin/racingcar/Application.kt index 0d8f3a79..5bfa0f5d 100644 --- a/src/main/kotlin/racingcar/Application.kt +++ b/src/main/kotlin/racingcar/Application.kt @@ -1,5 +1,92 @@ package racingcar +import camp.nextstep.edu.missionutils.Randoms +import camp.nextstep.edu.missionutils.Console +import racingcar.Validation.Validation +import racingcar.View.InputView +import racingcar.View.OutputView + + +fun carsNameTrim(cars : List): List { + return cars.map { it.trim() } +} + +fun isCanGo(): Boolean { + return Randoms.pickNumberInRange(0, 9) >= 4 +} + +fun gameOfOneCar(carsMoving: Array, index: Int) { + if (isCanGo()) { + carsMoving[index] += 1 + } +} + +fun gameOfTurn(cars: List, carsMovingArray: Array, outputView: OutputView) { + for (i in 0 until cars.count()) { + gameOfOneCar(carsMovingArray, i) + outputView.gameResult(cars[i], carsMovingArray[i]) + } + println() +} + +fun game(cars: List, carsMovingArray: Array, outputView: OutputView, count: Int) { + for (i in 0 until count) { + gameOfTurn(cars, carsMovingArray, outputView) + } +} + +fun getWinnerIndex(carsMoving: Array): MutableList { + val winners = mutableListOf() + var maxNumber = 0 + + carsMoving.forEachIndexed { idx, it -> + if (it == maxNumber) { + winners.addLast(idx) + } + if (it > maxNumber) { + maxNumber = it + winners.clear() + winners.addLast(idx) + } + } + return winners +} + +fun inputCars(inputView: InputView, validation: Validation): List { + inputView.inputCars() + val inputCar = Console.readLine() + validation.checkInputCarIsNotEmpty(inputCar) + + var cars: List = inputCar.split(',') + validation.checkCarNameDuplication(cars) + cars = carsNameTrim(cars) + validation.checkCarNameLength(cars) + + return cars +} + +fun inputCount(inputView: InputView, validation: Validation): Int { + inputView.inputCount() + val inputCount = Console.readLine() + validation.checkCountIsNumber(inputCount) + val count = inputCount.toInt() + + return count +} + fun main() { - // TODO: 프로그램 구현 + val outputView = OutputView() + val inputView = InputView() + val validation = Validation() + + val cars = inputCars(inputView, validation) + val count = inputCount(inputView, validation) + + val carsMovingArray = Array(cars.count()) { 0 } + + outputView.outputPrint() + game(cars, carsMovingArray, outputView, count) + + val winners = getWinnerIndex(carsMovingArray).map { cars[it] } + outputView.winnerPrint(winners) } diff --git a/src/main/kotlin/racingcar/Validation/Validation.kt b/src/main/kotlin/racingcar/Validation/Validation.kt new file mode 100644 index 00000000..7abe1b6f --- /dev/null +++ b/src/main/kotlin/racingcar/Validation/Validation.kt @@ -0,0 +1,31 @@ +package racingcar.Validation + +import java.lang.NumberFormatException + +class Validation { + fun checkCarNameLength(cars: List) { + if (!(cars.all { it -> it.count() <= 5 })) { + throw IllegalArgumentException("자동차 이름은 5자 이하만 가능합니다") + } + } + + fun checkInputCarIsNotEmpty(inputCar: String) { + if (inputCar == "") { + throw IllegalArgumentException("자동차 이름을 입력하지 않았습니다") + } + } + + fun checkCarNameDuplication(cars: List) { + if (cars.toSet().size != cars.size) { + throw IllegalArgumentException("자동차 이름이 중복입니다") + } + + } + fun checkCountIsNumber(inputCount: String) { + try { + inputCount.toInt() + } catch (e: NumberFormatException) { + throw IllegalArgumentException("정수만 입력가능합니다") + } + } +} \ 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 00000000..7302d8d7 --- /dev/null +++ b/src/main/kotlin/racingcar/View/InputView.kt @@ -0,0 +1,11 @@ +package racingcar.View + +class InputView { + fun inputCars() { + println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)") + } + + fun inputCount() { + println("시도할 횟수는 몇 회인가요?") + } +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/View/OutputView.kt b/src/main/kotlin/racingcar/View/OutputView.kt new file mode 100644 index 00000000..2e3ab591 --- /dev/null +++ b/src/main/kotlin/racingcar/View/OutputView.kt @@ -0,0 +1,16 @@ +package racingcar.View + +class OutputView { + fun outputPrint() { + println("실행 결과") + } + + fun gameResult(carName: String, movingCount: Int) { + println("$carName : ${"-".repeat(movingCount)}") + } + + fun winnerPrint(winners: List) { + println("최종 우승자 : ${winners.joinToString(", ")}") + + } +} \ No newline at end of file diff --git a/src/test/kotlin/racingcar/ApplicationTest.kt b/src/test/kotlin/racingcar/ApplicationTest.kt index 3c601c8e..77ee95ff 100644 --- a/src/test/kotlin/racingcar/ApplicationTest.kt +++ b/src/test/kotlin/racingcar/ApplicationTest.kt @@ -17,6 +17,13 @@ class ApplicationTest : NsTest() { }, MOVING_FORWARD, STOP ) + assertRandomNumberInRangeTest( + { + run("pobi,woni,jiji", "1") + assertThat(output()).contains("pobi : -", "woni : -", "jiji : ", "최종 우승자 : pobi, woni") + }, + MOVING_FORWARD, MOVING_FORWARD, STOP + ) } @Test @@ -24,6 +31,19 @@ class ApplicationTest : NsTest() { assertSimpleTest { assertThrows { runException("pobi,javaji", "1") } } + assertSimpleTest { + assertThrows { runException("", "1") } + } + assertSimpleTest { + assertThrows { runException("pobi,pobi,woni", "3") } + } + + assertSimpleTest { + assertThrows { runException("pobi,woni", "a") } + } + assertSimpleTest { + assertThrows { runException("pobi,woni", "1.1") } + } } override fun runMain() {