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

[경북대 BE_권도윤] 미션 제출합니다. #151

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b4fbfbc
docs README.md: 기능 요구사항 목록 작성
doyooon May 5, 2024
3cd1fad
docs README.md: 테스트 목록 작성
doyooon May 5, 2024
e50b63b
feat BaseballGame: 컴퓨터가 1에서 9까지 서로 다른 임의의 수 3개를 선택
doyooon May 5, 2024
dfd2e6a
refactor BaseballGame: BaseBallGame에서 player와 constant로 역할 분리
doyooon May 5, 2024
5cbf448
feat Player: guess 가 들어왔을 때, ball 과 strike 개수를 확인해주는 checkMatching 기능 구현
doyooon May 5, 2024
8e5794d
feat BaseballGame: 입력받은 수와 비교하여 힌트 생성
doyooon May 5, 2024
7cc2141
feat BaseballGame: 사용자에게 수 입력받고, 힌트 출력하기
doyooon May 5, 2024
e2c2095
fix Player: 랜덤 숫자 생성시 10 미만으로 생성하도록 변경
doyooon May 5, 2024
78e1e84
feat Player: 사용자가 수를 맞췄을 때, 게임을 다시 할 건지 물어보기
doyooon May 5, 2024
83b565e
refactor: 숫자 입력 메세지 추가, 코드정리, 재시작시 잘못 입력하면 IllegalArgumentException 발생
doyooon May 5, 2024
e078e77
refactor BaseballGame: input 변수명 좀 더 명확하게 변경 - 추측 입력의 경우 inputNumber,…
doyooon May 5, 2024
3e522d6
docs README: IllegalArgumentException 조건 추가
doyooon May 5, 2024
aadce0f
feat BaseballGame: 사용자가 잘못된 값을 입력한 경우 `IllegalArgumentException` 발생시키기
doyooon May 5, 2024
f4db7cd
refactor: "BaseballGame" 호칭을 "Game" 으로 변경
doyooon May 5, 2024
72fbdbb
refactor Game Validation: Game class의 숫자 유효성 검증 부분 클래스로 옮김
doyooon May 5, 2024
b708ce5
refactor Game Validation: Game 클래스의 끝내는 명령 입력 받는 걸 검증하는 부분 Validation…
doyooon May 5, 2024
875870c
refactor Game: run, init, game 순으로 함수 순서 변경
doyooon May 5, 2024
a8c7b31
refactor Game Hint: Hint 출력을 Hint 클래스로 옮김
doyooon May 5, 2024
489e4b1
refactor constant: Constant class를 constant package로 옮김
doyooon May 5, 2024
a932c5c
refactor GameResult: GameResult를 data 패키지로 옮김
doyooon May 5, 2024
28c84d3
docs README: 테스트 목록에 종료 입력 테스트도 추가
doyooon May 5, 2024
6ad9f06
test Validation: 사용자가 잘못된 값을 입력한 경우 Validation Class 에서 검증 되는지 확인
doyooon May 6, 2024
4b959c2
test Hint: strike와 ball에 따라 적절한 Hint String을 반환하는지 확인
doyooon May 6, 2024
9a399dd
refactor Player: 랜덤 번호 생성 코드를 클래스로 따로 옮김
doyooon May 6, 2024
d876213
fix Game: End Command if문 조건 잘못된 부분 변경
doyooon May 6, 2024
608c81f
test RandomNumberGenerator: 랜덤 3자리수를 제대로 생성하는지 확인
doyooon May 6, 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
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
# java-baseball-precourse
# java-baseball-precourse

### 기능 요구사항 목록

- [x] 컴퓨터가 1에서 9까지 서로 다른 임의의 수 3개를 선택
- [x] 사용자에게 수 입력받기
- [x] 입력받은 수와 비교하여 힌트 생성
- [x] 스트라이크 : 같은 수가 같은 자리에 있을 때
- [x] 볼 : 같은 수가 다른 자리에 있을 때
- [x] 낫싱 : 같은 수가 전혀 없을 때
- [x] 힌트 출력하기
- [x] 사용자가 잘못된 값을 입력한 경우 `IllegalArgumentException` 발생시키기
- [x] 게임 종료후, 재시작을 물어볼 때 1, 2 외에 잘못한 값을 입력했을 때
- [x] 게임 중, 세자리 숫자를 잘못 입력 했을 때
- [x] 사용자가 수를 맞췄을 때, 게임을 다시 할 건지 물어보기

### 테스트 목록

- [x] 랜덤 3자리수를 생성하는지 확인
- [x] 3자리 숫자를 생성하는지 확인
- [x] 중복이 없는 숫자를 생성하는지 확인
- [x] 사용자가 잘못된 값을 입력한 경우 Validation Class 에서 검증 되는지 확인
- [x] 숫자가 아닌 값을 입력했을 때
- [x] 3자리가 아닌 숫자를 입력했을 때
- [x] 같은 숫자 여러개를 입력했을 때
- [x] 종료할 때, 1과 2 외에 다른 값을 입력했을 때
- [x] strike와 ball에 따라 적절한 Hint String을 반환하는지 확인
- [x] 스트라이크
- [x] 볼
- [x] 낫싱
7 changes: 7 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public class Application {

public static void main(String[] args) {
Game game = new Game();
game.run();
}
}
75 changes: 75 additions & 0 deletions src/main/java/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import constant.GameConstant;
import constant.GameMessageConstant;
import data.GameResult;
import java.util.Scanner;

public class Game {

Player computer;
boolean isEnd;

public void run() throws IllegalArgumentException {
Scanner scanner = new Scanner(System.in);
String inputCommand;
do {
game();
System.out.println(GameMessageConstant.GAME_RESTART_QUESTION);
inputCommand = scanner.next();
if (!Validation.checkEndCommand(inputCommand)) {
throw new IllegalArgumentException();
}
} while (Integer.parseInt(inputCommand) != GameConstant.END_GAME_NUMBER);
System.out.println(GameMessageConstant.GAME_END);
}

public void init() {
computer = new Player();
isEnd = false;
}

public void game() throws IllegalArgumentException {
init();
System.out.println(GameMessageConstant.START_GAME);
Scanner scanner = new Scanner(System.in);
String inputNumber;
GameResult result;
Hint hint;
do {
System.out.print(GameMessageConstant.INPUT_NUMBER);
inputNumber = scanner.next();
checkInputNumber(inputNumber);
result = getResult(inputNumber);
hint = new Hint(result);
System.out.println(hint.getHint());
} while (!isEnd);
System.out.println(GameMessageConstant.GAME_CLEAR);
}

private GameResult getResult(String inputNumber) {
GameResult result = computer.checkMatching(input2IntArray(inputNumber));
checkEnd(result);
return result;
}

private void checkInputNumber(String inputNumber) throws IllegalArgumentException {
if (!Validation.checkThreeDigitNumber(inputNumber) || !Validation.checkDuplicateNumber(
inputNumber)) {
throw new IllegalArgumentException();
}
}

private void checkEnd(GameResult result) {
if (result.strike() == GameConstant.NUMBER_COUNT) {
isEnd = true;
}
}

private int[] input2IntArray(String inputNumber) {
int[] guess = new int[GameConstant.NUMBER_COUNT];
for (int i = 0; i < GameConstant.NUMBER_COUNT; i++) {
guess[i] = Character.getNumericValue(inputNumber.charAt(i));
}
return guess;
}

}
38 changes: 38 additions & 0 deletions src/main/java/Hint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import constant.GameMessageConstant;
import data.GameResult;

public class Hint {

GameResult result;

public Hint(GameResult result) {
this.result = result;
}

public String getHint() {
if (result.ball() == 0 && result.strike() == 0) {
return GameMessageConstant.NOTHING;
}
if (result.ball() == 0) {
return strike2String(result.strike());
}
if (result.strike() == 0) {
return ball2String(result.ball());
}
return ball2String(result.ball()) + " " + strike2String(result.strike());
}

private String ball2String(int ball) {
if (ball > 0) {
return String.format("%d%s", ball, GameMessageConstant.BALL);
}
return "";
}

private String strike2String(int strike) {
if (strike > 0) {
return String.format("%d%s", strike, GameMessageConstant.STRIKE);
}
return "";
}
}
50 changes: 50 additions & 0 deletions src/main/java/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import constant.GameConstant;
import data.GameResult;
import java.util.HashSet;
import java.util.Set;

public class Player {

private int[] answer = new int[GameConstant.NUMBER_COUNT];
Set<Integer> numbers = new HashSet<>();

public Player() {
createRandomAnswer();
}

private void createRandomAnswer() {
answer = RandomNumberGenerator.generate(GameConstant.NUMBER_COUNT);
for (int i = 0; i < GameConstant.NUMBER_COUNT; i++) {
numbers.add(answer[i]);
}
}

public GameResult checkMatching(int[] guess) {
int ball = checkBall(guess);
int strike = checkStrike(guess);
return new GameResult(ball, strike);
}

private int checkBall(int[] guess) {
int count = 0;
for (int i = 0; i < GameConstant.NUMBER_COUNT; i++) {
if (answer[i] == guess[i]) {
continue;
}
if (numbers.contains(guess[i])) {
count++;
}
}
return count;
}

private int checkStrike(int[] guess) {
int count = 0;
for (int i = 0; i < GameConstant.NUMBER_COUNT; i++) {
if (answer[i] == guess[i]) {
count++;
}
}
return count;
}
}
25 changes: 25 additions & 0 deletions src/main/java/RandomNumberGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class RandomNumberGenerator {

public static int[] generate(int length) {
int[] result = new int[length];
Set<Integer> numbers = new HashSet<>();
while (numbers.size() < length) {
int number = createRandomNumber();
numbers.add(number);
}
int index = 0;
for (int number : numbers) {
result[index++] = number;
}
return result;
}

private static int createRandomNumber() {
Random random = new Random();
return random.nextInt(10);
}
}
31 changes: 31 additions & 0 deletions src/main/java/Validation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import constant.GameConstant;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

public final class Validation {

static final String TREE_DIGIT_REGEX = "^[0-9]{3}$";
static final String ONE_DIGIT_REGEX = "^[0-9]{1}$";

public static boolean checkThreeDigitNumber(String inputNumber) {
return Pattern.compile(TREE_DIGIT_REGEX).matcher(inputNumber).matches();
}

public static boolean checkDuplicateNumber(String inputNumber) {
Set<Character> chars = new HashSet<>();
for (char c : inputNumber.toCharArray()) {
chars.add(c);
}
return chars.size() == GameConstant.NUMBER_COUNT;
}

public static boolean checkEndCommand(String inputCommand) {
if (!Pattern.compile(ONE_DIGIT_REGEX).matcher(inputCommand).matches()) {
return false;
}
int command = Integer.parseInt(inputCommand);
return command == GameConstant.END_GAME_NUMBER
|| command == GameConstant.RESTART_GAME_NUMBER;
}
}
8 changes: 8 additions & 0 deletions src/main/java/constant/GameConstant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package constant;

public final class GameConstant {

public static final int NUMBER_COUNT = 3;
public static final int RESTART_GAME_NUMBER = 1;
public static final int END_GAME_NUMBER = 2;
}
16 changes: 16 additions & 0 deletions src/main/java/constant/GameMessageConstant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package constant;

public final class GameMessageConstant {

public static final String BALL = "볼";
public static final String STRIKE = "스트라이크";
public static final String NOTHING = "낫싱";
public static final String START_GAME = "숫자 야구 게임을 시작합니다. 제가 생각한 숫자를 맞춰보세요!\n";
public static final String INPUT_NUMBER = "숫자를 입력해주세요 : ";
public static final String GAME_CLEAR = String.format("%d개의 숫자를 정확히 맞히셨습니다! 축하드립니다.",
GameConstant.NUMBER_COUNT);
public static final String GAME_RESTART_QUESTION = String.format(
"게임을 새로 시작하려면 %d, 종료하려면 %d를 입력하세요.",
GameConstant.RESTART_GAME_NUMBER, GameConstant.END_GAME_NUMBER);
public static final String GAME_END = "게임을 종료합니다.";
}
5 changes: 5 additions & 0 deletions src/main/java/data/GameResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package data;

public record GameResult(int ball, int strike) {

}
38 changes: 38 additions & 0 deletions src/test/java/HintTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import constant.GameMessageConstant;
import data.GameResult;
import org.junit.jupiter.api.Test;

class HintTest {

@Test
void getHint_nothing() {
Hint hint = new Hint(new GameResult(0, 0));
assertEquals(hint.getHint(), GameMessageConstant.NOTHING);
}

@Test
void getHint_onlyBall() {
int ball = 1;
Hint hint = new Hint(new GameResult(ball, 0));
assertEquals(hint.getHint(), String.format("%d%s", ball, GameMessageConstant.BALL));
}

@Test
void getHint_onlyStrike() {
int strike = 3;
Hint hint = new Hint(new GameResult(0, strike));
assertEquals(hint.getHint(), String.format("%d%s", strike, GameMessageConstant.STRIKE));
}

@Test
void getHint_ballAndStrike() {
int ball = 1;
int strike = 1;
Hint hint = new Hint(new GameResult(ball, strike));
assertEquals(hint.getHint(),
String.format("%d%s %d%s", ball, GameMessageConstant.BALL, strike,
GameMessageConstant.STRIKE));
}
}
27 changes: 27 additions & 0 deletions src/test/java/RandomNumberGeneratorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.Test;

class RandomNumberGeneratorTest {

@Test
void generate_lengthCheck_true() {
int length = 3;
int[] result = RandomNumberGenerator.generate(length);
assertEquals(result.length, length);
}

@Test
void generate_duplicateCheck_true() {
int length = 3;
Set<Integer> numbers = new HashSet<>();
int[] result = RandomNumberGenerator.generate(length);
for (int i : result) {
numbers.add(i);
}
assertEquals(numbers.size(), length);
}

}
Loading