diff --git a/README.md b/README.md index 43803e204..e2bf20e10 100644 --- a/README.md +++ b/README.md @@ -159,3 +159,13 @@ Randoms.pickNumberInRange(0, 9) - **Git의 커밋 단위는 앞 단계에서 `docs/README.md`에 정리한 기능 목록 단위**로 추가한다. - [커밋 메시지 컨벤션](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 가이드를 참고해 커밋 메시지를 작성한다. - 과제 진행 및 제출 방법은 [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서를 참고한다. + +## 기능 목록 + +- Player 도메인 구현하기 v +- 사용자에게 보여주는 기능을 할 printGame 부분 구현하기 v +- 기본적인 게임을 제공할 틀 만들기 v +- 사용자로부터 입력을 받을 수 있는 기능 만들기 v +- 받은 값을 저장할 수 있도록 기능 만들기 v +- 실제 게임을 진행하는 기능 만들기 v +- 게임이 다 끝난 후 출력 만들기 v \ No newline at end of file diff --git a/src/main/kotlin/racingcar/Application.kt b/src/main/kotlin/racingcar/Application.kt index 0d8f3a79d..ff28fe5ec 100644 --- a/src/main/kotlin/racingcar/Application.kt +++ b/src/main/kotlin/racingcar/Application.kt @@ -1,5 +1,10 @@ package racingcar +import racingcar.service.CarPlayGameImpl +import racingcar.service.CarPrintGame + fun main() { - // TODO: 프로그램 구현 + val playGame = CarPlayGameImpl(CarPrintGame()) + + playGame.playGame() } diff --git a/src/main/kotlin/racingcar/domain/Player.kt b/src/main/kotlin/racingcar/domain/Player.kt new file mode 100644 index 000000000..58f35b859 --- /dev/null +++ b/src/main/kotlin/racingcar/domain/Player.kt @@ -0,0 +1,14 @@ +package racingcar.domain + +data class Player( + val name: String, + var winCount: Int = 0 +) { + fun addWinCount() { + winCount++ + } + + companion object { + fun toPlayer(name: String): Player = Player(name, 0) + } +} diff --git a/src/main/kotlin/racingcar/service/CarPlayGameImpl.kt b/src/main/kotlin/racingcar/service/CarPlayGameImpl.kt new file mode 100644 index 000000000..5b8076033 --- /dev/null +++ b/src/main/kotlin/racingcar/service/CarPlayGameImpl.kt @@ -0,0 +1,85 @@ +package racingcar.service + +import camp.nextstep.edu.missionutils.Console +import camp.nextstep.edu.missionutils.Randoms +import racingcar.domain.Player +import kotlin.math.max + +class CarPlayGameImpl( + private val printGame: PrintGame +) : PlayGame { + + private var round: Int = 0 + private var players: List = listOf() + override fun initGame() { + printGame.printInit() + val inputPlayers = Console.readLine() + val names = inputPlayers.split(",") + initPlayers(names) + printGame.tryCount() + round = Console.readLine().toInt() + } + + override fun initPlayers(names: List) { + players = names.map { name -> + validCheck(name) + Player.toPlayer(name) + } + } + + override fun playGame() { + initGame() + + for (loop in 0.. + // 1 : go 0 : stop + if (canIGo()) player.addWinCount() + printGame.printGame(player.name, player.winCount) + } + } + + override fun endGame(winnerCount: Int) { + val winnerList = mutableListOf() + players.forEach { player -> + if (player.winCount == winnerCount) winnerList.add(player.name) + } + + printGame.printWinner(winnerList) + } + + // 5자 이하의 이름인지 확인하는 메서드 + private fun validCheck(name: String) { + require(name.length < 6) { + "이름의 길이는 5자이하 여야 합니다." + } + } + + // 랜덤으로 값을 뽑아 전진이 가능한지 확인하는 메서드 + // 4 이상 부터 전진한다. + private fun canIGo(): Boolean { + return Randoms.pickNumberInRange(0, 9) > RUN_OR_STOP_STANDARD + } + + // 현재 가장 많이 전진한 사람의 count를 가져오는 메서드 + private fun getCurrentWinnerCount(): Int { + var maxGoCount = 0 + + players.forEach { player -> maxGoCount = max(maxGoCount, player.winCount) } + + return maxGoCount + } + + companion object { + const val RUN_OR_STOP_STANDARD = 3 + } +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/service/CarPrintGame.kt b/src/main/kotlin/racingcar/service/CarPrintGame.kt new file mode 100644 index 000000000..8cc64cc5c --- /dev/null +++ b/src/main/kotlin/racingcar/service/CarPrintGame.kt @@ -0,0 +1,29 @@ +package racingcar.service + + +class CarPrintGame : PrintGame { + override fun printInit() { + println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)") + } + + override fun tryCount() { + println("시도할 횟수는 몇 회인가요?") + } + + override fun printGame(playerName: String, goCount: Int) { + print("$playerName : ") + for (loop in 0..) { + print("최종 우승자 : ") + //마지막에서 한명을 제외하고 ", " 형식으로 뽑기위해서 -2를 사용한다 + for (loop in 0..) + + // 게임의 전체 진행을 위한 메서드 + fun playGame() + + // 게임의 각 라운드를 위한 메서드 + fun playRound() + + // 게임 종료시 호출될 메서드 + fun endGame(winnerCount: Int) +} \ No newline at end of file diff --git a/src/main/kotlin/racingcar/service/PrintGame.kt b/src/main/kotlin/racingcar/service/PrintGame.kt new file mode 100644 index 000000000..d0f229608 --- /dev/null +++ b/src/main/kotlin/racingcar/service/PrintGame.kt @@ -0,0 +1,15 @@ +package racingcar.service + +interface PrintGame { + //초기화 시 프린트 하는 메서드 + fun printInit() + + //시도할 횟수에 대한 프린트 하는 메서드 + fun tryCount() + + // 게임 진행시 결과를 프린트 하는 메서드 + fun printGame(playerName: String, goCount: Int) + + // 게임 승리자를 프린트 하는 메서드 + fun printWinner(names: List) +} \ No newline at end of file diff --git a/src/test/kotlin/racingcar/ApplicationTest.kt b/src/test/kotlin/racingcar/ApplicationTest.kt index 2cb36835c..4f68ee16b 100644 --- a/src/test/kotlin/racingcar/ApplicationTest.kt +++ b/src/test/kotlin/racingcar/ApplicationTest.kt @@ -11,11 +11,11 @@ class ApplicationTest : NsTest() { @Test fun `전진 정지`() { assertRandomNumberInRangeTest( - { - run("pobi,woni", "1") - assertThat(output()).contains("pobi : -", "woni : ", "최종 우승자 : pobi") - }, - MOVING_FORWARD, STOP + { + run("pobi,woni", "1") + assertThat(output()).contains("pobi : -", "woni : ", "최종 우승자 : pobi") + }, + MOVING_FORWARD, STOP ) } @@ -26,6 +26,83 @@ class ApplicationTest : NsTest() { } } + @Test + fun `단독 우승`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni", "2") + assertThat(output()).contains("pobi : ", "woni : --", "최종 우승자 : woni") + }, + STOP, MOVING_FORWARD, STOP, MOVING_FORWARD + ) + } + + @Test + fun `혼자 경기한 경우`() { + assertRandomNumberInRangeTest( + { + run("pobi", "2") + assertThat(output()).contains("pobi : ", "최종 우승자 : pobi") + }, + STOP, STOP + ) + } + + @Test + fun `1, 3번째가 우승한 경우`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni,rilla", "3") + assertThat(output()).contains("pobi : --", "woni : ", "rilla : --", "최종 우승자 : pobi, rilla") + }, + MOVING_FORWARD, STOP, MOVING_FORWARD, STOP, STOP, MOVING_FORWARD, MOVING_FORWARD, STOP, STOP + ) + } + + @Test + fun `공동 우승`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni", "1") + assertThat(output()).contains("pobi : -", "woni : -", "최종 우승자 : pobi, woni") + }, + MOVING_FORWARD, MOVING_FORWARD + ) + } + + @Test + fun `모두 전진 실패`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni", "3") + assertThat(output()).contains("pobi : ", "woni : ", "최종 우승자 : pobi, woni") + }, + STOP, STOP, STOP, STOP, STOP, STOP + ) + } + + @Test + fun `모두 전진 성공`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni", "2") + assertThat(output()).contains("pobi : --", "woni : --", "최종 우승자 : pobi, woni") + }, + MOVING_FORWARD, MOVING_FORWARD, MOVING_FORWARD, MOVING_FORWARD + ) + } + + @Test + fun `전진 스탑 스탑 전진`() { + assertRandomNumberInRangeTest( + { + run("pobi,woni", "2") + assertThat(output()).contains("pobi : -", "woni : -", "최종 우승자 : pobi, woni") + }, + MOVING_FORWARD, STOP, STOP, MOVING_FORWARD + ) + } + public override fun runMain() { main() }