-
Notifications
You must be signed in to change notification settings - Fork 410
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
3단계 - 자동차 경주 #1179
base: sksskaw
Are you sure you want to change the base?
3단계 - 자동차 경주 #1179
Changes from all commits
d6579d2
0a389cc
65e5cc8
b6a707e
89800ba
1e10266
79dbf57
e526b93
8d7e0d0
cbab930
734d12b
2ea612f
898f250
18b9fa4
32d0518
0d2b28e
4b12b88
4c3d54b
ba2303c
ad20d7f
392ae80
20277d6
8d1a29f
705fe34
6259c0a
0eb9eb2
0022183
fa451f7
78bf4bc
1e7d6b3
d3d4436
628653b
a91b693
fd66916
9450131
a04e357
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package racingCar | ||
|
||
class Car( | ||
private var distance: Int = 0, | ||
private val randomNumber: RandomNumber | ||
) { | ||
val readOnlyDistance: Int | ||
get() { | ||
return distance | ||
} | ||
|
||
companion object { | ||
const val FORWARD_CONDITIONS: Int = 4 | ||
} | ||
|
||
fun move() { | ||
if (checkForwardCondition()) | ||
distance++ | ||
} | ||
|
||
private fun checkForwardCondition(): Boolean { | ||
return randomNumber.getRandomNumber() >= FORWARD_CONDITIONS | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package racingCar | ||
|
||
import java.lang.NumberFormatException | ||
|
||
class InputIO { | ||
fun inputNumber(numberType: InputType): Int { | ||
inputView(numberType) | ||
|
||
return checkNumber(readlnOrNull()) ?: return inputNumber(numberType) | ||
} | ||
|
||
private fun inputView(numberType: InputType) { | ||
println(numberType.message) | ||
} | ||
|
||
fun checkNumber(inputString: String?): Int? { | ||
try { | ||
val value = Integer.parseInt(inputString) | ||
|
||
if (value < 0) { | ||
println("양수만 입력해 주세요") | ||
return null | ||
} | ||
Comment on lines
+17
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4단계 요구사항인 indent 2를 넘어가는 조건을 위배하였습니다. 수정해주세요. |
||
|
||
return value | ||
} catch (e: NumberFormatException) { | ||
println("숫자를 입력해 주세요") | ||
return null | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package racingCar | ||
|
||
enum class InputType(val message: String) { | ||
CAR_COUNT("자동차 대수는 몇 대인가요?"), | ||
GAME_COUNT("시도할 횟수는 몇 회인가요?"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package racingCar | ||
|
||
class RacingField( | ||
private val cars: List<Car>, | ||
private val gameCount: Int | ||
) { | ||
constructor(carCount: Int, gameCount: Int) : this( | ||
List(if (carCount <= 0) 1 else carCount) { Car(randomNumber = RandomNumberGenerator()) }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. carCount가 0보다 작으면 1로 취급해야한다는 요구사항은 없는것으로 알고있습니다. 그리고 if 절을 사용한 뒤에는 중괄호를 반드시 작성해주시기 바랍니다. |
||
if (gameCount <= 0) 1 else gameCount | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이곳도 if 절을 사용한 뒤에는 중괄호를 반드시 작성해주시기 바랍니다. https://kotlinlang.org/docs/coding-conventions.html#control-flow-statements |
||
) | ||
|
||
fun getGameCount(): Int { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제가 읽기전용 프로퍼티를 이용해서 사용자 정의 게터를 이용하여 표현하는것을 적용해 달라고 말씀드렸는데 이 부분을 비롯해 다른 곳들은 누락하신것 같습니다. 전체적으로 코드를 다시한번 살펴 보시면서 리뷰를 반영하실 수 있는 부분을 찾아보시고 적용해주세요. |
||
return gameCount | ||
} | ||
|
||
fun gameStart() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드 이름은 동사가 먼저 오도록 변경해주세요. |
||
moveCars() | ||
} | ||
|
||
private fun moveCars() { | ||
cars.forEach { it.move() } | ||
} | ||
|
||
fun getCarCount(): Int { | ||
return cars.size | ||
} | ||
|
||
fun getCarsDistance(): List<Int> { | ||
return cars.map { it.readOnlyDistance } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package racingCar | ||
|
||
interface RandomNumber { | ||
fun getRandomNumber(): Int | ||
} | ||
|
||
class RandomNumberGenerator : RandomNumber { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
메서드의 이름으로 미루어보아 조금 더 추상적인 이름인 |
||
override fun getRandomNumber(): Int { | ||
return (0..9).random() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package racingCar | ||
|
||
class ResultView { | ||
|
||
companion object { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자바의 static 변수를 맨위에 적는 컨벤션이 있어 헷갈리실수 있을것 같은데 코틀린에서 보통 상수를 표현하기 위해 사용되는 companion object는 클래스의 최하단에 적는 것이 좋습니다. https://kotlinlang.org/docs/coding-conventions.html#class-layout |
||
const val DISPLAY_STRING = "-" | ||
} | ||
|
||
private fun resultMessage() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 함수의 이름은 동사로 시작하도록 표현하는 것이 좋습니다! https://kotlinlang.org/docs/coding-conventions.html#choose-good-names There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리고 지난번 리뷰사항 확인 부탁드립니다. |
||
println("실행 결과") | ||
} | ||
|
||
private fun carsDistanceDisplay(distances: List<Int>) { | ||
distances.forEach { distance -> | ||
println(DISPLAY_STRING.repeat(distance)) | ||
} | ||
} | ||
|
||
fun racingResultDisplay(distances: List<Int>) { | ||
resultMessage() | ||
carsDistanceDisplay(distances) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package racingCar | ||
|
||
fun main() { | ||
val inputIO = InputIO() | ||
val carCount = inputIO.inputNumber(InputType.CAR_COUNT) | ||
val gameCount = inputIO.inputNumber(InputType.GAME_COUNT) | ||
|
||
val racingField = RacingField(carCount, gameCount) | ||
|
||
val resultView = ResultView() | ||
|
||
repeat(gameCount) { | ||
racingField.gameStart() | ||
resultView.racingResultDisplay(racingField.getCarsDistance()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package racingCarTest | ||
|
||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
import racingCar.Car | ||
|
||
class CarMoveTest { | ||
@Test | ||
fun `전진 조건이 맞지 않는 경우`() { | ||
val car = Car(randomNumber = FixedNumberGenerator(3)) | ||
car.move() | ||
assertThat(car.readOnlyDistance).isEqualTo(0) | ||
} | ||
|
||
@Test | ||
fun `전진 조건이 맞는 경우`() { | ||
val car = Car(randomNumber = FixedNumberGenerator(7)) | ||
car.move() | ||
assertThat(car.readOnlyDistance).isEqualTo(1) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package racingCarTest | ||
|
||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
import racingCar.InputIO | ||
|
||
class CheckNumberTest { | ||
@Test | ||
fun `입력값이 음수일 경우 null 을 리턴한다`() { | ||
val inputIO = InputIO() | ||
val negativeValue = inputIO.checkNumber("-1") | ||
assertThat(negativeValue).isNull() | ||
} | ||
|
||
@Test | ||
fun `입력값이 양수일 경우 입력한 값을 Int 로 변환하여 리턴한다`() { | ||
val inputIO = InputIO() | ||
|
||
val positiveValue = inputIO.checkNumber("3") | ||
assertThat(positiveValue).isEqualTo(3) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package racingCarTest | ||
|
||
import racingCar.RandomNumber | ||
|
||
class FixedNumberGenerator( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 |
||
private val fixedNumber: Int | ||
) : RandomNumber { | ||
override fun getRandomNumber(): Int { | ||
return fixedNumber | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package racingCarTest | ||
|
||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
import racingCar.RacingField | ||
|
||
class RacingFieldTest { | ||
@Test | ||
fun `자동차 수 테스트`() { | ||
val racingField = RacingField(3, 0) | ||
assertThat(racingField.getCarCount()).isEqualTo(3) | ||
} | ||
|
||
@Test | ||
fun `자동차 수 음수 테스트`() { | ||
val racingField = RacingField(-3, 0) | ||
assertThat(racingField.getCarCount()).isEqualTo(1) | ||
} | ||
|
||
@Test | ||
fun `경기 실행 수 설정 테스트`() { | ||
val racingField = RacingField(0, 5) | ||
assertThat(racingField.getGameCount()).isEqualTo(5) | ||
} | ||
|
||
@Test | ||
fun `경기 실행 수 음수 테스트`() { | ||
val racingField = RacingField(0, -5) | ||
assertThat(racingField.getGameCount()).isEqualTo(1) | ||
} | ||
|
||
@Test | ||
fun `레이싱 경기 게임 실행 테스트`() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이름이 너무 추상적입니다. 행위에 따른 결과를 나타낼수 있도록 이름을 지어주는 것이 좋습니다. 테스트 이름을 짓는 게 난해하시다면 검색을 해보았을때 도움이 될만한 글들이 많으니 참고해보면 좋을것 같습니다. 예로 what is good name of test code라고 구글에 검색하면 나오는 글입니다. |
||
val carCount = 5 | ||
val gameCount = 100 | ||
val racingField = RacingField(carCount, gameCount) | ||
|
||
repeat(gameCount) { | ||
racingField.gameStart() | ||
assertThat(racingField.getCarsDistance().stream().allMatch { it in 0..gameCount }) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰드렸던대로 읽기전용 프로퍼티를 활용하여 잘 표현해주셨네요 👍
하지만 변수명이 너무 구체적입니다.
readOnly라는 이름이 val가 아닌 var로 고쳤을때는 알맞은 이름이라고 볼 수 없을것 같습니다.
아쉽게도 IDE는 그러한 부분까지 같이 고쳐주지는 않으니까요.
그러한 맥락에서 변수명이 변수의 특정 행위가 가능한지를 나타내는것은 유지보수를 하고 사용하는데 유리한 이름이 아닌것 같아 보입니다.
다른 이름을 고려해주세요.