Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

코드리뷰를 위한 리팩토링 코드 pr입니다. #237

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0842cb0
DOCS: 리드미 파일 생성 및 추가
park-yina Oct 26, 2023
8cc9995
DOCS: 리드미 파일 생성 및 추가
park-yina Oct 27, 2023
73232c7
Update README.md
park-yina Oct 27, 2023
9573d16
Delete docs/README.md
park-yina Oct 27, 2023
22e91d2
Rename README.md to OLDREADME.md
park-yina Oct 27, 2023
3cc6f34
Create README.md
park-yina Oct 27, 2023
dbe54df
DOCS:Update README.md
park-yina Oct 27, 2023
894cd98
FEAT:이름 입력 받기, 시도 횟수 출력하기
park-yina Oct 27, 2023
73f5309
FEAT:이름 및 게임시도 횟수 입력받기
park-yina Oct 27, 2023
d3b6033
FEAT:이름 및 게임시도 횟수 입력받기
park-yina Oct 27, 2023
97d5f01
FEAT:이름 및 게임시도 횟수 입력받기
park-yina Oct 27, 2023
c92d953
FEAT:이름 및 게임시도 횟수 입력받기
park-yina Oct 27, 2023
50305da
Merge branch 'createBranch' of https://github.com/park-yina/kotlin-ra…
park-yina Oct 27, 2023
1298fb6
FEAT:이름 및 게임시도 횟수 입력받기
park-yina Oct 27, 2023
c0f752e
FEAT:5글자 초과하는 이름 입력시 오류 발생
park-yina Oct 27, 2023
8726635
FEAT:실행결과 멘트 출력
park-yina Oct 28, 2023
bb60d50
FEAT:실행결과 멘트 출력
park-yina Oct 28, 2023
e4f65ed
DOCS:UpdateREADME.md
park-yina Oct 29, 2023
61511bf
DOCS:Update README.md
park-yina Oct 29, 2023
2c68fde
Refactory:Controller클래스 생성 및 기능점검
park-yina Oct 29, 2023
aba6220
Merge branch 'createBranch' of https://github.com/park-yina/kotlin-ra…
park-yina Oct 29, 2023
4eb0c93
Refactory:Controller클래스 생성 및 기능점검
park-yina Oct 29, 2023
938b73e
fix:동점자 모두 출력
park-yina Oct 31, 2023
c47b555
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
c9537be
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
2ca149d
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
c42eed3
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
41e1757
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
36e0f25
예기치 못한 오류 수정하기
park-yina Oct 31, 2023
874a2c0
들여쓰기 및 object명 수정
park-yina Oct 31, 2023
ec9a918
Docs:리드미의 위치 변경 및 내용추가
park-yina Nov 17, 2023
270e589
Docs:기존 리드미 삭제
park-yina Nov 17, 2023
99c3a2b
리팩토링:출력양식 정리
park-yina Nov 17, 2023
6348574
Feat:데이터 누적에 대한 부분 수정
park-yina Nov 20, 2023
191ca95
리팩토링: 자동정렬 및 run함수의 추가
park-yina Nov 21, 2023
26158e5
리팩토링:run 함수 쪼개기
park-yina Nov 21, 2023
1351427
리팩토링:변수명 변경
park-yina Nov 21, 2023
dd7fde7
리팩토링:랜덤의 범위도 상수화
park-yina Nov 21, 2023
8b8158b
리팩토링:자동정렬
park-yina Nov 21, 2023
a871e9d
리팩토링:import GameMessage
park-yina Nov 21, 2023
6e43490
리팩토링:require구문으로 변경
park-yina Nov 21, 2023
48d410a
리팩토링:require구문으로 변경
park-yina Nov 21, 2023
c30d9bd
Update ValidInput.kt
park-yina Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions Docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 필요한 함수 정리

## 1.입력에 대해서
### 1-1 가능한 예외 사항

✔ 이름의 길이가 길 경우->5글자 이상이면 오류 발생시켜야함
<br>
✔ ,를 통한 이름의 구분이 제대로 이루어지지 않을 경우도 존재
### 1-2 자동차의 이름 쪼개기

✔ split를 사용해서 ,를 기준으로 데이터 클래스나 배열에 집어넣기
<br>
[X] 입력시 Scanner과 next를 활용하여 쉼표를 구분자로 나누는 것도 가능. 어떤 것이 더 좋을까
->readline()사용해야함
<br>
요구조건 잘 읽기
<br>

### 1-3 시도 횟수 받기
✔ 시도 횟수의 경우 pickNumber을 사용하여 받아야함

## 2. 계산에 대해서
✔ 아까 입력 받은 시도 횟수를 어떻게 활용할 것인가?
<br>
for문이나 while을 쓰면 depth가 너무 깊어질 수도 있을듯. 게임을 실행하는 함수와 회차까지 실행하는 함수를 꼭 분리해야 요구 조건에 맞출 수 있을 것으로 추정

✔ 점수 계산 전 분리 작업
<br>
이름과 점수를 짝을 지어 진행하여야 한다.
->이러한 기능을 키와 value를 쌍으로 저장하는 map이나 pair을 사용하는 것이 좋을듯
<br>
✔ ','과 "무작위 숫자의 처리"
<br>
✔무작위 숫자의 발생은 PickNumberInRange(시작범위, 끝 범위)로 처리한다
<br>
✔들어온 숫자의 크기가 4이상일 때에만 전진이 가능하다.

## 3. 출력에 대해서
✔ "map의 키 : 맵의 value"의 형태로 실행 결과를 출력하여야한다.
repeat사용하여 특정 횟수만큼 특정 문자열을 출력하기

✔ 최종 우승자가 여러명이면 joinTostring을 사용하여 출력형태 맞추기
# 이번 주차를 진행하며 새로 알게된 함수
## .filter()함수
<br>
말 그대로 filter은 콜렉션에서 어떠한 기준으로 걸러내는 데에 사용할 수 있는 함수
<blockquote>
홀짝 감별 활용:val evenNumbers = numbers.filter { it % 2 == 0 }
<br>
.filterIndexed 활용해서 인덱스와 값을 동시에 활용하는 방법도 있음
</blockquote>

# 1차 피드백 통해서 개선해야 할 사항
## 의미에 맞는 이름
⚫구체성을 띄는 이름 만들기<br>
->이름을 통해서 의미를 드러내기 위해서는 보다 명확하게 다가가야한다.<br>
ex)단순한 이름의 Game보다는 GameConstants와 같은 디테일한 이름을 사용한다<br>
⚫명확한 이름을 만든다<br>
->for문 내에서도 단순한 i보다는 index나 name같은 명확한 변수를 사용한다.<br>
->name을 사용한 부분 역시 실제로는 차의 번째에 초점이 맞추어져 있으니 유의한다.<br>
⚫통일성을 가지게 한다<br>

## 세부적인 예외처리
⚫toInt()사용과 null점검 그리고 잘못된 사항에 대한 예외는 촘촘할수록 좋다.<br>
⚫단순히 5글자가 넘는 이름뿐 아니라 입력의 가능성이 있는 모든 경우에 대한 고민을 해본다.

## 내장함수 찾기
⚫필요 시 forEach나 when 그리고 repeat 등<br>
좋은 가독성과 통일성 등을 위하여 내장함수를 적극 활용한다
File renamed without changes.
Empty file removed docs/README.md
Empty file.
6 changes: 6 additions & 0 deletions src/main/kotlin/errorMessage/InputError.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package errorMessage

enum class InputError(val message: String) {
NOT_DIGIT("[Error]게임 횟수는 1이상의 숫자로만 입력해야합니다."),
OVER_FIVE("[Error]5글자 이상의 이름이 입력되었습니다."),
}
6 changes: 5 additions & 1 deletion src/main/kotlin/racingcar/Application.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package racingcar


fun main() {
// TODO: 프로그램 구현
Racing().run()
}



25 changes: 25 additions & 0 deletions src/main/kotlin/racingcar/InputUser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar

import camp.nextstep.edu.missionutils.Console
import racingcar.InputUser.GameMessage.DEFAULT_INPUT_MENT

class InputUser {
fun printlnDefaultMent() {
println(DEFAULT_INPUT_MENT)
}

fun inputCarName(): List<String> {
val input = Console.readLine()
return input.split(GameMessage.COMMA).map { it.trim() }
}

fun printlnGameCountMent() {
println(GameMessage.GAME_COUNT_MENT)
}

object GameMessage {
const val DEFAULT_INPUT_MENT: String = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"
const val GAME_COUNT_MENT = "시도할 횟수는 몇 회인가요?"
const val COMMA = ","
}
}
101 changes: 101 additions & 0 deletions src/main/kotlin/racingcar/Racing.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package racingcar

import camp.nextstep.edu.missionutils.Randoms
import racingcar.Racing.GameConstants.EXECUTION_RESULT
import racingcar.Racing.GameConstants.FORWARD_STEP
import racingcar.Racing.GameConstants.RANDOM_NUMBER_RANGE_END
import racingcar.Racing.GameConstants.RANDOM_NUMBER_RANGE_START
import racingcar.Racing.GameConstants.RESULT_PLAYER
import racingcar.Racing.GameConstants.WINNERS
import viewModel.ValidInput

class Racing {
val inputUser = InputUser()
fun outputStartMent() {
println(EXECUTION_RESULT)
}

fun generateNumber(carName: List<String>): Map<String, Int> {
val gameInfo = mutableMapOf<String, Int>()
for (name in carName) {
val number =
Randoms.pickNumberInRange(RANDOM_NUMBER_RANGE_START, RANDOM_NUMBER_RANGE_END)
gameInfo[name] = number
}
return gameInfo
}

fun printPerExecutionResult(gameInfo: Map<String, Int>) {
for ((name, number) in gameInfo) {
println("$name : ${GameConstants.BAR.repeat(number)}")
}
println(GameConstants.ENTER)
}

fun calculateScore(gameInfo: Map<String, Int>): List<String> {
for ((name, number) in gameInfo) {
if (number >= FORWARD_STEP) {
WINNERS.add(name)
}
}
return WINNERS
}

private fun findTopScoreList(): String {
val elementCounts = WINNERS.groupingBy { it }.eachCount()
val maxCount = elementCounts.maxByOrNull { it.value }?.value
val topScore = elementCounts.filter { it.value == maxCount }.keys.toList()
return topScore.joinToString(", ")
}

private fun printlnResult() {
println(RESULT_PLAYER + findTopScoreList())
}

fun run() {
inputUser.printlnDefaultMent()
val carNames = getUserInput()
ValidInput().validName(carNames)
val gameCount = getGameCountFromUser()
startGame(carNames, gameCount)

printFinalResult()
}

private fun getUserInput(): List<String> {
val inputUser = InputUser()
return inputUser.inputCarName()
}

private fun getGameCountFromUser(): Int {
val inputUser = InputUser()
inputUser.printlnGameCountMent()
return ValidInput().validInputGameCount()
}

private fun startGame(carNames: List<String>, gameCount: Int) {
outputStartMent()
WINNERS.clear()
repeat(gameCount) {
val gameInfo = generateNumber(carNames)
printPerExecutionResult(gameInfo)
Racing().calculateScore(gameInfo)
}
}

private fun printFinalResult() {
printlnResult()
}

object GameConstants {
const val RANDOM_NUMBER_RANGE_START = 0
const val RANDOM_NUMBER_RANGE_END = 9
const val EXECUTION_RESULT: String = "실행 결과"
const val FORWARD_STEP: Int = 4
const val RESULT_PLAYER: String = "최종 우승자 : "
const val BAR: String = "-"
const val LIMIT_LENGTH: Int = 5
var WINNERS = mutableListOf<String>()
const val ENTER: String = "\n"
}
}
17 changes: 17 additions & 0 deletions src/main/kotlin/viewModel/ValidInput.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package viewModel

import camp.nextstep.edu.missionutils.Console
import errorMessage.InputError.*
import racingcar.Racing.GameConstants

class ValidInput {
fun validInputGameCount(): Int {
val gameCount = Console.readLine()
require(gameCount.toIntOrNull() != null || gameCount.toInt() <= 0) { NOT_DIGIT.message }
return gameCount.toInt()
}

fun validName(carName: List<String>) {
require(!carName.any { it.length > GameConstants.LIMIT_LENGTH }) { OVER_FIVE.message }
}
}
29 changes: 29 additions & 0 deletions src/test/kotlin/racingcar/ApplicationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,35 @@ class ApplicationTest : NsTest() {
assertThrows<IllegalArgumentException> { runException("pobi,javaji", "1") }
}
}
@Test
fun `이름이 한 개만 들어오면`(){
assertRandomNumberInRangeTest({
run("woni","1")
assertThat(output()).contains("최종 우승자 : woni")
},
MOVING_FORWARD
)
}
@Test
fun `우승자 여려명 테스트`() {
assertRandomNumberInRangeTest(
{
run("woni,king", "1")
assertThat(output()).contains("최종 우승자 : woni, king")
},
MOVING_FORWARD
)
}
@Test
fun `누적 확인 테스트`(){
assertRandomNumberInRangeTest({
run("woni,james","3")
assertThat(output()).contains("최종 우승자 : james")
},
2, MOVING_FORWARD, MOVING_FORWARD, MOVING_FORWARD, MOVING_FORWARD, MOVING_FORWARD
)
}


public override fun runMain() {
main()
Expand Down