Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,14 @@

## 과제 제출 과정
* [과제 제출 방법](https://github.com/next-step/nextstep-docs/tree/master/ent-precourse)

## 구현할 기능 목록
- [x] 숫자 입력
- [x] 입력값 검증 (1 ~ 9 사이의 숫자 3개)
- [x] 값 Parsing ("234" => [2, 3, 4])
- [x] 랜덤 숫자 생성
- [x] 값 비교 ([2, 3, 4] vs [4, 5, 6] => 1개 겹침)
- [x] 결과 판단 (1 => 1 스트라이크 2 볼)
- [x] 결과 출력
- [x] 게임 반복 진행 가능
- [ ] 테스트 구현
20 changes: 20 additions & 0 deletions src/main/java/study/baseball/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package study.baseball;

import java.util.regex.Pattern;
import study.baseball.engine.Baseball;
import study.baseball.engine.InputParser;
import study.baseball.engine.InputValidator;
import study.baseball.engine.NumberGenerator;

public class App {
public static void main(String[] args) {
Console console = new Console();
Pattern regex = Pattern.compile("[0-9]{3}");
InputValidator validator = new InputValidator(regex);
InputParser parser = new InputParser();
NumberGenerator numberGenerator = new NumberGenerator();
Baseball baseball = new Baseball(console, validator, parser, numberGenerator);

baseball.run();
}
}
25 changes: 25 additions & 0 deletions src/main/java/study/baseball/Console.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package study.baseball;

import java.util.Scanner;
import study.baseball.engine.io.Input;
import study.baseball.engine.io.Output;

public class Console implements Input, Output {
private final Scanner scanner = new Scanner(System.in);

@Override
public String input(String message) {
System.out.print(message);
return scanner.nextLine();
}

@Override
public void printError(String message) {
System.out.println("[ERROR] : " + message);
}

@Override
public void printOutput(String message) {
System.out.println(message);
}
}
80 changes: 80 additions & 0 deletions src/main/java/study/baseball/engine/Baseball.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package study.baseball.engine;

import java.util.List;
import study.baseball.Console;
import study.baseball.engine.model.BallCount;
import study.baseball.engine.model.Numbers;

public class Baseball implements Runnable {
private final Console console;
private final InputValidator validator;
private final InputParser parser;
private final NumberGenerator numberGenerator;

public Baseball(Console console, InputValidator inputValidator, InputParser inputParser,
NumberGenerator numberGenerator) {
this.console = console;
this.validator = inputValidator;
this.parser = inputParser;
this.numberGenerator = numberGenerator;
}

@Override
public void run() {
while (true) {
Numbers answer = numberGenerator.generateRandomNumber();
while (saveGame(answer))
;
if (askContinue()) {
continue;
}
break;
}
}

private boolean saveGame(Numbers answer) {
try {
return proceedGame(answer);
} catch (RuntimeException exception) {
console.printError(exception.getMessage());
return true;
}
}

private boolean proceedGame(Numbers answer) {
String input = console.input("숫자를 입력해주세요 : ");
validator.checkValidFormat(input);
List<Integer> parsedInput = parser.parseStringToIntegerList(input);
BallCount result = new BallCount(answer.getStrike(parsedInput), answer.getBall(parsedInput));
if (result.getStrike() == 3) {
console.printOutput("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
return false;
}
showResult(result);
return true;
}

private boolean askContinue() {
while (true) {
String input = console.input("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.\n");
if (input.equals("1")) {
return true;
}
if (input.equals("2")) {
return false;
}
console.printError("잘못된 입력입니다.");
}
}

private void showResult(BallCount ballCount) {
StringBuilder output = new StringBuilder();
if (ballCount.getStrike() > 0) {
output.append(ballCount.getStrike()).append(" 스트라이크 ");
}
if (ballCount.getBall() > 0) {
output.append(ballCount.getBall()).append(" 볼 ");
}
console.printOutput(output.toString().length() > 0 ? output.toString() : "낫싱");
}
}
20 changes: 20 additions & 0 deletions src/main/java/study/baseball/engine/InputParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package study.baseball.engine;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class InputParser {
public List<Integer> parseStringToIntegerList(String input) {
String[] inputArray = input.split("");
Set<Integer> result = new LinkedHashSet<>();
for (String number : inputArray) {
result.add(Integer.parseInt(number));
}
if (result.size() < 3) {
throw new RuntimeException("중복된 숫자가 존재합니다.");
}
return new ArrayList<>(result);
}
}
19 changes: 19 additions & 0 deletions src/main/java/study/baseball/engine/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package study.baseball.engine;

import java.util.regex.Pattern;

public class InputValidator {

private final Pattern regex;

public InputValidator(Pattern regex) {
this.regex = regex;
}

public boolean checkValidFormat(String input) {
if (!regex.matcher(input).matches()) {
throw new RuntimeException("입력의 형식이 잘못되었습니다.");
}
return true;
}
}
18 changes: 18 additions & 0 deletions src/main/java/study/baseball/engine/NumberGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package study.baseball.engine;

import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;
import study.baseball.engine.model.Numbers;

public class NumberGenerator {
private final Random random = new Random();

public Numbers generateRandomNumber() {
Set<Integer> randomNumbers = new LinkedHashSet<>();
while (randomNumbers.size() < 3) {
randomNumbers.add(random.nextInt(10));
}
return new Numbers(randomNumbers);
}
}
5 changes: 5 additions & 0 deletions src/main/java/study/baseball/engine/io/Input.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package study.baseball.engine.io;

public interface Input {
String input(String s);
}
7 changes: 7 additions & 0 deletions src/main/java/study/baseball/engine/io/Output.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package study.baseball.engine.io;

public interface Output {
void printError(String s);

void printOutput(String s);
}
19 changes: 19 additions & 0 deletions src/main/java/study/baseball/engine/model/BallCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package study.baseball.engine.model;

public class BallCount {
private int strike;
private int ball;

public BallCount(int strike, int ball) {
this.strike = strike;
this.ball = ball;
}

public int getStrike() {
return strike;
}

public int getBall() {
return ball;
}
}
39 changes: 39 additions & 0 deletions src/main/java/study/baseball/engine/model/Numbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package study.baseball.engine.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

public class Numbers {

private final List<Integer> numbers;

public Numbers(Set<Integer> numbers) {
this.numbers = new ArrayList<>(numbers);
}

public List<Integer> getNumbers() {
return numbers;
}

public Integer getBall(List<Integer> input) {
Set<Integer> sum = new HashSet<>(input);
sum.addAll(numbers);
return input.size() + numbers.size() - sum.size() - getStrike(input);
}

public Integer getStrike(List<Integer> input) {
Iterator<Integer> numbersIterator = numbers.iterator();
int index = 0;
int strike = 0;
while (numbersIterator.hasNext()) {
if (Objects.equals(numbersIterator.next(), input.get(index++))) {
strike++;
}
}
return strike;
}
}
27 changes: 27 additions & 0 deletions src/test/java/study/baseball/engine/InputParserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package study.baseball.engine;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.util.List;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class InputParserTest {
private final InputParser parser = new InputParser();

@ParameterizedTest
@ValueSource(strings = {"123", "076", "234", "543", "932"})
public void testParseValidInput(String input) {
List<Integer> numbers = parser.parseStringToIntegerList(input);
assertThat(numbers).hasSize(3);
}

@ParameterizedTest
@ValueSource(strings = {"777", "112", "911", "707"})
public void testParseDuplicatedInput(String input) {
assertThatThrownBy(() -> {
List<Integer> numbers = parser.parseStringToIntegerList(input);
}).isInstanceOf(RuntimeException.class).hasMessage("중복된 숫자가 존재합니다.");
}
}
27 changes: 27 additions & 0 deletions src/test/java/study/baseball/engine/InputValidatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package study.baseball.engine;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.util.regex.Pattern;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class InputValidatorTest {
Pattern regex = Pattern.compile("[0-9]{3}");
private final InputValidator validator = new InputValidator(regex);

@ParameterizedTest
@ValueSource(strings = {"123", "076", "234", "543", "932"})
public void testValidInput(String input) {
assertThat(validator.checkValidFormat(input)).isTrue();
}

@ParameterizedTest
@ValueSource(strings = {"321312", "", " ", "dsfjasdflk", "fdf dfd !@#!@ d"})
public void testInvalidFormatInput(String input) {
assertThatThrownBy(() -> {
validator.checkValidFormat(input);
}).isInstanceOf(RuntimeException.class).hasMessage("입력의 형식이 잘못되었습니다.");
}
}
21 changes: 21 additions & 0 deletions src/test/java/study/baseball/engine/NumberGeneratorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package study.baseball.engine;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import study.baseball.engine.model.Numbers;

class NumberGeneratorTest {
private final NumberGenerator numberGenerator = new NumberGenerator();

@Test
public void testGenerateRandomNumbers() {
for (int i = 0; i < 10; i++) {
Numbers random = numberGenerator.generateRandomNumber();
assertThat(random.getNumbers()).hasSize(3);
for (Integer integer : random.getNumbers()) {
assertThat(integer).isLessThan(10).isGreaterThanOrEqualTo(0);
}
}
}
}
Loading