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

레디 step1 미션 제출 #6

Open
wants to merge 103 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
e504ca0
docs: 기능 요구 사항 작성
reddevilmidzy Mar 5, 2024
3ed10c0
test: 카드 합 구하기
JINU-CHANG Mar 5, 2024
42a28a9
feat: 카드 합 구하기
reddevilmidzy Mar 5, 2024
8972ef5
chore: 패키지 변경
JINU-CHANG Mar 5, 2024
3a7d4d4
feat: 참여자 생성 기능 구현
JINU-CHANG Mar 5, 2024
d719d08
feat: null 이나 공백인 경우 예외가 발생 기능 구현
JINU-CHANG Mar 5, 2024
a83c06d
feat: 참여자 이름이 중복시 예외 발생 기능 구현
reddevilmidzy Mar 5, 2024
3a1cd48
feat: 총 참여자의 수는 2이상 8이하가 아닐시 예외 발생 기능 구현
JINU-CHANG Mar 5, 2024
acf6680
feat: 카드를 추가하는 기능 구현
reddevilmidzy Mar 5, 2024
68fa548
feat: Player가 Packet을 필드로 갖도록 구현
JINU-CHANG Mar 5, 2024
fbf514f
feat: CardDeck 생성 기능 구현
JINU-CHANG Mar 5, 2024
6017614
test: 플레이어에게 카드 2장을 나눠주는 기능 구현
reddevilmidzy Mar 5, 2024
ac2aa22
refactor: 리스트에서 스택으로 변경
JINU-CHANG Mar 5, 2024
aa6549c
feat: 참여자에게 카드를 2장씩 분배하는 기능 구현
JINU-CHANG Mar 5, 2024
9450f3b
feat: 딜러가 카드 2장을 분해하다.
reddevilmidzy Mar 5, 2024
b533c94
refactor: 스택에서 덱으로 변경
JINU-CHANG Mar 5, 2024
b458bdf
fix: CardNumber ONE 제거, TEN으로 추가
reddevilmidzy Mar 6, 2024
63ec5fb
feat: 카드 내의 ACE 가 포함된 경우 합이 21이하이면 에이스는 11로 계산 기능 구현
reddevilmidzy Mar 6, 2024
50e902d
feat: 카드 합 계산시 ACE 고려하는 로직 추가
JINU-CHANG Mar 6, 2024
52dcb84
refactor: Packet 클래스 이름을 Hands로 변경
reddevilmidzy Mar 6, 2024
ba0dd83
feat: 참여자의 대답이 y, n 가 아닐시 예외가 발생한다.
reddevilmidzy Mar 6, 2024
56eaa06
feat: 참여자 이름 입력받는 기능 구현
JINU-CHANG Mar 6, 2024
ee77777
feat: 플레이어의 시작 카드 출력 기능 구현
reddevilmidzy Mar 6, 2024
a5255e3
feat: 딜러 카드 출력하는 기능 구현
JINU-CHANG Mar 6, 2024
9575be9
docs: 완료한 기능 체크
JINU-CHANG Mar 6, 2024
e4d4369
feat: answer에 따라 카드를 추가 기능 구현
reddevilmidzy Mar 6, 2024
51f5aea
refactor: Dealer 필드에서 Players 제거
JINU-CHANG Mar 6, 2024
3a0ddb4
feat: 추가된 카드 출력하는 기능 구현
JINU-CHANG Mar 6, 2024
9b1e7a4
style: 사용하지 않는 메서드 삭제
reddevilmidzy Mar 6, 2024
546c4e9
feat: 참여자의 대답이 y일시 한번 더 deal 기능 구현
reddevilmidzy Mar 6, 2024
9fd7e9c
feat: 변경된 카드가 있을 경우 출력하는 기능 구현
JINU-CHANG Mar 6, 2024
3c2ce48
feat: 딜러의 카드가 17 이상이 될때까지 카드 받는 기능 구현
reddevilmidzy Mar 6, 2024
eb08c75
feat: 딜러가 카드를 받을 때 메시지 출력기능 구현
JINU-CHANG Mar 6, 2024
a1f0915
feat: 모든 참여자의 카드의 합을 출력하는 기능 구현
JINU-CHANG Mar 7, 2024
3595593
feat: hands의 승패 판단 기능 구현
reddevilmidzy Mar 7, 2024
e26d988
feat: 참여자의 승패 확인 기능 구현
reddevilmidzy Mar 7, 2024
bbd54df
style: '플레이어'를 '참여자'로 변경
reddevilmidzy Mar 7, 2024
57572c0
feat: 모든 참여자의 카드의 합을 출력하는 기능 구현
reddevilmidzy Mar 7, 2024
ef45b28
fix: 컴파일 에러 수정
JINU-CHANG Mar 7, 2024
8f1e9b8
feat: 딜러의 승패를 확인 기능 구현
JINU-CHANG Mar 7, 2024
755f99a
docs: 구현해야 할 기능 목록 추가
JINU-CHANG Mar 7, 2024
d8f2ad4
feat: 최종 결과 출력하는 기능 구현
JINU-CHANG Mar 7, 2024
4f080a1
feat: 참가자의 카드의 합이 21을 초과하면 BUST 메시지 출력 기능 구현
reddevilmidzy Mar 7, 2024
f6438d3
feat: 모든 참여자가 버스트라면 딜러는 딜하지 않는 기능 구현
reddevilmidzy Mar 7, 2024
649014a
feat: 무승부 기능 구현
JINU-CHANG Mar 7, 2024
7593784
fix: 딜러가 버스트일때 참여자가 버스트가 아니면 WIN
reddevilmidzy Mar 7, 2024
cbee98a
feat: 블랙잭 시 메시지 출력후 카드 더 받지 않는 기능 구현
JINU-CHANG Mar 7, 2024
0909ae6
docs: 블랙잭 규칙 추가
reddevilmidzy Mar 7, 2024
c96930e
Merge branch 'step1' of https://github.com/reddevilmidzy/java-blackja…
reddevilmidzy Mar 7, 2024
b188bdf
refactor: 'CardNumber'를 'Rank'로 변경, 'CardShape'를 'Shape'로 변경 및 card 패…
JINU-CHANG Mar 7, 2024
62493d6
refactor: players 관련 메서드의 파라미터 및 변수명 변경
reddevilmidzy Mar 7, 2024
4df9b26
refactor: 메서드 삭제 및 이름 변경
JINU-CHANG Mar 7, 2024
7b0d3d7
refactor: Player 클래스 메서드명 및 순서 변경
JINU-CHANG Mar 7, 2024
75d216b
refactor: CardDeck의 generate메서드 스트림 활용
reddevilmidzy Mar 7, 2024
72b3f45
refactor: Dealer 초기 카드 넘버 상수명 변경
reddevilmidzy Mar 7, 2024
6238248
refactor: Dealer가 Participant 상속받도록 변경
JINU-CHANG Mar 7, 2024
5a87d7c
docs: 기능 요구 사항 수정
reddevilmidzy Mar 8, 2024
72a3a20
fix: 카드의 사이즈가 같을 때 21에 가까운 카드 합이 이기는 기능 수정
reddevilmidzy Mar 8, 2024
9414fb4
refactor: Participant 추상클래스 생성
JINU-CHANG Mar 8, 2024
2d2154e
refactor: Dto의 이름 변경 및 정적 팩터리 메서드 명 변경
reddevilmidzy Mar 8, 2024
356674b
refactor: getCardNames 메서드 동작 로직을 hands 안으로 이동
reddevilmidzy Mar 8, 2024
da599d2
refactor: Participant 생성자 접근제한자 변경 및 메서드 정렬
reddevilmidzy Mar 8, 2024
0198084
refactor: Dealer 의 deal을 Dealer 클래스로 이동
reddevilmidzy Mar 8, 2024
781f8e8
refactor: controller 인덴트 줄이기 및 메서드 분리
JINU-CHANG Mar 8, 2024
162927e
refactor: cardDeckTest 클래스 접근제한자 변경
reddevilmidzy Mar 8, 2024
02211ea
refactor: null과 blank 테스트 코드 메서드 분리
JINU-CHANG Mar 8, 2024
2d96eec
refactor: 중복되는 테스트코드 변수 분리
JINU-CHANG Mar 8, 2024
32b1496
style: static 변수 import
JINU-CHANG Mar 8, 2024
d0c0451
refactor: 테스트 코드내에 중복되는 변수를 필드로 선언
reddevilmidzy Mar 8, 2024
23bdf69
refactor: outputView FORM 상수static 으로 변경
reddevilmidzy Mar 8, 2024
4e2a246
refactor: 사용하지 않는 필드 및 메서드 삭제
reddevilmidzy Mar 8, 2024
4ab6363
style: 코드 정렬
reddevilmidzy Mar 8, 2024
987be12
refactor: HandsTest 중복되는 테스트코드 분리
JINU-CHANG Mar 8, 2024
8c64ab9
Merge branch 'step1' of https://github.com/reddevilmidzy/java-blackja…
reddevilmidzy Mar 8, 2024
88665a8
refactor: ParticipantDto 레코드로 변경
reddevilmidzy Mar 8, 2024
7977057
refactor: Hands 메서드 분리
JINU-CHANG Mar 8, 2024
995d864
refactor: calculateResult 메서드 인덴트 줄이기
reddevilmidzy Mar 8, 2024
2d822e9
docs: 리팩터링 목록 추가
reddevilmidzy Mar 11, 2024
405ac6b
refactor: createEmptyPacket 메서드명 createEmptyHands로 수정
reddevilmidzy Mar 11, 2024
dfaae33
feat: 카드덱이 비었을때 꺼낸 경우 예외 발생
reddevilmidzy Mar 11, 2024
aaf03ab
refactor: Name 객체 포장
JINU-CHANG Mar 11, 2024
017e6a0
refactor: 승패무 판단을 Result의 책임으로 이동 (재미있게 BiPredicate 활용)
reddevilmidzy Mar 11, 2024
36094c8
refactor: Game 클래스 삭제 및 책임 분리
JINU-CHANG Mar 11, 2024
ad35da3
refactor: TestFixture 생성
JINU-CHANG Mar 11, 2024
5e142b0
style: import 문 순서 변경
reddevilmidzy Mar 11, 2024
cc6a91f
refactor: 테스트코드 변수명 변경 및 테스트 추가
reddevilmidzy Mar 11, 2024
d5564b4
fix: LinkedHashMap으로 변경하여 참여자 순서 유지
reddevilmidzy Mar 11, 2024
2b02cdb
refactor: System.out.println 대신 %n과 System.lineSeparator 사용
reddevilmidzy Mar 11, 2024
b23548c
docs: 리팩터링 목록 수정
reddevilmidzy Mar 11, 2024
8e95a70
feat: 참가자의 이름에 딜러가 사용될 시 예외 발생 기능 구현
reddevilmidzy Mar 11, 2024
2a8dfdc
refactor: isHit 메서드 생성
JINU-CHANG Mar 11, 2024
3de3d0b
docs: 리팩터링 목록 수정
JINU-CHANG Mar 11, 2024
21ec566
style: 메서드 위치 변경
JINU-CHANG Mar 11, 2024
f2d25ec
refactor: controller 메서드 추출
reddevilmidzy Mar 11, 2024
96cdc3b
chore: 패키지 정리
reddevilmidzy Mar 11, 2024
fec95ee
docs: 리팩터링 목록 추가
reddevilmidzy Mar 12, 2024
41b1df7
feat: 예외 시 재입력 기능 구현
reddevilmidzy Mar 12, 2024
4347c8c
feat: 커스텀 예외 구현
reddevilmidzy Mar 12, 2024
1713750
refactor: Participant 추상 메서드 사용
reddevilmidzy Mar 12, 2024
167957a
refactor: InvalidPlayerName 예외 클래스 이름 변경
reddevilmidzy Mar 12, 2024
e9374bc
refactor: 카드 생성 책임을 Card로 변경 및 카드를 캐시하여 가져오는 기능 구현
reddevilmidzy Mar 12, 2024
19b71c6
docs: 리팩터링 목록 수정
reddevilmidzy Mar 12, 2024
80e13e4
refactor: cardDeck 생성 책임 위치 변경
reddevilmidzy Mar 12, 2024
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
90 changes: 90 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# 블랙잭 규칙

## 참여자

**승**

* (딜러 카드 합 < 참여자 카드 합) && 참여자가 버스트가 아닌 경우
* (딜러 카드 합 == 참여자 카드 합) && (딜러 카드 수 > 참여자 카드 수) && 참여자가 버스트가 아닌 경우
* 딜러가 버스트인 경우 && 참여자가 버스트가 아닌 경우

**무**

* (딜러 카드 합 == 참여자 카드 합) && (딜러 카드 수 == 참여자 카드 수) && 참여자가 버스트가 아닌 경우

**패**

* 참여자가 버스트인 경우
* (딜러 카드 합 > 참여자 카드 합)
Comment on lines +5 to +18
Copy link
Member

Choose a reason for hiding this comment

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

개인적으로 참여자가 버스트가 아닌 경우가 맨 앞에 가있거나, 다른 방식으로 언급이 되면 더 좋을 것 같아요~
맨 뒤에 같은 말이 반복되어 가독성이 조금 떨어진다고 느껴집니다.

그리고 딜러 카드 합 == 참여자 카드 합 인데 딜러 카드 수 < 참여자 카드 수인 경우는 어떻게 되나요?
언급이 되어 있지 않아 여쭤봅니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

딜러 카드 합 == 참여자 카드 합 && 딜러 카드 수 < 참여자 카드 수 라면 "패"조건이네요 작성을 놓쳤네요😅


<br>

# 기능 요구 사항

* [x] 참여자 이름 입력 받는다.
* [x] 양 끝 공백을 제거한다.
* [x] 참여자는 쉼표(,)로 구분한다.
* [x] null 이나 공백인 경우 예외가 발생한다.
* [x] 쉼표로 시작시 예외가 발생한다. ex) ,pobi,jason
* [x] 쉼표로 끝날시 예외가 발생한다. ex) pobi,jason,
* [x] 쉼표가 연속으로 올시 예외가 발생한다. ex) pobi,,jason
* [x] 참여자 이름이 중복시 예외가 발생한다.
* [x] 총 참여자의 수는 2이상 8이하여야 한다.

<br>

* [x] 딜러가 카드 2장을 분배하다.
* [x] 카드는 총 6벌을 둔다. (52 * 6)
* [x] 딜러의 카드를 출력한다. (1장)
* [x] 참여자의 카드를 출력한다. (2장)

<br>

* [x] 참여자는 hit(y) / stay(n)를 선택한다.
* [x] y, n 가 아닐시 예외가 발생한다.
* [x] 참여자가 hit을 하는 경우 현재 가지고 있는 카드를 출력한다.
* [x] 참여자가 hit을 한 적 없이 stay를 하는 경우 현재 가지고 있는 카드를 출력한다.
* [x] 카드 합이 블랙잭인 경우 블랙잭 메시지를 출력한다.
* [x] 카드 합이 21 초과시 버스트 메시지를 출력한다.

<br>

* [x] 딜러의 카드의 합을 계산한다.
* [x] 카드 내의 ACE 가 포함된 경우
* ACE: 11
* 11로 했을 때 카드의 합이 21을 초과한 경우 1로 계산
* [x] 17 이상이 될때까지 카드를 받는다.

<br>

* [x] 모든 참여자의 카드의 합을 계산한다.
* [x] 딜러의 승패무를 확인한다.
* [x] 참여자의 승패무를 확인한다.
* [x] 게임 결과를 출력한다.

---

## 리팩터링 목록

~~추상 클래스 활용~~

* [x] 카드덱이 비었을때 꺼낸 경우 예외 발생
* [x] createEmptyPacket 메서드명 수정
* [x] 참가자의 이름 딜러 불가
* [x] Name 객체 포장하기
* [x] Result 함수형 프로그래밍 사용
* [x] TestFixture 사용
* [x] 패키지 정리
* [x] 메서드 컨벤션 작성 및 확인
* [x] final 컨벤션 통일
* [x] CardDeck 생성자 닫기

<br>

* [x] 예외 시 재입력 기능
* [x] 예외 메시지 상수화
* 커스텀 예외 구현
* [x] CardDeck 웨어하우스로 바라보기
* [ ] ~~컨트롤러 메서드 수정하기~~
* [x] ~~Participant 추상 클래스 대신 클래스로 변경하기~~
* 추상 클래스를 유지하고 추상 메서드 추가
18 changes: 18 additions & 0 deletions src/main/java/application/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package application;

import controller.BlackJackController;
import controller.InputController;
import java.util.Scanner;
import view.InputView;
import view.OutputView;

public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
final InputView inputView = new InputView(scanner);
final OutputView outputView = new OutputView();
final InputController inputController = new InputController(inputView, outputView);
final BlackJackController blackJackController = new BlackJackController(inputController, outputView);
blackJackController.run();
}
}
15 changes: 15 additions & 0 deletions src/main/java/constants/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package constants;

public enum ErrorCode {

NOT_EXIST_MESSAGE,
INVALID_SEPARATOR,
INVALID_INPUT,
INVALID_SIZE,
DUPLICATE_NAME,
RESERVED_NAME,
BLANK_VALUE,
EMPTY_CARD,
INVALID_COMMAND,
;
}
92 changes: 92 additions & 0 deletions src/main/java/controller/BlackJackController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package controller;

import domain.Answer;
import domain.participant.Dealer;
import domain.participant.Player;
import domain.participant.Players;
import dto.DealerHandsDto;
import dto.ParticipantDto;
import dto.ParticipantsDto;
import view.OutputView;

public class BlackJackController {

private final InputController inputController;
private final OutputView outputView;


public BlackJackController(final InputController inputController, final OutputView outputView) {
this.inputController = inputController;
this.outputView = outputView;
}

public void run() {
Copy link
Member

Choose a reason for hiding this comment

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

메서드 길이가 10라인을 넘었네요

final Players players = inputController.getPlayers();
final Dealer dealer = new Dealer();

initHands(players, dealer);
dealWithPlayers(players, dealer);

if (!players.isAllBust()) {
dealer.deal();
printDealerTurnMessage(dealer.countAddedHands());
}

printFinalResult(players, dealer);
}

private void printDealerTurnMessage(final int turn) {
for (int i = 0; i < turn; i++) {
outputView.printDealerTurnMessage();
}
}

private void dealWithPlayers(final Players players, final Dealer dealer) {
for (Player player : players.getPlayers()) {
deal(player, dealer);
}
}

private void initHands(final Players players, final Dealer dealer) {
dealer.initHands(players);
outputView.printStartDeal(DealerHandsDto.from(dealer), ParticipantsDto.of(players));
}

private void printFinalResult(final Players players, final Dealer dealer) {
outputView.printHandsResult(ParticipantsDto.of(dealer, players));
outputView.printGameResult(dealer.getDealerResult(players), players.getPlayersResult(dealer));
}

private void deal(final Player player, final Dealer dealer) {
boolean handsChanged = false;
boolean turnEnded = false;

while (!turnEnded) {
final Answer answer = inputController.getAnswer(player.getName());
dealer.deal(player, answer);

printHandsIfRequired(player, handsChanged, answer);
Copy link
Member

Choose a reason for hiding this comment

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

21 이상이면 카드를 받을 수 없는 것은 예제와 다르게 구현하셨는데,
보여준 적 없으면 보여준다는 것은 예제대로 구현하셨네요!

저는 이 부분이 생기면서 로직이 좀 복잡해진 듯 합니다.
혹시 이 기능이 꼭 필요하다고 생각하신 이유가 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

오오 잘 캐치해주셨어요!

어떤건 예제대로 하고 어떤건 또 멋대로 구현하여 혼란을 줄 수도 있을거 같은데 이유를 설명해보자면;;;
21이상 일때 카드를 더 받을 수 없게 한것은 플레이어가 최적의 스코어를 얻을 수 있게하기 위함이었습니다

그리고 변경된 경우에만 출력하는 기능은 예제 보고 규칙을 파악하여 그냥 신나서 구현했던 거 같아요 ㅎㅎㅎ
꼭 필요하다고 생각해서 구현하진 않았습니다😅


handsChanged = true;
turnEnded = isTurnEnded(player, answer);
}
}

private void printHandsIfRequired(final Player player, final boolean handsChanged, final Answer answer) {
if (shouldShowHands(handsChanged, answer)) {
outputView.printHands(ParticipantDto.from(player));
}
}
Comment on lines +75 to +79
Copy link
Member

Choose a reason for hiding this comment

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

printHandsIfRequired 라는 네이밍을 봤을 때 한 번에 이해하기는 좀 힘든 것 같아요.

직역하면 "필요한 경우 핸드를 출력한다" 라는 의미 같은데,
왜 필요한지 알기 위해 메서드를 열어봤더니 또 if 조건 문 안에
shouldShowHands "보여줘야한다" 라는 의미의 네이밍 조건이 있어서.. 이해하기 조금 힘드네용 😊

메서드 이름에 행위를 드러내더라도 의도가 조금 섞이도록 하는게 좋을 것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

네이밍 어려워요ㅜㅜ
사실 저 메서드명은 채찍피티가 짜줬던 거 같네요
좀 더 고민해보겠습니다!

Copy link
Member

Choose a reason for hiding this comment

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

ㅋㅋㅋㅋㅋㅋㅋ 저는 지쌤이라 부르는데 채찍피티도 재밌네요


private boolean isTurnEnded(final Player player, final Answer answer) {
if (player.canDeal()) {
return !answer.isHit();
}
outputView.printDealEndMessage(player.isBust());
return true;
}

private boolean shouldShowHands(final boolean handsChanged, final Answer answer) {
return answer.isHit() || !handsChanged;
}
}
55 changes: 55 additions & 0 deletions src/main/java/controller/InputController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package controller;

import domain.Answer;
import domain.participant.Players;
import exception.CustomException;
import java.util.List;
import view.InputView;
import view.OutputView;

public class InputController {

private final InputView inputView;
private final OutputView outputView;

public InputController(final InputView inputView, final OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}

public Players getPlayers() {
Players players;
do {
players = readPlayers();
} while (players == null);
return players;
}

public Answer getAnswer(String name) {
Answer answer;
do {
answer = readAnswer(name);
} while (answer == null);
return answer;
}

private Players readPlayers() {
try {
List<String> rawNames = inputView.readNames();
return Players.from(rawNames);
} catch (CustomException exception) {
outputView.printException(exception.getErrorCode());
return null;
}
}

private Answer readAnswer(String name) {
try {
String value = inputView.readAnswer(name);
return Answer.from(value);
} catch (CustomException exception) {
outputView.printException(exception.getErrorCode());
return null;
}
}
}
28 changes: 28 additions & 0 deletions src/main/java/domain/Answer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package domain;

import constants.ErrorCode;
import exception.InvalidCommandException;
import java.util.Arrays;

public enum Answer {

HIT("y"),
STAY("n");

private final String value;

Answer(final String value) {
this.value = value;
}

public static Answer from(final String value) {
return Arrays.stream(Answer.values())
.filter(answer -> answer.value.equals(value))
.findFirst()
.orElseThrow(() -> new InvalidCommandException(ErrorCode.INVALID_COMMAND));
}

public boolean isHit() {
return HIT.equals(this);
}
}
55 changes: 55 additions & 0 deletions src/main/java/domain/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package domain;

import domain.participant.Hands;
import java.util.Arrays;
import java.util.function.BiPredicate;

public enum Result {

WIN("승", Result::winningCondition),
TIE("무", Result::tieCondition),
LOSE("패", Result::loseCondition);

private final String value;
private final BiPredicate<Hands, Hands> condition;

Result(final String value, final BiPredicate<Hands, Hands> condition) {
this.value = value;
this.condition = condition;
}

public Result reverse() {
if (Result.WIN.equals(this)) {
return LOSE;
}
if (Result.LOSE.equals(this)) {
return WIN;
}
return TIE;
}

public static Result calculateOf(final Hands hands, final Hands target) {
return Arrays.stream(Result.values())
.filter(result -> result.condition.test(hands, target))
.findFirst()
.orElseThrow();
}

private static boolean winningCondition(final Hands hands, final Hands target) {
return (!hands.isBust() && target.isBust())
|| (hands.sum() > target.sum() && !hands.isBust())
|| (hands.sum() == target.sum() && hands.size() < target.size() && !hands.isBust());
}

private static boolean tieCondition(final Hands hands, final Hands target) {
return hands.sum() == target.sum() && hands.size() == target.size() && !hands.isBust();
}

private static boolean loseCondition(final Hands hands, final Hands target) {
return hands.isBust() || hands.sum() < target.sum() || !target.isBust();
}

public String getValue() {
return value;
}
}
Loading