Skip to content

[1단계 - 블랙잭 게임 실행] 조조(조은별) 미션 제출합니다.#658

Merged
choijy1705 merged 77 commits intowoowacourse:eun-byeolfrom
eun-byeol:step1
Mar 14, 2024
Merged

[1단계 - 블랙잭 게임 실행] 조조(조은별) 미션 제출합니다.#658
choijy1705 merged 77 commits intowoowacourse:eun-byeolfrom
eun-byeol:step1

Conversation

@eun-byeol
Copy link
Copy Markdown

영이, 안녕하세요! 조조입니다🐥
중간부터 페어의 건강상 문제로 부득이하게 혼자 진행하게 되었습니다.
저는 24시 언제든 slack으로 응답이 가능합니다. 반대로, 영이의 시간규칙(?)을 알려주시면 좋을 것 같아요!(ex. 몇 시 이후에는 dm 자제 등)

🥔 본인의 상황(feat. TMI)

독창적이고 신박한(?) 코드 보다는, 누구나 예측가능한 코드를 짜는 것을 목표하고 있습니다.
그러나, 스스로 판단 기준이 명확하지 않다 보니 코드를 짤 때 여러 의문점들이 생겼었습니다.
정답을 요구하는 것은 아니지만, 현직에 계신 영이의 견해 또한 들어보고 싶습니다.

대학을 졸업하고 취준생의 신분에서 우테코에 들어왔습니다.
수료 후 취업을 희망하다 보니, 현직에 계신 분들의 이야기를 많이 듣고 싶습니다.

🤔 코드를 작성할 때 신경 쓴 점

1. 쉬운 테스트를 위한 인터페이스 사용 자제

저는 테스트를 쉽게 작성할 수 있어야 한다는 기준을 지향합니다.
특히 랜덤 테스트를 할 때, 인터페이스를 재정의하여 테스트 코드를 작성하는 방식이 오히려 테스트를 어렵게 하는 것 같습니다.

따라서, 랜덤으로 카드를 뽑는 로직(CardDispenser)과 연관이 있는 도메인을 어떻게 쉽게 테스트 할 수 있을까?하는 고민에 대해,
외부에서 카드를 생성하고 인자로 받아 처리하는 방식을 선택했습니다.

BlackjackGame 클래스의 메서드 인자를 통해 Cards를 받고 있습니다.

public void distributeCardsForSetting(Cards cards) {...}
public Player hitForPlayer(Player player, Card card) {...}
public boolean hitForDealer(Card card) {...}

2. 불변 객체 만들기

자동차 미션 때와 유사하게, 딜러와 플레이어의 카드는 계속 변합니다.
불변 객체를 만들기 위해, 카드가 늘어날 때마다 새로운 객체를 생성해서 반환했습니다.

public Dealer addCard(Card card) {
    Cards addedCards = cards.add(card);
    return new Dealer(addedCards);
}

public Dealer addCards(List<Card> cardsElement) {
    Cards addedCards = cards.addAll(cardsElement);
    return new Dealer(addedCards);
}

3. 카드 합 계산 로직 단순화

특히 카드 합을 계산하는 로직이 까다로웠습니다.
ACE가 2개의 값을 가질 수 있다보니 Enum 클래스에서 처리하는 것에 한계를 느껴, 다음과 같이 단순화했습니다.

1. default 값으로, ACE1의 값을 갖는다.
Hit 질문 여부를 판단하기 위해, ACE의 최소 조건으로 카드 합을 계산했습니다.

2. 승패를 낼 때, ACE11값을 고려하여 최적화 한다.
GameScore 클래스에서 1번에서 계산된 값에서 +10을 하면서 21에 가까운 값을 찾도록 했습니다.

💭 질문

1. 모든 원시 값과 문자열을 포장한다 어디까지 지켜야 할까?

요구사항에 명시된 조건입니다.
여기서 의미하는 원시 값은 어느 범위까지 해당 되는 지에 대해 고민이 있었습니다.
Collection으로 선언된 변수를 비롯하여 모든 원시값을 감싸다 보면, 불필요한 getter 과정이 반복되고 코드가 복잡해지는 문제가 있었습니다.

아래 코드처럼, 파라미터 변수도 포장 대상이 되는지 궁금합니다.

    public Cards addAll(List<Card> cardsElement) {
        List<Card> addedCards = new ArrayList<>(elements);
        addedCards.addAll(cardsElement);
        return new Cards(addedCards);
    }

2. 재입력 로직을 View로 이동, View가 Model을 알고 있는 것이 괜찮을까?

MVC에서 View가 Model을 알고 있는 것이 가능하다고 공부했지만,
View에서 객체를 생성할 만큼 알아도 괜찮을까? 하는 의문이 있었습니다.
이에 대한 의견 궁금합니다🤔

플레이어를 입력 받는 InputView 클래스입니다.

    public static Players preparePlayers() {
        return retryOnException(() -> {
            List<String> playerNames = askPlayerNames();
            return Players.from(playerNames);
        });
    }

eun-byeol and others added 30 commits March 5, 2024 14:51
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: eun-byeol <joeunbyeol98@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
Co-authored-by: lilychoibb <choiyoonseo02@gmail.com>
- 이름의 마지막 글자가 모음이면 '는' 붙여 이름 출력
- 모음 이외의 문자는 '은' 붙여 이름 출력
- 기존 players = players.hit(player, card) 로직에서 player.hitCard(card)으로 수정
- BlackjackGame players 멤버의 final 키워드 추가
- Player hand 멤버의 final 키워드 삭제
- Dealer hand 멤버 final 키워드 삭제
DealerResult 정적 팩토리 메서드 추가
GameResult, DealerResult 패키지 이동
- Players 이름 중복 검사 로직 수정
- Player equals, hashCode 메서드 삭제
- Dealer name 정적 필드 추가
- RandomCard.pickCards 반환 타입 수정
- assertAll 테스트 라이브러리 추가
- ParameterizedTest 추가
- 테스트 이름 수정
@eun-byeol
Copy link
Copy Markdown
Author

eun-byeol commented Mar 12, 2024

영이, 안녕하세요!
리팩터링에 대한 고민이 깊어져 요청이 다소 늦어지게 되었습니다.🥲
특히 객체의 역할을 분리하는 것에 많이 시간을 썼던 것 같습니다. 아직 부족한 점이 많은 설계이지만, 문제점을 짚어주시면 빠르게 수정해보겠습니다!
네이밍을 비롯해서 구현을 자주 바꾸다보니, 커밋 단위가 깔끔하지 못한 점 양해 부탁드립니다..!

⭐️ 리팩터링 시 신경 쓴 점

1. 네이밍

조금 혼란을 주는 일반적이지 않은 경우 피드백에 대해 고민을 많이 했습니다.
Contoller 메서드를 비롯하여, 전체적인 클래스와 메서드 이름을 수정했습니다.

클래스 명 수정 사항은 다음과 같습니다.

  • Cards -> Hand : 여러장의 카드를 지칭
  • CardDispenser -> RandomCard : 한 장의 카드 혹은 여러 장의 카드를 뽑아주는 Util
  • GameScore -> ParticipantScore : 참가자(딜러, 플레이어)의 최종 점수를 저장

2. 클래스의 역할 분리

로직의 수행을 어떤 도메인에서 처리하는게 좋을지 피드백에 대한 답변입니다.
기존, 게임의 승무패 결과를 내고 딜러의 결과를 통계 처리를 모두 수행했던 GameResult에 대한 책임이 모호하다고 생각했습니다.
따라서, DealerResult와 PlayersResult 클래스를 추가하여 역할을 분리했습니다.

  • GameResult의 역할 : 딜러와 플레이어의 각 점수를 계산하여 저장하는 역할
  • DealerResult의 역할 : 딜러의 승무패 통계 결과를 내고 저장하는 역할
  • PlayersResult의 역할 : 모든 플레이어의 승무패 결과를 내고 저장하는 역할

3. OutView 비즈니스 로직 제거

view에서 비즈니스 로직 제거 피드백에 대한 답변입니다.
getter 메서드 이외 비즈니스 로직을 수행했던 코드를 전반적으로 수정했습니다.

💭 추가 질문 목록

Copy link
Copy Markdown

@choijy1705 choijy1705 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 조조!
최초의 카드를 생성하는 과정이 쉽게 이해가 잘안가는것 같아요
피드백 참고해서 카드 묶음(deck)을 만들고 이를 게임중에 관리하는 방법에 대해 고민해보면 좋을것 같습니다!

Comment thread src/main/java/view/InputView.java Outdated
Comment on lines +26 to +31
public static Players preparePlayers() {
return retryOnException(() -> {
List<String> playerNames = askPlayerNames();
return Players.from(playerNames);
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재입력로직은 domain 에서는 있으면 안될것 같네요! 도메인에는 관련된 비즈니스로직만 있어야 할것 같아요
이상적인것은 inputView에서 받는것이 가장 좋을것 같네요!

return new BlackjackGame(dealer, players);
}

private void setting(BlackjackGame blackjackGame) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init은 초기화라는 사전에 등재된 단어라서
축약이 아니지 않을까요?

Comment thread src/main/java/model/player/Players.java Outdated
private static final String INVALID_PLAYER_NAMES_UNIQUE = "플레이어 이름은 중복될 수 없습니다.";
private static final int CARDS_PER_PLAYER = 2;

private final List<Player> group;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스명과 필드명이 같은걸 지양해야 한다에 가독성 좋은 어색하게 group으로 바꾼게 아닐까요??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

players로 다시 수정했습니다!

Comment on lines +26 to +27
hitToPlayers(blackjackGame);
hitToDealer(blackjackGame);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hitToPlayers(blackjackGame);
hitToDealer(blackjackGame);
blackjackGame.hitToPlayers();
blackjackGame.hitToDealer();

이런 느낌으로 가야하지 않을까요? game을 파라미터로 받는 어색한 구조인것 같아요
hitToPlayers()라는 명칭도 조금 어색하네요
blackjackGame.play()라는 메서드안에서 이 로직들을 수행해보면 어떨까요?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 game클래스에서 진행할법한 로직들이 controller에서 수행하고 있는 느낌이네요
현재 구조에서 game의 메서드들은 로직은 따로없고 player, delaer에거 호출을 전파하는 역할만 하고 있는것 같습니다

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전반적으로 컨트롤러에 있던 로직을 blackjackGame으로 옮겼습니다!
단, hitToPlayers() 로직은 hit 여부 응답을 받는 InputView 로직이 포함되어있어, 컨트롤러에 남겨두었습니다.

Comment on lines +38 to +43
private void initGame(BlackjackGame blackjackGame) {
int cardCount = blackjackGame.determineInitCardCount();
List<Card> cards = RandomCard.pickCards(cardCount);
blackjackGame.initHand(cards);
OutputView.printInitHand(blackjackGame);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

얘도 blackJackGame 안에서 초기화하는게 안어색하지 않을까요?

import java.util.List;
import java.util.stream.Stream;

public class RandomCard {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 클래스의 로직이 쉽게 이해가 안가는데
설명해줄 수 있나요??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 로직을 완전히 수정하여 제로에서 재설계했습니다. 이에 대한 내용은 아래에 정리해두었습니다.

Comment on lines +39 to +41
int cardCount = blackjackGame.determineInitCardCount();
List<Card> cards = RandomCard.pickCards(cardCount);
blackjackGame.initHand(cards);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 이해가 안가는 로직인것 같아요ㅠ
어떤 상황일까요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최초 카드를 배분하는 로직에 대한 내용입니다. 해당 로직을 전부 BlackjackGame 클래스로 이동시켰습니다!

Comment on lines +23 to +30
public int determineInitCardCount() {
return (players.count() + DEALER_COUNT) * INITIAL_CARD_COUNT;
}

public void initHand(List<Card> cards) {
dealer.hitCards(cards.subList(0, INITIAL_CARD_COUNT));
players.hitCards(cards.subList(INITIAL_CARD_COUNT, cards.size()));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분들도 설명이 필요한 로직같아요 ㅠ

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlackjackGame 관련 로직을 전면 수정했습니다. 아래 메시지에 답변 정리해두었습니다.😊

Comment thread src/main/java/model/player/Player.java Outdated
import model.card.Card;
import model.card.Hand;

public class Player {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dealer와 player는 인터페이스를 정의해서 관리해보는 건 어떨까요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

결론적으로, 상속과 인터페이스를 모두 사용했습니다.

인터페이스를 사용한 이유

  • 블랙잭 게임에서 요구되는 행동을 인터페이스로 관리할 수 있습니다. 참가자들은 이 인터페이스를 extends하기만 하면 됩니다.
  • 다른 액션이 추가되는 경우 다중 상속을 통해 쉽게 확장시킬 수 있습니다.

상속을 사용한 이유

  • Player와 Dealer의 중복 코드를 줄이기 위함입니다.
  • Participant 추상 클래스를 생성하고, 인터페이스(HitAction)를 구현하고 있습니다.
public abstract class Participant implements HitAction {

import java.util.Map;
import java.util.stream.IntStream;

public class CardDispenser {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카드 묶음(Deck)을 만드는 로직이 변경해주신 부분도 쉽게 이해하기 어려운것 같습니다

  1. 모양과 번호에 따라 다른 카드를 어떻게 초기화하여 52장(?)을 만들지
  2. 해당 카드에서 순서대로 카드를 뽑는다고 했을때 어떤 자료구조를 사용하면 좋을지
  3. 만들어진 카드 묶음(Deck)을 어느 객체에서 관리하면 좋을지

변경해주신 randomCard부분도 너무 복잡한것 같습니다 😭
제로에서 다시한번 설계해보면 어떨까요??

- 컨트롤러 비즈니스 로직 BlackjackGame으로 이동
- BlackjackGame에서 CardShuffler, Dealer 인스턴스 변수로 갖도록 수정
- 랜덤 라이브러리 변경으로 인하여 ApplicationTest 삭제
- blackjackgame 패키지 -> game로 이름 수정
- dealer, player 패키지 -> participant 패키지로 이동
Player, Dealer가 HitAction 인터페이스를 구현하도록 수정
- ParticipantScore -> CardsScore 클래스로 대체
- 딜러의 승무패 판단 로직 수정
- Participant 추상 클래스 생성
- Participant에서 HitAction 인터페이스를 구현하도록 수정
@eun-byeol
Copy link
Copy Markdown
Author

eun-byeol commented Mar 14, 2024

안녕하세요 영이! 조조입니다😃
리팩터링의 방향성을 제시해주셔서 감사합니다! 피드백 주신 내용에 대해 고민 해보고 수정해보았습니다.
아직 부족한 부분이 많겠지만 가감없이 말씀해주시면 많은 도움이 될 것 같습니다.

🤔 리팩토링 시 신경 쓴 점

1. 랜덤 카드 로직 단순화

피드백 주신 카드 묶음(Deck)을 만드는 로직 , RandomCard 로직에 대한 답변입니다.

가정 : 랜덤 카드 묶음은 유한하다.

블랙잭 게임 시작 시에, 다음 로직이 수행됩니다.

  1. BlackjackGame - 게임에서 사용 할 Deck의 개수를 정합니다.(현재는 4개를 사용하는 것으로 구현했습니다.)
  2. CardShuffler - N개의 Deck을 생성하고 랜덤으로 섞습니다.
  3. CardShuffler - 랜덤으로 섞인 카드 중 1장의 카드를 뽑아줍니다.(Queue 자료구조 사용)

2. 컨트롤러에 혼재된 BlackjackGame 역할 분리

game클래스에서 진행할법한 로직들이 controller에서 수행 피드백에 대한 답변입니다.

주요 변경사항입니다.

  1. BlackjackGame 인스턴스 변수로 CardShuffler, Dealer를 갖도록 수정

    • BlackjackGame 외부에 있던 랜덤 카드 로직을 내부에서 처리하도록 수정했습니다.
    • BlackjackGame이 CardShuffler와 Dealer를 외부에서 아는 것이 오히려 어색하고, 로직을 복잡하게 만든다고 생각했습니다.
  2. BlackjackGame의 역할 수정

    • dealInitialCards : 플레이어와 딜러에게 초기 카드를 배분하는 메서드입니다.
    • dealCard : 플레이어가 Hit 시에, 카드를 1장 배분하는 메서드입니다.
    • dealerHitTurn : 딜러가 Hit이 가능하다면, 카드를 1장 배분하는 메서드입니다.
    • finish : GameResult를 반환하여 게임을 종료하는 메서드입니다.

3. Player와 Dealer의 중복 코드 제거

상속을 통해 구현했습니다.
Participant 추상 클래스를 만들고, 중복 코드를 정의했습니다.
Player와 Dealer가 Participant를 상속하고 있습니다.

또한, dealer와 player는 인터페이스를 정의해서 관리해보는 건 어떨까요? 피드백에 대해
HitAction 인터페이스를 정의하고 Participant에서 구현하고 있습니다.

public abstract class Participant implements HitAction {

Copy link
Copy Markdown

@choijy1705 choijy1705 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조조 피드백 잘 반영해주셨습니다!👍
추가 피드백 있는데
2단계 진행하면서 반영해주시면 좋을것 같습니다!

Comment on lines +15 to +20
public static HitChoice findHitChoice(String choice) {
return Arrays.stream(values())
.filter(hitChoice -> hitChoice.displayName.equals(choice))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("y 혹은 n 중 하나를 입력해 주세요."));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes or no 인데
if 문으로 분기하는게 더 간결하고 가독성 좋지 않을까요?


private static final int HIT_CONDITION = 22;

private final String name;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dealer 에게도 이름을 부여하면 participant에서 관리할 수 있지 않을까요?
딜러에게 이름이 부여된다면 player이름이 딜러 혹은 dealer라면 게임이 굉장히 혼란스러울것 같은데 막는게 좋지 않을까요??
image
지금은 이런식의 게임이 가능하네요!!

Comment on lines +26 to +42
private static void validate(List<String> playerNames) {
validateEmpty(playerNames);
validatePlayerNamesUnique(playerNames);
}

private static void validateEmpty(List<String> playerNames) {
if (playerNames.isEmpty()) {
throw new IllegalArgumentException("플레이어 수는 1명 이상이어야 합니다.");
}
}

private static void validatePlayerNamesUnique(List<String> playerNames) {
Set<String> uniqueNames = new HashSet<>(playerNames);
if (uniqueNames.size() < playerNames.size()) {
throw new IllegalArgumentException("플레이어 이름은 중복될 수 없습니다.");
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate 메서드안에서 모든 검증을 처리하도록 하나로 합치면 어떨까요?
검증이 하나둘 추가되면 메서드도 늘어나고 클래스가 커져서 복잡해질것 같아요

import java.util.List;
import java.util.stream.Stream;

public class Deque {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 클래스의 존재 이유를 잘 모르겠습니다!
CardShuffler에서 초기화시에 initCards 로직을 수행하면 안되는건가요?

그리고 자료구조를 Class명으로 가지는것도 어색하네요😭

import java.util.NoSuchElementException;
import java.util.Queue;

public class CardShuffler {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CardShuffler라는 네이밍이 매번 카드를 뽑을때마다 카드를 섞을것 같은 느낌을 주는데
CardDeck과 같은 네이밍이 어떤가요?

Comment on lines +35 to +38
while (dequeCount > 0) {
cards.addAll(new Deque().getCards());
dequeCount--;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for문 처리가 좋지 않을까요?
while은 무한루프의 가능성이 있기 때문에 정말 어쩔 수 없는 경우 아니면 사용하지 않는것이 좋은것 같아요

Comment on lines +35 to +36
IntStream.range(0, players.count())
.forEach(order -> dealCardsToPlayer(players, order));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

players.deal(cardShuffler)
같은 형태로 처리하는게 자연스럽지 않을까 싶습니다 ㅎㅎ

Comment on lines +30 to +31
IntStream.range(0, INITIAL_CARD_COUNT)
.forEach(count -> dealer.hitCard(cardShuffler.drawCard()));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IntStream은 요즘 트렌드인가 봅니다...?
for문이 더 가독성 좋지 않나요?

this.results = Collections.unmodifiableMap(results);
}

public static PlayerResults from(GameResult gameResult) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GameResult안에서 getPlayerResults 하면 Map<String, ResultStatus> 가 반한되도록 하면 좀 더 심플해지지 않을까요?
map을 포장하면 결과를 내는 과정이 많이 복잡해진것 같아요
DealerResult도 마찬가지입니다!

@choijy1705 choijy1705 merged commit 3888869 into woowacourse:eun-byeol Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants