generated from gonza-st/playground-template
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Open
hongxeob
wants to merge
29
commits into
hongxeob
Choose a base branch
from
hongxeob-feature
base: hongxeob
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+965
−3
Open
[홍섭] 숫자 야구 #2
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
37ece42
docs : 기능 목록 작성
hongxeob 96af6a0
docs : 기능 목록 작성
hongxeob c69ccea
feat: 콘솔로 사용자의 입력을 받는 Reader 예외 구현
hongxeob c0d3112
feat: 랜덤 숫자를 생성하는 생성기 구현 및 테스트
hongxeob 68f6db3
feat: 룰에 관한 값을 관리 하기 위한 상수 클래스 구현
hongxeob 486d780
refactor: Validator 추상화 해제 및 검증 로직 오버로딩
hongxeob 60aafdc
docs : update README.md
hongxeob 105c9f5
feat: 숫자를 비교하는 심판 테스트 코드 및 구현
hongxeob 2cc2624
feat: 검증없이 입력 읽는 메서드 추가
hongxeob cb78f5d
feat: 숫자 야구를 실행하는 Game 클래스 테스트 및 구현
hongxeob 1b16ff7
refactor: 검증용 클래스 static으로 사용
hongxeob 0b305cf
style: 패키지 설정
hongxeob e8419f9
feat: 출력의 역할을 하는 Printer 구현 및 테스트
hongxeob bf10789
refactor : Game 클래스 수정
hongxeob 7b80461
update README.md
hongxeob 91a3763
test: 패키지 이동
hongxeob ba5ecd3
refactor: 검증 순서 변경
hongxeob 5251d14
refactor: Game -> BaseballGameRule로 변경
hongxeob 6556810
test: BaseballGameRule 테스트 코드 작성
hongxeob fb70817
test: BaseballGame/ BaseballGameManager로 리팩토링
hongxeob 0c97e38
test : 테스트코드 작성
hongxeob 8e103ec
refactor: 메인에 반영
hongxeob 1093f77
리뷰 반영 : number List -> 객체로 변경
hongxeob 34dec54
리뷰 반영 Test : number List -> 객체로 변경
hongxeob 2b554b8
리뷰 반영 : Random 생성자 초기화
hongxeob a43688a
리뷰 반영 : Converter 검증 추가
hongxeob 28a43b3
리뷰 반영 : read 네이밍 변경
hongxeob fe5ac84
add : 회고
hongxeob 200e04f
add : 회고
hongxeob File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# ⚾️ 숫자 야구 기능 목록 Check List | ||
|
||
- [x] 1부터 9까지 서로 다른 랜덤 숫자 3개를 생성한다. | ||
- [x] 사용자로부터 숫자를 입력 받는다. | ||
- [x] [예외] 받은 값이 3자리가 아니다. | ||
- [x] [예외] 받은 값이 숫자가 아니다. | ||
- [x] [예외] 받은 값에 중복이 있다. | ||
- [x] 컴퓨터의 수 & 플레이어수를 비교한다. | ||
- [x] 몇 개의 숫자가 같은지 확인한다. | ||
- [x] 특정 자리에 해당 숫자가 있는지 확인한다. | ||
- [x] 같은 숫자만 있으면 `ball` | ||
- [x] 같은 숫자 + 같은 위치면 `strike` | ||
- [x] 같은 숫자가 하나도 없으면 `낫싱` | ||
- [x] 숫자 모두 같은 위치에 있으면 게임 종료. | ||
- [x] 사용자에게 결과를 알려준다. | ||
- [x] 재시작 여부를 묻는다. | ||
-[x] [예외] 1,2 이외의 값이 포함 되어있다. | ||
|
||
# 회고 | ||
|
||
## Keep | ||
- `테스트를 먼저 작성한다.`를 지키기 위해 힘들어도 의식적으로 최대한 테스트 코드를 먼저 작성 하려고했다. -> 컴포트 존에서 벗어나려는 노력 | ||
- SOLID 원칙중 SRP를 최대한 지키려고 노력했다. | ||
- 스터디 시간 외에도 더 관심있게 보고 작업하고 이어가려고 노력했다. | ||
- 비슷한 주제로 부트캠프에서 빅테크 선배들한테 코드리뷰를 받은 적 있는데, 기억을 살려 최대한 비슷하게 팀원들에게 리뷰해주려고 노력했다. | ||
- 팀원들이 까먹지 않게 최대한 리마인드를 했다. | ||
|
||
## Problem | ||
- 코드리뷰 후 막바지 수정에 100% 고민하고 에너지를 쏟아서 리팩토링하지 못한 것 같다. | ||
- TDD 진행시 엣지 케이스, 실패 케이스에 대한 테스트를 더 많이 작성해야한다. | ||
|
||
## Try | ||
- 테스트 코드 작성시 해피 케이스도 좋지만, 실패/엣지 케이스에 대해 더 고민하고 작성해야겠다. | ||
- 비즈니스적인 feature 코드를 잘 작성하는 것에 더불어 공통적인 코드(ex. `common`,`util`, `general` 및 컨버터, 정규식 등등) 조각들을 어떻게 더 효율적으로 관리할지 고민해봐야겠다. | ||
- 초반에 잘 불타던 것이 뒷심이 딸리지 않게 에너지/시간 분배를 잘 해야겠다. |
32 changes: 29 additions & 3 deletions
32
java-playground/src/main/java/org/gonza/javaplayground/JavaPlaygroundApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,39 @@ | ||
package org.gonza.javaplayground; | ||
|
||
import org.gonza.javaplayground.core.BaseballGameManager; | ||
import org.gonza.javaplayground.core.BaseballGameRule; | ||
import org.gonza.javaplayground.core.Judgement; | ||
import org.gonza.javaplayground.core.NumberGenerator; | ||
import org.gonza.javaplayground.view.*; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
import java.util.Scanner; | ||
|
||
@SpringBootApplication | ||
public class JavaPlaygroundApplication { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(JavaPlaygroundApplication.class, args); | ||
} | ||
public static void main(String[] args) { | ||
SpringApplication.run(JavaPlaygroundApplication.class, args); | ||
|
||
Scanner scanner = new Scanner(System.in); | ||
Reader reader = new ConsoleReader(scanner); | ||
Printer printer = new ConsolePrinter(); | ||
|
||
// 도메인 | ||
NumberGenerator numberGenerator = new NumberGenerator(); | ||
Judgement judgement = new Judgement(); | ||
BaseballGameRule baseballGameRule = new BaseballGameRule(numberGenerator, judgement); | ||
|
||
// UI View | ||
GameView gameView = new GameView(reader, printer); | ||
|
||
// 게임 매니저 생성 및 실행 | ||
BaseballGameManager baseballGameManager = new BaseballGameManager(baseballGameRule, gameView); | ||
baseballGameManager.run(); | ||
|
||
scanner.close(); | ||
|
||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
java-playground/src/main/java/org/gonza/javaplayground/core/BaseballGame.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
public class BaseballGame { | ||
private final BaseballGameRule rule; | ||
private Numbers computerNumbers; | ||
|
||
public BaseballGame(BaseballGameRule rule) { | ||
this.rule = rule; | ||
this.computerNumbers = rule.generateNumbers(); | ||
} | ||
|
||
public GameResult guess(Numbers playerNumbers) { | ||
return rule.guess(computerNumbers, playerNumbers); | ||
} | ||
|
||
public void restart() { | ||
this.computerNumbers = rule.generateNumbers(); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
java-playground/src/main/java/org/gonza/javaplayground/core/BaseballGameManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
import org.gonza.javaplayground.view.GameView; | ||
|
||
public class BaseballGameManager { | ||
private final BaseballGame game; | ||
private final GameView view; | ||
|
||
public BaseballGameManager(BaseballGameRule rule, GameView view) { | ||
this.game = new BaseballGame(rule); | ||
this.view = view; | ||
} | ||
|
||
public void run() { | ||
view.displayGameStart(); | ||
startGameLoop(); | ||
} | ||
|
||
private void startGameLoop() { | ||
while (true) { | ||
playRoundWithErrorHandling(); | ||
} | ||
} | ||
|
||
private void playRoundWithErrorHandling() { | ||
try { | ||
playOneRound(); | ||
} catch (IllegalArgumentException e) { | ||
view.displayError(e.getMessage()); | ||
} | ||
} | ||
|
||
private void playOneRound() { | ||
Numbers playerNumberList = view.getPlayerInput(); | ||
GameResult gameResult = game.guess(playerNumberList); | ||
view.displayResult(gameResult.result()); | ||
|
||
if (!gameResult.isGameWon()) return; | ||
handleWin(); | ||
} | ||
|
||
private void handleWin() { | ||
view.displayWinMessage(); | ||
if (!shouldPlayAgain()) { | ||
exitGame(); | ||
} | ||
startNewGame(); | ||
} | ||
|
||
private void startNewGame() { | ||
game.restart(); | ||
view.displayNewGameMessage(); | ||
} | ||
|
||
private boolean shouldPlayAgain() { | ||
try { | ||
GameCommand command = getGameCommand(); | ||
return command.isRestart(); | ||
} catch (IllegalArgumentException e) { | ||
view.displayInvalidChoiceError(); | ||
return shouldPlayAgain(); | ||
} | ||
} | ||
|
||
private GameCommand getGameCommand() { | ||
int choice = view.getRetryChoice(); | ||
return GameCommand.from(choice); | ||
} | ||
|
||
private void exitGame() { | ||
System.exit(0); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
java-playground/src/main/java/org/gonza/javaplayground/core/BaseballGameRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
public class BaseballGameRule { | ||
private final NumberGenerator numberGenerator; | ||
private final Judgement judgement; | ||
|
||
public BaseballGameRule(NumberGenerator numberGenerator, Judgement judgement) { | ||
this.numberGenerator = numberGenerator; | ||
this.judgement = judgement; | ||
} | ||
|
||
public GameResult guess(Numbers computerNumbers, Numbers playerNumbers) { | ||
String result = judgement.compareNumber(computerNumbers, playerNumbers); | ||
boolean isGameWon = judgement.isGameWon(result); | ||
|
||
return new GameResult(result, isGameWon); | ||
} | ||
|
||
public Numbers generateNumbers() { | ||
return numberGenerator.generateRandomNumber(RuleConstants.REQUIRED_LENGTH); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
java-playground/src/main/java/org/gonza/javaplayground/core/GameCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
import java.util.Arrays; | ||
|
||
public enum GameCommand { | ||
RESTART(1), | ||
EXIT(2); | ||
|
||
private final int command; | ||
|
||
GameCommand(int command) { | ||
this.command = command; | ||
} | ||
|
||
public static GameCommand from(int input) { | ||
return Arrays.stream(values()) | ||
.filter(command -> command.command == input) | ||
.findFirst() | ||
.orElseThrow(() -> new IllegalArgumentException("1 또는 2만 입력 가능합니다.")); | ||
} | ||
|
||
public boolean isRestart() { | ||
return this == RESTART; | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
java-playground/src/main/java/org/gonza/javaplayground/core/GameResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
public record GameResult(String result, boolean isGameWon) { | ||
} |
65 changes: 65 additions & 0 deletions
65
java-playground/src/main/java/org/gonza/javaplayground/core/Judgement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
import java.util.List; | ||
|
||
public class Judgement { | ||
|
||
public String compareNumber(Numbers computerNumbers, Numbers playerNumbers) { | ||
int correctCount = getPlaceHitCount(computerNumbers, playerNumbers); | ||
int strike = getStrikeCount(computerNumbers, playerNumbers); | ||
int ball = getBallCount(correctCount, strike); | ||
|
||
String result = getResult(correctCount, strike, ball); | ||
|
||
return result; | ||
} | ||
|
||
public boolean isGameWon(String result) { | ||
return result.equals(RuleConstants.REQUIRED_LENGTH + "스트라이크"); | ||
} | ||
|
||
private String getResult(int correctCount, int strike, int ball) { | ||
if (correctCount == 0) { | ||
return "아웃"; | ||
} | ||
|
||
if (strike == 0) { | ||
return ball + "볼"; | ||
} | ||
|
||
if (ball == 0) { | ||
return strike + "스트라이크"; | ||
} | ||
|
||
return ball + "볼 " + strike + "스트라이크"; | ||
} | ||
|
||
private int getStrikeCount(Numbers computerNumberList, Numbers playerNumberList) { | ||
int strike = 0; | ||
|
||
for (int placeIndex = 0; placeIndex < playerNumberList.values().size(); placeIndex++) { | ||
if (hasNumberInPlace(computerNumberList.values(), placeIndex, playerNumberList.values().get(placeIndex))) { | ||
strike++; | ||
} | ||
} | ||
return strike; | ||
} | ||
|
||
private int getBallCount(int correctCount, int strike) { | ||
return correctCount - strike; | ||
} | ||
|
||
private int getPlaceHitCount(Numbers computerNumberList, Numbers playerNumberList) { | ||
int count = 0; | ||
for (int player : playerNumberList.values()) { | ||
if (computerNumberList.values().contains(player)) { | ||
count++; | ||
} | ||
} | ||
return count; | ||
} | ||
|
||
private boolean hasNumberInPlace(List<Integer> computers, int placeIndex, int number) { | ||
return computers.get(placeIndex) == number; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
java-playground/src/main/java/org/gonza/javaplayground/core/NumberGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
import org.gonza.javaplayground.util.Validator; | ||
|
||
import java.util.*; | ||
|
||
public class NumberGenerator { | ||
private static final int MIN_NUMBER = 1; | ||
private static final int MAX_NUMBER = 9; | ||
|
||
private final Random random; | ||
|
||
public NumberGenerator() { | ||
this.random = new Random(); | ||
} | ||
|
||
public Numbers generateRandomNumber(int size) { | ||
Validator.validateListSize(size); | ||
return new Numbers(generateUniqueNumbers(size)); | ||
} | ||
|
||
private List<Integer> generateUniqueNumbers(int size) { | ||
Set<Integer> numberSet = new HashSet<>(); | ||
|
||
while (numberSet.size() < size) { | ||
numberSet.add(random.nextInt(MAX_NUMBER) + MIN_NUMBER); | ||
} | ||
|
||
return new ArrayList<>(numberSet); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
java-playground/src/main/java/org/gonza/javaplayground/core/Numbers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
import org.gonza.javaplayground.util.Validator; | ||
|
||
import java.util.List; | ||
|
||
public record Numbers(List<Integer> values) { | ||
public Numbers { | ||
Validator.validateListSize(values.size()); | ||
values = List.copyOf(values); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
java-playground/src/main/java/org/gonza/javaplayground/core/RuleConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.gonza.javaplayground.core; | ||
|
||
public final class RuleConstants { | ||
public static final int MIN_NUMBER = 1; | ||
public static final int MAX_NUMBER = 9; | ||
public static final int REQUIRED_LENGTH = 3; | ||
|
||
private RuleConstants() { | ||
throw new AssertionError("StringUtil 클래스는 인스턴스화 할 수 없습니다."); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
java-playground/src/main/java/org/gonza/javaplayground/util/Converter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.gonza.javaplayground.util; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class Converter { | ||
|
||
public static List<Integer> convertStringToNumberList(String input) { | ||
if (input == null || input.isEmpty()) { | ||
throw new IllegalArgumentException("입력값이 비어있습니다."); | ||
} | ||
|
||
Validator.validateNumeric(input); | ||
|
||
return input.chars() | ||
.map(Character::getNumericValue) | ||
.boxed() | ||
.collect(Collectors.toList()); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
숫자로 이루어진 문자열이 아닌 경우가 발생할 수 있지 않을까요?
작성자는 Validate에서 검증한다 인지할 수 있지만, 해당 함수만 봤을 때에는 오류의 가능성이 보여서요!
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.
해당 부분은 단순하게 숫자로 이루어진 문자열을 변환만 해주는 역할로 썼습니다!
그래서 호출하는 쪽 (사용자에게 입력 받는 부분)에서 이미 검증을 한 상태입니다. 그래서 말씀주신
숫자로된 문자열
형태가 아닐시 그 전에 예외가 터집니다!근데 현진님 말씀대로 이 안에서 한 번 더 검증하는 것도 맞는거 같습니다.