Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1ac9014
docs: 페어 규칙 정의
hanull Mar 8, 2022
c9803a7
docs: 연료 주입 구현 기능 목록 정의 및 README 패키지 분리
hanull Mar 8, 2022
cd54ba2
docs: 구현할 기능 목록 추가
hanull Mar 8, 2022
c4fe436
feat: 차량 생성 기능 구현
hanull Mar 8, 2022
6300622
docs: 구현 목록 수정
hanull Mar 8, 2022
e97c83d
feat: 주입해야 할 연료량 계산 기능 구현
hanull Mar 8, 2022
0cbf073
feat: 렌트 회사 차량 추가 기능 구현
hanull Mar 8, 2022
b31236a
feat: 보고서 생성 기능 구현
hanull Mar 8, 2022
b1f051c
docs: 게임 룰, 구현할 기능 목록 정의
hanull Mar 8, 2022
409b960
docs: 구현할 도메인 정보 수정
hanull Mar 9, 2022
b354262
docs: 처리해야할 예외 목록 추가
hanull Mar 9, 2022
ce18f77
docs: 구현할 기능 및 도메인 수정
hanull Mar 9, 2022
cb334a7
feat: 카드덱을 생성하고 뽑아주는 기능 구현
hanull Mar 9, 2022
82b88d2
feat: 플레이어에게 카드를 나누어주는 기능 구현
hanull Mar 9, 2022
41d6e5f
feat: 플레이어의 카드 총합 계산 및 확인 기능 구현
hanull Mar 9, 2022
c703895
feat: 유저와 딜러의 카드 총합을 계산하는 기능 구현
hanull Mar 10, 2022
632cd2f
refactor: 클래스 위치 변경 및 불필요한 import 삭제
hanull Mar 10, 2022
2d4d76d
feat: 딜러와 유저의 게임 결과를 구하는 기능 구현
hanull Mar 10, 2022
d87e8a7
refactor: 처음 받는 카드의 수 검증 로직 플레이어로 이동
hanull Mar 10, 2022
9d76f84
fix: 카드의 총합이 21을 넘는 경우에 대한 결과 처리 해결
hanull Mar 10, 2022
c46ba94
fix: 카드의 총합 계산시 고려하지 않았던 에이스 카드 처리
hanull Mar 10, 2022
03993dc
feat: 플레이어의 이름을 입력 받는 기능 추가
brorae Mar 10, 2022
d7c9fe5
feat: 플레이어가 카드를 더 받을 것인지 물어보는 기능 구현
brorae Mar 10, 2022
d61716b
feat: 첫 딜러와 유저의 카드를 출력하는 기능 추가
brorae Mar 10, 2022
f27e748
feat: 게임이 종료될 때까지 카드를 받을지 물어보는 기능 구현
brorae Mar 10, 2022
0ed9759
feat: 딜러와 유저의 최종 카드 결과를 출력하는 기능 추가
brorae Mar 10, 2022
844d772
feat: 딜러와 유저의 최종 승패를 출력하는 기능 추가
brorae Mar 10, 2022
bbd0809
refactor: 카드 패턴 enum으로 분리
brorae Mar 11, 2022
6bb3ea4
refactor: Card test 추가 및 매직 넘버 상수화
brorae Mar 11, 2022
70a5be5
refactor: GameMachine 생성하여 역할 분리
brorae Mar 11, 2022
9e0beea
refactor: 블랙잭인 경우 수정
brorae Mar 11, 2022
71a6de9
refactor : 메소드 이름 수정 및 리팩토링
brorae Mar 11, 2022
7e348e9
refactor: 불필요한 부분 제거
brorae Mar 11, 2022
31230aa
refactor: 카드 테스트 수정
brorae Mar 12, 2022
0a930cd
refactor: 에러메시지 출력 부분 view로 이동
brorae Mar 12, 2022
1afa8d5
refactor: Player 사용 명확하도록 수정, 재할당 하지 않도록 수정
brorae Mar 12, 2022
cea7edf
fix: 게임 참여 인원 제한 추가
brorae Mar 12, 2022
3999639
refactor: final 키워드 수정
brorae Mar 12, 2022
9ec8782
refactor: protected 접근 제한자 변경
brorae Mar 15, 2022
228cce9
refactor: 결과 비교 함수 파라미터 변경
brorae Mar 15, 2022
9006600
refactor: public 상수 private으로 변경
brorae Mar 15, 2022
3d0f800
refactor: users domain 추가
brorae Mar 16, 2022
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
80 changes: 80 additions & 0 deletions docs/blackjack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# 블랙잭

## 페어 규칙

- 어려워도 TDD로 구현한다.
- 2시간 코딩하고 10분 휴식한다.
- 밤 10시 이후에는 개인 시간을 가진다.
- 커밋 컨벤션은 아래와 같이 작성한다.
- feat: commit message
- 네이밍 시, 깊게 고민한 후 결정한다.
- 역할 교대는 5분 간격으로 한다.
- 의견 조율이 필요하다면, 시간을 멈춘다.

## 카드 정보

- 카드는 4개의 문향을 가진다.
- 다이아몬드, 하트, 스페이드, 클로버
- 각 문향은 2 - 10의 숫자 카드와 10을 나타내는 K, Q, J 카드, 1과 11을 선택할 수 있는 A 카드로 나뉜다.

## 게임 룰

- 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이긴다.
- 게임 시작 시, 딜러와 플레이어에게 각각 2장씩 카드를 나눠준다. 단, 딜러는 1장의 카드만 오픈한다. (오픈하는 카드는 랜덤으로 정한다.)
- 플레이어는 카드를 더 받을 것인지 선택할 수 있다.
- 플레이어의 카드 합이 21을 초과한 경우, 딜러의 패와 상관없이 패배한다.
- 딜러가 처음 받은 2장의 카드 합이 16이하면 반드시 1장의 카드를 추가로 받아야 하고, 합이 17이상이면 추가로 받을 수 없다.
- 딜러와 플레이어의 카드 합이 동일한 경우, 무승부이다.

## 구현할 기능 목록

- [x] 플레이어의 이름을 입력한다.
- [x] [ERROR] 참여한 플레이어가 없는 경우
- [x] [ERROR] 플레이어의 이름이 공백인 경우
- [x] [ERROR] 플레이어의 이름이 중복된 경우
- [x] [ERROR] 플레이어의 인원이 8명 초과인 경우
- [x] 카드덱은 카드덱을 생성하고 사용한 카드를 제거한다.
- [x] 생성한 카드덱에서 플레이어에게 카드를 나누어준다.
- [x] 첫 딜러와 유저의 카드를 출력한다. (딜러 1장, 플레이어 2장)
- [x] 플레이어 카드의 총합을 구한다.
- [x] 유저의 카드 총합이 21이하인지 확인한다.
- [x] 딜러의 카드 총합이 16이하인지 확인한다.
- [x] 카드를 더 받을 것인지 물어본다.
- [x] [ERROR] y, n 이외에 다른 문자를 입력한 경우 (단, y와 n의 대소문자 모두 허용)
- [x] 플레이어가 보유한 카드를 출력한다.
- [x] 모든 유저의 게임이 종료될 때까지 위의 두 과정을 반복한다.
- 종료 조건 : 플레이어 카드의 합이 21을 초과, 카드를 더 이상 받지 않는 경우
- [x] 딜러와 유저의 최종 결과를 계산한다.
- [x] 딜러와 유저의 최종 카드 결과를 출력한다.
- [x] 딜러와 유저의 최종 승패를 출력한다.

## 도메인

- 카드
- 카드의 문향과 숫자 정보
- 카드덱
- 모든 카드 정보
- 카드덱을 생성한다.
- 카드를 나눠준다.
- 사용한 카드를 제거한다.
- 플레이어
- 카드를 뽑는다.
- 카드의 합을 계산한다.
- 유저
- 이름, 카드 리스트
- 딜러
- 이름, 카드 리스트
- 게임 머신
- 게임 전체 로직을 관리한다.
- 유저의 상태를 관리한다.
- 카드를 더 받을 것인지 물어본다.
- 게임 결과
- 유저와 딜러의 승패 결과를 계산한다.

## 카드 계산 방법
- 기본 A의 점수는 11로 한다.
- A를 포함하지 않는 경우
- 일반적으로 계산
- A를 포함하는 경우
- 총합이 21을 초과하는 경우
- 최대 A의 수만큼 반복하면서 10씩 뺴준다. (21 이하가 될 때 반복을 멈춘다.)
19 changes: 19 additions & 0 deletions docs/rentcompany/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 연료 주입

## 구현할 기능 목록

- [x] 렌트회사는 차량을 추가할 수 있다.
- [x] 입력받은 이동거리와 각 차량의 연비로 차량을 생성한다.
- [x] 이동거리를 활용해서 차량 별로 주입해야 할 연료량을 구한다.
- Sonata : 10km/리터
- Avante : 15km/리터
- K5 : 13km/리터
- [x] 차량 별로 주입할 연료량 보고서를 생성한다.

## 도메인

- RentCompany
- Car
- Sonata
- Avante
- K5
15 changes: 15 additions & 0 deletions src/main/java/blackjack/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package blackjack;

import blackjack.controller.GameController;
import blackjack.view.ResultView;

public class Application {
public static void main(String[] args) {
try {
GameController gameController = new GameController();
gameController.run();
} catch (IllegalArgumentException e) {
ResultView.printErrorMessage(e);
}
}
}
53 changes: 53 additions & 0 deletions src/main/java/blackjack/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package blackjack.controller;

import blackjack.domain.CardDeckGenerator;
import blackjack.domain.GameMachine;
import blackjack.domain.GameResult;
import blackjack.domain.player.Dealer;
import blackjack.domain.player.User;
import blackjack.domain.player.Users;
import blackjack.view.InputView;
import blackjack.view.ResultView;

public class GameController {

public void run() {
GameMachine gameMachine = new GameMachine(CardDeckGenerator.createCardDeckByCardNumber());

Dealer dealer = gameMachine.createDealer();
Users users = gameMachine.createUsers(InputView.inputUsers());
ResultView.printPlayersCards(dealer, users);

playTurn(gameMachine, dealer, users);
ResultView.printTotalCardResult(dealer, users);

GameResult gameResult = GameResult.createPlayerGameResult(dealer, users);
ResultView.printGameResult(gameResult);
}

private void playTurn(GameMachine gameMachine, Dealer dealer, Users users) {
if (!gameMachine.hasBlackJack(dealer, users)) {
turnOfUsers(gameMachine, users);
turnOfDealer(gameMachine, dealer);
}
}

private void turnOfUsers(GameMachine gameMachine, Users users) {
for (User user : users.getUsers()) {
processForUser(gameMachine, user);
}
}

private void processForUser(final GameMachine gameMachine, final User user) {
while (user.canDrawCard() && InputView.inputDrawCardAnswer(user)) {
gameMachine.drawCardToPlayer(user);
ResultView.printPlayerCards(user);
}
}

private void turnOfDealer(GameMachine gameMachine, Dealer dealer) {
if (gameMachine.checkPlayerReceiveCard(dealer)) {
ResultView.printDealerReceiveCard();
}
}
}
31 changes: 31 additions & 0 deletions src/main/java/blackjack/domain/CardDeck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package blackjack.domain;

import blackjack.domain.card.Card;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class CardDeck {

private final Queue<Card> cardDeck;

public CardDeck(final List<Card> cardDeck) {
this.cardDeck = (LinkedList<Card>) cardDeck;
}

public List<Card> selectOriginalCard() {
List<Card> cards = new ArrayList<>();
cards.add(selectCard());
cards.add(selectCard());
return cards;
}

public Card selectCard() {
return cardDeck.poll();
}

public int size() {
return cardDeck.size();
}
}
26 changes: 26 additions & 0 deletions src/main/java/blackjack/domain/CardDeckGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package blackjack.domain;

import blackjack.domain.card.Card;
import blackjack.domain.card.CardNumber;
import blackjack.domain.card.CardPattern;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class CardDeckGenerator {

public static CardDeck createCardDeckByCardNumber() {
List<Card> cards = new LinkedList<>();
for (final CardPattern cardPattern : CardPattern.values()) {
addCard(cards, cardPattern);
}
Collections.shuffle(cards);
return new CardDeck(cards);
}

private static void addCard(List<Card> cards, CardPattern cardPattern) {
for (final CardNumber cardNumber : CardNumber.values()) {
cards.add(new Card(cardPattern, cardNumber));
}
}
}
55 changes: 55 additions & 0 deletions src/main/java/blackjack/domain/GameMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package blackjack.domain;

import blackjack.domain.player.Dealer;
import blackjack.domain.player.Player;
import blackjack.domain.player.User;
import blackjack.domain.player.Users;
import blackjack.view.InputView;
import java.util.List;
import java.util.stream.Collectors;

public class GameMachine {

private static final int MAX_PLAY_GAME_COUNT = 7;
private static final String PLAY_GAME_COUNT_EXCEPTION_MESSAGE = "게임에 참여할 수 있는 유저는 최대 7명입니다.";

private final CardDeck cardDeck;

public GameMachine(final CardDeck cardDeck) {
this.cardDeck = cardDeck;
}

public Dealer createDealer() {
return new Dealer(cardDeck.selectOriginalCard());
}

public Users createUsers(final List<String> userNames) {
validateUserCount(userNames);
List<User> users = userNames.stream()
.map(userName -> new User(userName, cardDeck.selectOriginalCard()))
.collect(Collectors.toList());
return new Users(users);
}

private static void validateUserCount(final List<String> users) {
if (users.size() > MAX_PLAY_GAME_COUNT) {
throw new IllegalArgumentException(PLAY_GAME_COUNT_EXCEPTION_MESSAGE);
}
}

public boolean checkPlayerReceiveCard(final Player player) {
if (player.canDrawCard()) {
drawCardToPlayer(player);
return true;
}
return false;
}

public void drawCardToPlayer(final Player player) {
player.drawCard(cardDeck.selectCard());
}

public boolean hasBlackJack(Dealer dealer, Users users) {
return dealer.isBlackJack() || users.hasBlackJack();
}
}
45 changes: 45 additions & 0 deletions src/main/java/blackjack/domain/GameResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package blackjack.domain;

import blackjack.domain.player.Dealer;
import blackjack.domain.player.Player;
import blackjack.domain.player.Users;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class GameResult {

private final Map<String, Result> userResult;
private final Map<Result, Integer> dealerResult;

private GameResult(final Map<String, Result> userResult, final Map<Result, Integer> dealerResult) {
this.userResult = userResult;
this.dealerResult = dealerResult;
}

public static GameResult createPlayerGameResult(final Dealer dealer, final Users users) {
Map<String, Result> userResult = new HashMap<>();
Map<Result, Integer> dealerResult = initializeDealerResultCount();
for (final Player user : users.getUsers()) {
userResult.put(user.getName(), user.findResult(dealer));
dealerResult.compute(dealer.findResult(user), (result, count) -> count + 1);
}
return new GameResult(userResult, dealerResult);
}

private static Map<Result, Integer> initializeDealerResultCount() {
return new HashMap<>(Map.ofEntries(
Map.entry(Result.WIN, 0),
Map.entry(Result.DRAW, 0),
Map.entry(Result.LOSE, 0)
));
}

public Map<String, Result> getUserResult() {
return Collections.unmodifiableMap(userResult);
}

public Map<Result, Integer> getDealerResult() {
return Collections.unmodifiableMap(dealerResult);
}
}
43 changes: 43 additions & 0 deletions src/main/java/blackjack/domain/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package blackjack.domain;

import blackjack.domain.player.Player;

public enum Result {

WIN("승"),
DRAW("무"),
LOSE("패");

private final String result;

Result(String result) {
this.result = result;
}

public static Result findResult(final Player player, final Player otherPlayer) {
if (player.isBust() && otherPlayer.isBust()) {
return DRAW;
}
if (player.isBust()) {
return LOSE;
}
if (otherPlayer.isBust()) {
return WIN;
}
return compareScore(player.getTotalScore(), otherPlayer.getTotalScore());
}

private static Result compareScore(final int myScore, final int otherScore) {
if (myScore > otherScore) {
return WIN;
}
if (myScore < otherScore) {
return LOSE;
}
return DRAW;
}

public String getResult() {
return result;
}
}
Loading