-
Notifications
You must be signed in to change notification settings - Fork 120
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
[부나] 2단계 자동차 경주 제출합니다. #64
Changes from 98 commits
4d15ac7
2fb4547
d85e64e
69fe601
ca51779
37462f6
8808d37
1d86cdd
e1f5fc1
118d2cb
b826b0e
972d412
7b51f8c
b16841c
e724948
1381ae5
d88ea80
7e42178
0edf628
1ca0cda
4d5d28b
89bfc95
fe11d89
5d67e4e
3571323
39f2cdd
3e46229
c34e4cc
890bef6
8945701
3aa878a
74f7af6
3ab052f
ce2e1bb
efd5d0c
9282f50
35dff55
e45ab6b
4f9ba23
07dcf8e
983fd98
e735d17
8a24159
d9c1cde
3250ce8
c41adbe
aaca844
385e9b7
7012826
810050b
0924fe7
1f76b4e
3783a31
f3d42d2
a2441a2
3966720
f1d7a52
5a27b6d
cbed4f1
919ba1c
7e22dea
322b011
b96c5d1
3cd5d3b
b354f94
1b9aae3
a2a3628
c1bbd0c
0e2a0d6
330601f
910225c
70e8c98
5f2d1f7
feb31e3
2a702a1
9298caf
16de727
6320815
14595f1
249b12d
9656256
ee98952
4cf09d2
ba98fd4
a614450
255a8bf
228132e
4b82d73
782af39
6360209
9c847c0
8046843
a39cc01
3a09e61
78fe97b
24e8396
b2919dd
dc441fa
8268211
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,7 @@ | ||
package racingcar.dto.car | ||
|
||
import racingcar.model.car.CarName | ||
|
||
class CarDto(_carName: String, val position: Int = 0) { | ||
val carName: CarName = CarName(_carName.trim()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package racingcar.dto.car | ||
|
||
class CarsDto(_cars: List<CarDto>) : List<CarDto> by _cars |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package racingcar.dto.car | ||
|
||
import racingcar.model.car.Car | ||
|
||
class WinnersDto(winners: List<Car>) : List<Car> by winners |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package racingcar.dto.round | ||
|
||
class RoundDto(val count: Int) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.model.car.move.step.MoveStep | ||
|
||
class Car(name: String, private var _position: Int = 0) { | ||
val carName: CarName = CarName(name) | ||
val position: Int get() = _position | ||
|
||
fun move(moveStep: MoveStep) { | ||
_position += moveStep.move() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package racingcar.model.car | ||
|
||
class CarName(private var _value: String) { | ||
val value: String get() = _value.trim() | ||
|
||
init { | ||
require(value.length in MIN_CAR_NAME_LENGTH..MAX_CAR_NAME_LENGTH) { | ||
CAR_NAME_LENGTH_OVER_BOUNDARY_ERROR_MESSAGE | ||
} | ||
} | ||
|
||
companion object { | ||
private const val MIN_CAR_NAME_LENGTH = 1 | ||
private const val MAX_CAR_NAME_LENGTH = 5 | ||
|
||
private const val CAR_NAME_LENGTH_OVER_BOUNDARY_ERROR_MESSAGE = | ||
"자동차 이름 길이의 범위는 $MIN_CAR_NAME_LENGTH 이상 $MAX_CAR_NAME_LENGTH 이하입니다." | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.model.car.move.condition.CarMoveCondition | ||
import racingcar.model.car.move.step.OneStep | ||
import racingcar.model.car.move.step.ZeroStep | ||
|
||
class Cars(_cars: List<Car>) : List<Car> by _cars { | ||
init { | ||
validateExistDuplicatedCarName() | ||
} | ||
|
||
private fun validateExistDuplicatedCarName() { | ||
val nonDuplicatedCarsForName = this.distinctBy { it.carName.value } | ||
|
||
require(this.size == nonDuplicatedCarsForName.size) { | ||
DUPLICATED_CAR_NAME_ERROR_MESSAGE | ||
} | ||
} | ||
|
||
fun moveAll(carMoveCondition: CarMoveCondition): Cars = this.onEach { car -> | ||
if (isSatisfyCondition(carMoveCondition)) { | ||
car.move(OneStep) | ||
} else { | ||
car.move(ZeroStep) | ||
} | ||
} | ||
|
||
private fun isSatisfyCondition(carMoveCondition: CarMoveCondition) = | ||
carMoveCondition() >= MOVE_CONDITION | ||
|
||
fun getWinners(): Winners { | ||
val winnerStandard = this.maxBy { it.position } | ||
return Winners(this.filter { it.position == winnerStandard.position }) | ||
} | ||
|
||
companion object { | ||
private const val DUPLICATED_CAR_NAME_ERROR_MESSAGE = | ||
"중복된 자동차 이름이 존재합니다." | ||
private const val MOVE_CONDITION = 4 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.dto.car.WinnersDto | ||
|
||
class Winners(winners: List<Car>) : List<Car> by winners { | ||
fun toDto(): WinnersDto = WinnersDto(this) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package racingcar.model.car.move.condition | ||
|
||
interface CarMoveCondition { | ||
operator fun invoke(): Int | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package racingcar.model.car.move.condition | ||
|
||
class CarRandomMoveCondition : CarMoveCondition { | ||
override operator fun invoke(): Int = | ||
(START_RANDOM_MOVEMENT_PROBABILITY..END_RANDOM_MOVEMENT_PROBABILITY).random() | ||
|
||
class FakeForSuccess : CarMoveCondition { | ||
override operator fun invoke(): Int = SUCCESS_NUMBER | ||
} | ||
|
||
class FakeForFailed : CarMoveCondition { | ||
override operator fun invoke(): Int = FAIL_NUMBER | ||
} | ||
|
||
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. Fake객체는 실제 코드에서는 사용되지않는코드입니다, 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. Fake 관련 클래스를 어디에 구현해야 하는지 고민이었는데 답을 얻은 것 같습니다! |
||
companion object { | ||
private const val START_RANDOM_MOVEMENT_PROBABILITY = 0 | ||
private const val END_RANDOM_MOVEMENT_PROBABILITY = 9 | ||
|
||
private const val FAIL_NUMBER = 0 | ||
private const val SUCCESS_NUMBER = 9 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar.model.car.move.step | ||
|
||
sealed class MoveStep { | ||
abstract fun move(): Int | ||
} | ||
|
||
object ZeroStep : MoveStep() { | ||
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. sealed 클래스 👍 |
||
private const val ZERO_STEP = 0 | ||
|
||
override fun move(): Int = ZERO_STEP | ||
} | ||
|
||
object OneStep : MoveStep() { | ||
private const val ONE_STEP = 1 | ||
|
||
override fun move(): Int = ONE_STEP | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package racingcar.model | ||
package racingcar.model.round | ||
|
||
class Round(val count: Int) { | ||
init { | ||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,27 @@ | ||
package racingcar.service | ||
|
||
import racingcar.model.Car | ||
import racingcar.repository.CarRepository | ||
import racingcar.repository.Repository | ||
import racingcar.dto.car.CarsDto | ||
import racingcar.dto.car.WinnersDto | ||
import racingcar.dto.round.RoundDto | ||
import racingcar.model.car.move.condition.CarMoveCondition | ||
import racingcar.model.car.move.condition.CarRandomMoveCondition | ||
import racingcar.utils.mapper.toDto | ||
import racingcar.utils.mapper.toModel | ||
|
||
class RacingService( | ||
private val carRepository: Repository<Car> = CarRepository() | ||
_cars: CarsDto, | ||
private val carMoveCondition: CarMoveCondition = CarRandomMoveCondition() | ||
) { | ||
fun getAll(): List<Car> = carRepository.selectAll() | ||
private val cars = _cars.toModel() | ||
|
||
fun insertCars(cars: List<Car>) { | ||
cars.forEach { insertCar(it) } | ||
fun runAllRounds(round: RoundDto, doEachRoundResult: (CarsDto) -> Unit) { | ||
repeat(round.toModel().count) { | ||
doEachRoundResult(moveCars()) | ||
} | ||
} | ||
|
||
private fun insertCar(car: Car) = carRepository.insert(car) | ||
private fun moveCars(): CarsDto = | ||
cars.moveAll(carMoveCondition).toDto() | ||
|
||
fun createCars(names: List<String>): List<Car> = | ||
names.map { Car(it) } | ||
|
||
fun moveRandomly(car: Car) { | ||
car.move(getRandomProbability()) | ||
} | ||
|
||
private fun getRandomProbability(): Int = | ||
(START_RANDOM_MOVEMENT_PROBABILITY..END_RANDOM_MOVEMENT_PROBABILITY).random() | ||
|
||
fun getWinners(): List<Car> { | ||
val cars = getAll() | ||
val winnerStandard = cars.maxBy { it.position } | ||
return cars.filter { it.position == winnerStandard.position } | ||
} | ||
|
||
companion object { | ||
private const val START_RANDOM_MOVEMENT_PROBABILITY = 1 | ||
private const val END_RANDOM_MOVEMENT_PROBABILITY = 10 | ||
} | ||
fun getWinners(): WinnersDto = cars.getWinners().toDto() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
package racingcar.utils | ||
|
||
fun List<String>.removeBlank() = map { it.trim() } | ||
fun List<String>.removeBlank(): List<String> = | ||
this.map { it.trim() } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.car.CarDto | ||
import racingcar.model.car.Car | ||
|
||
fun CarDto.toModel(): Car = Car(carName.value, position) | ||
|
||
fun Car.toDto(): CarDto = CarDto(carName.value, position) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.car.CarsDto | ||
import racingcar.model.car.Cars | ||
|
||
fun CarsDto.toModel(): Cars = Cars(this.map { it.toModel() }) | ||
|
||
fun Cars.toDto(): CarsDto = CarsDto( | ||
this.map { car -> car.toDto() } | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.round.RoundDto | ||
import racingcar.model.round.Round | ||
|
||
fun RoundDto.toModel(): Round = Round(count) |
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.
추가적인 내용이니 참고만해주셔도 좋습니다! (다음 미션들의 내용이니 참고만해주세요!)
_position이라는 가변 상태 변수의 존재는 Car의 상태를 관리해주어야하게 만듭니다!
객체의 불변성을 유지하여 불변객체로 관리해 보아도 좋을거 같아요!