Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
74ce91e
feat: 콘솔 환경에서 유저 입력 핸들러 구성
LeeJuHwan Aug 22, 2024
dd102b0
feat: 콘솔 환경에서 어플리케이션 내용 출력 핸들러 구성
LeeJuHwan Aug 22, 2024
226ab87
chore: 어플리케이션 레벨 커스텀 Exception 생성
LeeJuHwan Aug 22, 2024
2c9309b
chore: 어플리케이션 진행을 위한 매직 넘버, 스트링 상수 클래스 생성
LeeJuHwan Aug 22, 2024
588ad94
feat: 플레이어 역할의 유저 도메인 구성
LeeJuHwan Aug 22, 2024
af248eb
feat: 플레이어의 입력 값 검증 시 점수 저장을 위한 스코어 도메인 구성
LeeJuHwan Aug 22, 2024
2a7ad63
feat: 플레이어의 정답과 비교 할 대상 컴퓨터 도메인 구성
LeeJuHwan Aug 22, 2024
38017b4
feat: 플레이어의 행동을 점수로 기록 할 심판 도메인 구성
LeeJuHwan Aug 22, 2024
de9e110
feat: 메인 어플리케이션 인터페이스 생성
LeeJuHwan Aug 22, 2024
413519c
feat: 숫자 야구게임 어플리케이션 구현
LeeJuHwan Aug 22, 2024
c61f9a7
feat: 메인 어플리케이션 레벨 실행 함수 구성
LeeJuHwan Aug 22, 2024
8bd1ec9
update: change multi line to one-line
LeeJuHwan Aug 22, 2024
67ac759
update: change the method names
LeeJuHwan Aug 22, 2024
44f0bad
refactor: 스코어 객체의 매직 스트링 상수 추출
LeeJuHwan Aug 23, 2024
db0f077
refactor: 스코어 객체의 결과 값 출력 대신 반환으로 변경
LeeJuHwan Aug 23, 2024
f0eccc5
update: 출력 핸들러 사용자 메세지 인스턴스 메서드로 변경
LeeJuHwan Aug 23, 2024
853a13d
update: 컴퓨터 객체의 난수 생성 메서드를 게임과 관련된 메서드로 명칭 변경
LeeJuHwan Aug 23, 2024
cf30776
refactor: 심판 객체의 결과 판정 메서드 출력 위치 변경
LeeJuHwan Aug 23, 2024
c682dc0
update: 스코어 객체 초기화 메서드 래핑 및 명칭 변경
LeeJuHwan Aug 23, 2024
66882e1
refactor: 게임 클래스 다형성 유지
LeeJuHwan Aug 23, 2024
8f00b97
update: 메서드 시그니처의 불분명한 파라미터 명칭 변경
LeeJuHwan Aug 23, 2024
133bcdf
refactor: 메인 어플리케이션 레벨에서 게임 실행 도우미 메서드 제거
LeeJuHwan Aug 23, 2024
6c0ed04
update: 어플리케이션 인터페이스 메서드 축소
LeeJuHwan Aug 23, 2024
03da346
update: 직관적인 네이밍으로 변경
LeeJuHwan Aug 23, 2024
9850d24
refactor: 불필요한 반복 구조 제거
LeeJuHwan Aug 23, 2024
c6f3658
chore: 출력 핸들러 정적 메서드 축소
LeeJuHwan Aug 23, 2024
5d9f09e
feat: 점수 객체의 카운트 증가 메서드 예외 처리 추가
LeeJuHwan Aug 26, 2024
1ee19ae
feat: 랜덤 난수 생성 시 설정 값 상수 추출
LeeJuHwan Aug 26, 2024
d7a47a1
refactor: 테스트를 고려하여 심판 객체의 메서드 시그니처 변경
LeeJuHwan Aug 26, 2024
d15062c
update: 컴퓨터 객체 클래스 변수 레벨로 위치 변경
LeeJuHwan Aug 26, 2024
48df0ef
fix: 게임 재실행 시 문구 내용 포함 및 난수 재생성
LeeJuHwan Aug 26, 2024
56f7857
test: 심판 도메인 단위 테스트
LeeJuHwan Aug 26, 2024
01ec918
test: 점수 도메인 단위 테스트
LeeJuHwan Aug 26, 2024
2782287
update: 불명확한 메서드 명 수정
LeeJuHwan Aug 26, 2024
0655846
test: 유저 도메인 단위 테스트 구현
LeeJuHwan Aug 26, 2024
82b962b
chore: mocking dependency 추가
LeeJuHwan Aug 27, 2024
aed9f79
update: 컴퓨터 객체 생성 시 랜덤 생성자 의존성 주입
LeeJuHwan Aug 27, 2024
09c884f
update: 배열에 값 추가하는 메서드 추출
LeeJuHwan Aug 27, 2024
dd1fd37
feat: 랜덤 유틸 클래스 생성
LeeJuHwan Aug 27, 2024
c5653fb
test: 컴퓨터 도메인 단위 테스트 구현
LeeJuHwan Aug 27, 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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repositories {
dependencies {
testImplementation "org.junit.jupiter:junit-jupiter:5.7.2"
testImplementation "org.assertj:assertj-core:3.19.0"
testImplementation "org.mockito:mockito-junit-jupiter:5.2.0"
}

test {
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import app.BaseballApplication;
import base.Application;
import io.OutputHandler;

public class Main {

public static void main(String[] args) {
Application baseballApplication = new BaseballApplication();
try {
baseballApplication.startGame();
} catch (Exception e) {
OutputHandler.printDefaultExceptionMessage(e);
}
}
}
113 changes: 113 additions & 0 deletions src/main/java/app/BaseballApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package app;

import base.Application;
import domain.Computer;
import domain.Judgment;
import domain.Score;
import domain.User;
import io.InputHandler;
import io.OutputHandler;
import java.util.ArrayList;
import core.AppException;
import util.RandomGenerator;

import static core.SystemConstant.*;


public class BaseballApplication implements Application {

private final Computer computer = new Computer(new RandomGenerator());
private final InputHandler inputHandler = new InputHandler();
private final OutputHandler outputHandler = new OutputHandler();


public void startGame() {
boolean isGameRunning = true;

while (isGameRunning) {
Judgment judgment = readyToGame();
outputHandler.gameStartCommentPrint();
run(judgment);

isGameRunning = pauseForUserGameRunOptionSelect();
}
}

private String userSelectGameRestartOrStop() {
outputHandler.gameEndCommentPrint();
return inputHandler.getUserInput();
}

private boolean isGameRestart(String gameFlag) {
return GAME_RESTART_FLAG.equals(gameFlag);
}

private boolean isGameStop(String gameFlag) {
return GAME_STOP_FLAG.equals(gameFlag);
}

private void run(Judgment judgment) {
try {
actionToGameStartByJudgement(judgment);

} catch (AppException e) {
outputHandler.printAppExceptionMessage(e);

run(judgment);
}
}

private boolean pauseForUserGameRunOptionSelect() {
try {
String gameFlag = userSelectGameRestartOrStop();

return isGameContinue(gameFlag);

} catch (AppException e) {
outputHandler.printAppExceptionMessage(e);
return pauseForUserGameRunOptionSelect();
}
}

private boolean isGameContinue(String gameFlag) {
if (isGameRestart(gameFlag)) {
return true;
}

if (isGameStop(gameFlag)) {
return false;
}

throw new AppException("게임 시작 명령어를 잘못 입력 하였습니다.");
}

private void actionToGameStartByJudgement(Judgment judgment) {
String userInputValue = userInput();
User user = new User(userInputValue);
ArrayList<String> getUserInputArrayStringNumbers = user.getUserInputNumbers();

Score score = judgment.judge(getUserInputArrayStringNumbers);

String scoreResultMessage = score.getScoreRecordResult();
outputHandler.printMessage(scoreResultMessage);

boolean isGameSet = score.isStrikeCountEqualToWinningStrikeCount();

if (stillGameRunning(isGameSet)) {
actionToGameStartByJudgement(judgment);
}
}

private boolean stillGameRunning(boolean isGameSet) {
return !isGameSet;
}

private String userInput() {
outputHandler.questionToUserAboutInputNumber();
return inputHandler.getUserInput();
}

private Judgment readyToGame() {
return new Judgment(computer.readyToGameStart());
}
}
6 changes: 6 additions & 0 deletions src/main/java/base/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package base;

public interface Application {

void startGame();
}
8 changes: 8 additions & 0 deletions src/main/java/core/AppException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core;

public class AppException extends RuntimeException {

public AppException(String message) {
super(message);
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/SystemConstant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core;

public class SystemConstant {
public static final int INPUT_LIMIT_LENGTH = 3;
public static final int WINNING_STRIKE_COUNT = 3;
public static final String GAME_STOP_FLAG = "2";
public static final String GAME_RESTART_FLAG = "1";

}
41 changes: 41 additions & 0 deletions src/main/java/domain/Computer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package domain;

import static core.SystemConstant.*;
import java.util.ArrayList;
import util.RandomGenerator;

public class Computer {

public static final int BOUND = 9;
private final RandomGenerator randomGenerator;
private final ArrayList<String> randomNumbers = new ArrayList<>();

public Computer(RandomGenerator randomGenerator) {
this.randomGenerator = randomGenerator;
}

public ArrayList<String> readyToGameStart() {

if (isGenerateRandomNumberSizeEqualToLimit()) {
return randomNumbers;
}
String number = randomGenerator.getRandomNumberToString(BOUND);

if (doesNotDuplicate(number)) {
append(number);
}
return readyToGameStart();
}

private void append(String number) {
randomNumbers.add(number);
}

private boolean isGenerateRandomNumberSizeEqualToLimit() {
return randomNumbers.size() == INPUT_LIMIT_LENGTH;
}

private boolean doesNotDuplicate(String compareInteger) {
return !randomNumbers.contains(compareInteger);
}
}
46 changes: 46 additions & 0 deletions src/main/java/domain/Judgment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package domain;

import java.util.ArrayList;

public class Judgment {

private final Score score = new Score();
private final ArrayList<String> computerRandomNumbers;


public Judgment(ArrayList<String> computerRandomNumbers) {
this.computerRandomNumbers = computerRandomNumbers;
}

public Score judge(ArrayList<String> userInputNumbers) {
newScore();

for (int seq = 0; seq < userInputNumbers.size(); seq++) {
scoreRecord(userInputNumbers, seq);
}
return score;
}

private void newScore() {
score.clean();
}

private void scoreRecord(ArrayList<String> userInputNumbers, int arrayInPosition) {
if (isStrike(userInputNumbers, arrayInPosition)) {
score.strikeIncrement();
return;
}

if (isBall(userInputNumbers, arrayInPosition)) {
score.ballIncrement();
}
}

private boolean isBall(ArrayList<String> userInputNumbers, int arrayInPosition) {
return computerRandomNumbers.contains(userInputNumbers.get(arrayInPosition));
}

private boolean isStrike(ArrayList<String> userInputNumbers, int arrayInPosition) {
return computerRandomNumbers.get(arrayInPosition).equals(userInputNumbers.get(arrayInPosition));
}
}
68 changes: 68 additions & 0 deletions src/main/java/domain/Score.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package domain;

import static core.SystemConstant.*;

import core.AppException;

public class Score {

private int strikeCount;
private int ballCount;

private static final String BALL_MESSAGE = "볼";
private static final String STRIKE_MESSAGE = "스트라이크";
private static final String UN_HANDLE_MESSAGE = "낫싱";

void clean() {
this.strikeCount = 0;
this.ballCount = 0;
}

public void strikeIncrement() {
if (strikeCount + 1 > WINNING_STRIKE_COUNT) {
throw new AppException("스트라이크 카운트는 최대 " + WINNING_STRIKE_COUNT + "까지 증가할 수 있습니다.");
}
this.strikeCount += 1;
}

public void ballIncrement() {
if (ballCount + 1 > WINNING_STRIKE_COUNT) {
throw new AppException("볼 카운트는 최대 " + WINNING_STRIKE_COUNT + "까지 증가할 수 있습니다.");
}

this.ballCount += 1;
}

public String getScoreRecordResult() {
if (isBallAndStrike()) {
return ballCount + BALL_MESSAGE + " " + strikeCount + STRIKE_MESSAGE;
}

if (isOnlyBall()) {
return ballCount + BALL_MESSAGE;
}

if (isOnlyStrike()) {
return strikeCount + STRIKE_MESSAGE;
}

return UN_HANDLE_MESSAGE;
}

private boolean isOnlyStrike() {
return strikeCount > 0;
}

private boolean isOnlyBall() {
return ballCount > 0;
}

private boolean isBallAndStrike() {
return ballCount > 0 && strikeCount > 0;
}

public boolean isStrikeCountEqualToWinningStrikeCount() {
return strikeCount == WINNING_STRIKE_COUNT;
}

}
56 changes: 56 additions & 0 deletions src/main/java/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package domain;


import static core.SystemConstant.*;

import java.util.ArrayList;
import java.util.Arrays;
import core.AppException;

public class User {

private final static int NUMBER_LIMIT_LENGTH = INPUT_LIMIT_LENGTH;
private final ArrayList<String> userInputNumbers;

public User(String userInputNumber) {
if (invalidLengthUserInputNumber(userInputNumber)) {
throw new AppException("입력한 숫자의 길이가 올바르지 않습니다.");
}

if (doesNotNumeric(userInputNumber)) {
throw new AppException("지정 되지 않은 타입의 입력입니다.");
}

this.userInputNumbers = convertStringToArrayList(userInputNumber);

if (hasZeroNumber()) {
throw new AppException("0은 입력 할 수 없습니다.");
}

}

public ArrayList<String> getUserInputNumbers() {
return userInputNumbers;
}

private static ArrayList<String> convertStringToArrayList(String userInput) {
return new ArrayList<>(Arrays.asList(userInput.split("")));
}

private boolean hasZeroNumber() {
return this.userInputNumbers.contains("0");
}

private boolean doesNotNumeric(String userInput) {
try {
Integer.valueOf(userInput);
return false;
} catch (Exception e) {
return true;
}
}

private boolean invalidLengthUserInputNumber(String userInput) {
return !(userInput.length() == NUMBER_LIMIT_LENGTH);
}
}
12 changes: 12 additions & 0 deletions src/main/java/io/InputHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io;

import java.util.Scanner;

public class InputHandler {

private static final Scanner SCANNER = new Scanner(System.in);

public String getUserInput() {
return SCANNER.nextLine();
}
}
Loading