-
Notifications
You must be signed in to change notification settings - Fork 75
[이호찬] 연료 주입, 블랙잭 (Step 1) #29
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
base: hochan222
Are you sure you want to change the base?
Changes from all commits
194bd15
2132cfe
452e494
af3b6ac
a508794
115b872
afb8d8b
27431e9
bed1c08
33d93c5
7071676
4d48981
49214d3
e5bcbc7
9e5d638
7aab241
6081d09
4f596ac
d557835
5ced626
c2d769b
fdc4a5d
c0f7781
18191da
0501b46
7ad9a5f
4d22b97
94c57b9
3fbb733
ffc7c7f
118309e
0083d3c
00c41a8
f6076e5
226c68d
df2f622
c983e1d
b12d669
b01db13
18abdbf
3521cdf
15f080c
4a3c4db
ea6bcd9
caa3e0e
ed92876
99a0d73
14d58ef
66493b8
f7b945e
0015e65
9c12086
ec1bb3d
093f6a0
efe9782
9dc87ff
a5f917f
c532650
99a30dc
8f38840
3a11286
b4fcda3
9866a48
7647b14
3f16e2f
7293f4e
359e1fa
175b6e0
17fbe9c
ff529d1
f8aa8fb
70929bf
53bccc6
f3bc3af
e8617a6
8165393
5e682f8
2c0ee93
6d6cb04
35ca712
64ce0e8
bb07a41
d93d497
78af8ab
19f4ef3
cd83748
a761d7c
c5a791d
5feebd2
7ad8fe2
4b81f6b
452aa4c
359ff2f
d8f4f20
3e33b79
2c71cbf
d0e97ac
03ea0d5
7908ef9
d7a5c87
37c524e
44216e4
2589dfc
352de29
83bcacb
52fe5e1
0f7ea39
4e5dc51
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 |
|---|---|---|
| @@ -1 +1,149 @@ | ||
| # java-blackjack | ||
| # 연료 주입 | ||
|
|
||
| ## TDD 기능 구현 사항 | ||
|
|
||
| - [x] Sonata | ||
| - [x] `Sonata` String Type 이름을 가져야한다. | ||
| - [x] `10km/리터`의 연비 가져야한다. | ||
| - [x] 거리 | ||
| - [x] 거리를 가져야한다. | ||
| - [x] 거리는 `0` 이상 정수이어야 한다. | ||
| - [x] 주입해야할 연료량을 구할 수 있다. | ||
| - [x] Avante | ||
| - [x] `Avante` String Type 이름을 가져야한다. | ||
| - [x] `15km/리터`의 연비 가져야한다. | ||
| - [x] 거리 가져야한다. | ||
| - [x] 거리는 `0` 이상 정수이어야한다. - | ||
| - [x] 주입해야할 연료량을 구할 수 있다. | ||
| - [x] K5 | ||
| - [x] `K5` String Type 이름을 가져야한다. | ||
| - [x] `13km/리터`의 연비 가져야한다. | ||
| - [x] 거리 가져야한다. | ||
| - [x] 거리는 `0` 이상 정수이어야한다. | ||
| - [x] 주입해야할 연료량을 구할 수 있다. | ||
| - [x] RentCompany | ||
| - [x] `List<Car>`을 가져야한다. | ||
| - [x] `List<Car>`에 대한 getter를 가져야한다. | ||
| - [x] `create()`, 팩토리 메서드를 구현한다. | ||
| - [x] `addCar()`, 차를 추가할 수 있다. | ||
| - [x] `List<Car>`에 Sonata를 추가할 수 있다. | ||
| - [x] `List<Car>`에 Avante를 추가할 수 있다. | ||
| - [x] `List<Car>`에 K5를 추가할 수 있다. | ||
| - [x] `generateReport()`는 전체 결과를 출력한다. | ||
|
|
||
| ## 기능 구현 사항 | ||
|
|
||
| - 보유 차량 | ||
| - Sonata | ||
| - 대수: 2대 | ||
| - 연비: 10km/리터 | ||
| - Avante | ||
| - 대수: 1대 | ||
| - 연비: 15km/리터 | ||
| - K5 | ||
| - 대수: 2대 | ||
| - 연비: 13km/리터 | ||
| - 고객이 인터넷으로부터 예약할 때 여행할 목적지의 대략적인 이동거리를 입력 받을 수 있다. | ||
| - 이동거리를 활용해 차량 별로 필요한 연료를 주입할 수 있다. | ||
| - 차량 별로 주입해야 할 연료량을 확인할 수 있는 보고서를 생성할 수 있다. | ||
|
|
||
| ## 프로그래밍 요구 사항 | ||
|
|
||
| - [x] 상속과 추상 메서드를 활용한다. | ||
| - [x] 위 요구사항을 if/else 절을 쓰지 않고 구현해야 한다. | ||
| - [x] 인터페이스를 적용해 구현한다. | ||
|
|
||
| --- | ||
|
|
||
| # java-blackjack | ||
|
|
||
| ## TDD 기능 구현 사항 | ||
|
|
||
| - [x] User | ||
| - [x] Deck을 가지고 있다. | ||
| - [x] UserName을 가지고 있다. | ||
| - [x] Deck에 카드를 추가할 수 있다. | ||
| - [x] 해당 카드의 점수인 score를 반환할 수 있다. | ||
| - [x] Dealer | ||
| - [x] Deck을 가지고 있다. | ||
| - [x] UserName을 가지고 있다. - name은 `dealer`라는 기본 이름을 가진다. | ||
| - [x] 현재 score가 16이하 인지를 판단하여 반환할 수 있다. | ||
| - [x] 1장의 카드를 추가로 받을 수 있다. | ||
| - [x] Player | ||
| - [x] Deck을 가지고 있다. | ||
| - [x] UserName을 가지고 있다. | ||
| - [x] 현재 score가 21을 넘지 않는지를 판단하여 반환할 수 있다. | ||
| - [x] Deck - 딜러 또는 플레이어가 가진 Card의 집합 | ||
| - [x] List<Card>를 가지고 있다. | ||
| - [x] 현재 List<Card>의 총 score를 계산할 수 있다. | ||
| - [x] Deck의 현재 score가 21을 넘는지에 대한 boolean 계산을 할 수 있다. | ||
| - [x] 현재 가진 Card 중에서 Ace가 있는 경우, 해당 Card에 대한 Score를 1 또는 11로 계산할 수 있다. | ||
| - [x] 21을 초과하지 않으면서, 21에 가깝게 계산할 수 있다. | ||
| - [x] Card - Game에서 사용할 카드의 객체 | ||
| - [x] CardType type을 가지고 있다. (e.g 다이아몬드, 클로버, 스페이드, 하트 ...) | ||
| - [x] CardNumber _String을_ 가지고 있다. (e.g 2, 3, A, K, Q, J ...) | ||
| - [x] 카드 숫자와 카드 타입을 입력할때, 주어진 숫자와 타입으로 카드가 생성된다. | ||
| - [x] CardType - Card의 타입 | ||
| - [x] CardType은 `"다이아몬드", "하트", "클로버", "스페이드"` 이 범위안에 반드시 있어야한다. | ||
| - [x] CardNumber - Card의 숫자 | ||
| - [x] CardNumber는 `"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"` 이 범위안에 반드시 있어야한다. | ||
| - [x] GameCard - 게임에서 사용될 모든 Card의 집합 | ||
| - [x] 모든 Card는 중복이 없어야한다. | ||
| - [x] 총 52 장이 있어야한다. | ||
| - [x] 모든 Card를 셔플할 수 있다. | ||
| - [x] GameUser - BlackJack을 수행하는 User의 집합 | ||
| - [x] List<User>를 가지고 있다. | ||
| - [x] User를 추가할 수 있다. | ||
| - [x] List<User>를 반환할 수 있다. | ||
| - [x] BlackJack - 게임 로직 수행 | ||
| - [x] GameUser를 가지고 있다. | ||
| - [x] GameCard를 가지고 있다. | ||
| - [x] 게임 진행시 최초로 GameCard를 셔플할 수 있다. | ||
| - [x] User별로 초기 카드를 나눠준다. | ||
| - [x] GameCard에서 Card를 두 장 뽑기 | ||
| - [x] User에게 Card 전달하기 | ||
| - [x] Dealer는 총 score가 16이하일 경우, 1장의 카드를 추가로 받는다. | ||
| - [x] User별로 턴을 진행할 수 있게 한다. | ||
| - [x] GameCard에서 Card를 한 장 뽑기 | ||
| - [x] User에게 Card 전달하기 | ||
| - [x] Player는 총 score가 21이하일 경우, 1장의 카드를 추가로 받을 수 있다. | ||
| - [x] UserStats - User별 승/패에 대한 정보 | ||
| - [x] GameUser를 인자로 받아 User별, 승/패 정보를 계산한다. | ||
| - [x] User별 Deck의 score를 출력하기 위한 String을 반환할 수 있다. convertTotalScore() | ||
| - [x] User별 최종 승/패를 출력하기 위한 String을 반환할 수 있다. convertTotalResult() | ||
| - [x] User별 Deck의 score가 21을 초과할 경우, 승/패를 계산할 수 있다. | ||
| - [x] Dealer의 score가 21을 초과할 경우, Player가 승리한다. | ||
| - [x] Dealer의 score가 21을 초과하지 않고, Player의 score가 21을 초과하는 경우, Dealer가 승리한다. | ||
| - [x] Game - 전체적인 게임을 진행할 Controller | ||
| - [x] 이름의 배열을 BlackJack에 전달한다. | ||
| - [x] 싱글턴 패턴 적용 | ||
| - [x] UserName - 게임 참여자의 이름 | ||
| - [x] InputView | ||
| - [x] 게임에 참여할 이름을 입력받는다. | ||
| - [x] OutputView | ||
|
|
||
| ## 최초 PR 마감 기한 | ||
|
|
||
| 2월 17일 목요일까지 | ||
|
|
||
| ### test | ||
|
|
||
| ```bash | ||
| ./gradlew clean check | ||
| ``` | ||
|
|
||
| ### git pull pair | ||
|
|
||
| ```bash | ||
| git pull pair step1 | ||
| ``` | ||
|
|
||
| ### git multiple author | ||
|
|
||
| ```bash | ||
| git commit -m "commit message | ||
|
|
||
|
|
||
| Co-authored-by: hochan222 <hochan049@gmail.com> | ||
| Co-authored-by: chanuuuuu <dn0208@gmail.com> | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package blackJack; | ||
|
|
||
| import blackJack.controller.Game; | ||
|
|
||
| public class Application { | ||
|
|
||
| public static void main(String[] args) { | ||
| Game game = Game.getInstance(); | ||
| game.run(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package blackJack.controller; | ||
|
|
||
| import blackJack.domain.BlackJack; | ||
| import blackJack.domain.UserStats; | ||
| import blackJack.util.Util; | ||
| import blackJack.view.InputView; | ||
| import blackJack.view.OutputView; | ||
| import java.util.List; | ||
|
|
||
| public class Game { | ||
|
|
||
| private static Game game = null; | ||
| private final BlackJack blackJack; | ||
|
|
||
| private Game(List<String> playerNames) { | ||
| blackJack = BlackJack.from(playerNames); | ||
| } | ||
|
|
||
| public static Game getInstance() { | ||
| if (game == null) { | ||
| game = new Game(getPlayerName()); | ||
| } | ||
| return game; | ||
| } | ||
|
|
||
|
Comment on lines
+19
to
+25
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. 싱글톤 패턴을 사용하신 이유가 있을까요? |
||
| public void run() { | ||
| init(); | ||
| goPhase(); | ||
| summarize(); | ||
| } | ||
|
|
||
| private void init() { | ||
| blackJack.initCardDraw(); | ||
| OutputView.printInitCardDrawFormat(blackJack.getGameUser().convertPlayersName()); | ||
| OutputView.printUserStatus(blackJack.getGameUser()); | ||
| } | ||
|
Comment on lines
+32
to
+36
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 void goPhase() { | ||
| blackJack.playerPhase(); | ||
| blackJack.dealerPhase(); | ||
| } | ||
|
|
||
| private void summarize() { | ||
| UserStats userStats = UserStats.of(blackJack.getGameUser()); | ||
| OutputView.printTotalScore(userStats.convertTotalScore()); | ||
| OutputView.printTotalResult(userStats.convertTotalResult()); | ||
| } | ||
|
Comment on lines
+43
to
+47
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 static List<String> getPlayerName() { | ||
| OutputView.printRequestPlayerNames(); | ||
| return Util.stringToStringList(InputView.readPlayerName()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| package blackJack.domain; | ||
|
|
||
| import blackJack.view.InputView; | ||
| import blackJack.view.OutputView; | ||
| import java.util.List; | ||
|
|
||
| public class BlackJack { | ||
|
|
||
| private static final int INITIAL_DRAW_CARD_COUNT = 2; | ||
|
|
||
| private final GameUser gameUser; | ||
| private final GameCard gameCard; | ||
|
|
||
| private BlackJack(List<String> userNames) { | ||
| this.gameUser = GameUser.from(userNames); | ||
| this.gameCard = GameCard.create(); | ||
| cardShuffle(); | ||
| } | ||
|
|
||
| public static BlackJack from(List<String> userNames) { | ||
| return new BlackJack(userNames); | ||
| } | ||
|
|
||
| public GameUser getGameUser() { | ||
| return gameUser; | ||
| } | ||
|
|
||
| public List<Player> getPlayers() { | ||
| return gameUser.getPlayers(); | ||
| } | ||
|
|
||
| public List<Card> getGameCard() { | ||
| return gameCard.getGameCard(); | ||
| } | ||
|
|
||
| private void cardShuffle() { | ||
| gameCard.shuffle(); | ||
| } | ||
|
Comment on lines
+36
to
+38
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. 랜덤적인 요소가 있는 메서드를 어떻게 테스트를 진행해 볼 수 있을까요? |
||
|
|
||
| public void initCardDraw() { | ||
| initDealerDraw(); | ||
| initPlayerDraw(); | ||
| } | ||
|
|
||
| private void initDealerDraw() { | ||
| gameUser.getDealer().appendToDeck(gameCard.drawCard(INITIAL_DRAW_CARD_COUNT)); | ||
| } | ||
|
|
||
| private void initPlayerDraw() { | ||
| gameUser.getPlayers() | ||
| .forEach(player -> player.appendToDeck(gameCard.drawCard(INITIAL_DRAW_CARD_COUNT))); | ||
| } | ||
|
Comment on lines
+40
to
+52
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. 해당 메서드들의 테스트 코드를 작성해 보는 것이 어떨가요? |
||
|
|
||
| public void dealerPhase() { | ||
| if (gameUser.getDealer().isCardDraw()) { | ||
| gameUser.getDealer().additionalCardDraw(gameCard.drawCard()); | ||
| OutputView.printDealerAdditionalCardDraw(); | ||
| } | ||
| } | ||
|
Comment on lines
+54
to
+59
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. 도메인 로직에 화면이 있으면 테스트하기가 어려워요 |
||
|
|
||
| public void playerPhase() { | ||
| for (Player player : gameUser.getPlayers()) { | ||
| useTurn(player); | ||
| } | ||
| } | ||
|
|
||
| private void useTurn(Player player) { | ||
| while (player.isCardDraw()) { | ||
| OutputView.printRequestAdditionalCardDrawFormat(player); | ||
| if (InputView.readYN()) { | ||
| player.appendToDeck(gameCard.drawCard()); | ||
| OutputView.printPlayerStatus(player); | ||
| continue; | ||
| } | ||
| OutputView.printPlayerStatus(player); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+67
to
+79
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. indent 를 줄여 보아요 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package blackJack.domain; | ||
|
|
||
| import static blackJack.domain.CardNumber.ACE_INDEX; | ||
| import static blackJack.domain.CardNumber.CARD_NUMBER_LIST; | ||
|
|
||
| public class Card { | ||
|
|
||
| private static final String JQK_REGEX = "[JQK]"; | ||
| private static final int JQK_SCORE = 10; | ||
| private static final int ACE_SCORE = 1; | ||
|
|
||
| private final CardType cardType; | ||
| private final CardNumber cardNumber; | ||
|
|
||
| private Card(String cardType, String cardNumber) { | ||
| this.cardType = CardType.from(cardType); | ||
| this.cardNumber = CardNumber.from(cardNumber); | ||
| } | ||
|
|
||
| public static Card of(String cardType, String cardNumber) { | ||
| return new Card(cardType, cardNumber); | ||
| } | ||
|
|
||
| public String getCardType() { | ||
| return cardType.getType(); | ||
| } | ||
|
|
||
| public String getCardNumber() { | ||
| return cardNumber.getNumber(); | ||
| } | ||
|
|
||
| public int calculateCardScore() { | ||
| String number = cardNumber.getNumber(); | ||
|
|
||
| if (number.matches(JQK_REGEX)) { | ||
| return JQK_SCORE; | ||
| } | ||
| if (number.equals(CARD_NUMBER_LIST.get(ACE_INDEX))) { | ||
| return ACE_SCORE; | ||
| } | ||
|
|
||
| return Integer.parseInt(number); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package blackJack.domain; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class CardNumber { | ||
|
|
||
| public static final int ACE_INDEX = 0; | ||
|
|
||
| public static final List<String> CARD_NUMBER_LIST = Arrays.asList("A", "2", "3", "4", "5", "6", | ||
| "7", "8", "9", "10", "J", "Q", "K"); | ||
|
|
||
| private final String cardNumber; | ||
|
|
||
| private CardNumber(String cardNumber) { | ||
| this.cardNumber = cardNumber; | ||
|
|
||
| validateCardNumberRange(); | ||
|
Comment on lines
+16
to
+18
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. 유효성 검사를 먼저 진행하는 것이 어떨까요? |
||
| } | ||
|
|
||
| public static CardNumber from(String cardNumber) { | ||
| return new CardNumber(cardNumber); | ||
| } | ||
|
|
||
| public String getNumber() { | ||
| return cardNumber; | ||
| } | ||
|
|
||
| private void validateCardNumberRange() { | ||
| if (!CARD_NUMBER_LIST.contains(cardNumber)) { | ||
| throw new RuntimeException("[ERROR] CardNumber 범위인 String을 입력해주세요."); | ||
| } | ||
| } | ||
| } | ||
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.
테스트 코드가 필요해 보여요~