Skip to content
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# java-baseball-precourse
# java-baseball-precourse

## 1. View
1. 정답 추측: "숫자를 입력해주세요" 문구 출력 후 사용자 입력 받는 기능
2. 힌트: 입력받은 결과를 처리하여 힌트를 출력하는 기능
3. 게임 클리어: 클리어 문구 출력 후 다시하기 여부를 입력받는 기능

## 2. Validator
1. 추측 검증: 추측 정보를 검증하는 기능
2. 다시하기 검증: 다시 시작 정보를 검증하는 기능

## 3. GameService
1. 무작위 정답 숫자를 생성하는 새 게임 기능
2. 입력과 정답을 비교하여 결과를 반환하는 기능

## 4. Game
1. 실행: 위 기능들을 사용하여 게임의 전체적인 흐름을 관리하고 게임을 진행하는 기능
6 changes: 6 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
public class Application {

public static void main(String[] args) {
Game.start();
}
}
49 changes: 49 additions & 0 deletions src/main/java/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import java.util.InputMismatchException;

public class Game {

public static void start() {
Game game = new Game();
boolean flag = true;

while (flag) {
flag = game.play();
}

}

int answer;

public boolean play() {
answer = GameService.getNewAnswer();
int guess = 0;

while (answer != guess) {
try {
guess = View.guessView();
} catch (InputMismatchException e) {
throw new IllegalArgumentException("숫자를 입력해야합니다.");
} catch (Exception e) {
throw new IllegalArgumentException();
}

Validator.validateGuess(guess);
ResultDto resultDto = GameService.getResult(answer, guess);

View.hintView(resultDto);
}

int input;
try {
input = View.successView();
} catch (InputMismatchException e) {
throw new IllegalArgumentException("숫자를 입력해야 합니다.");
} catch (Exception e) {
throw new IllegalArgumentException();
}
Validator.validateReGame(input);

return input == 1;
}

}
40 changes: 40 additions & 0 deletions src/main/java/GameService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import java.util.Random;

public class GameService {

private GameService() {
}

public static int getNewAnswer() {
Random rand = new Random();
int num1 = rand.nextInt(9) + 1;
int num2 = rand.nextInt(9) + 1;
while (num1 == num2) {
num2 = rand.nextInt(9) + 1;
}
int num3 = rand.nextInt(9) + 1;
while (num3 == num1 || num3 == num2) {
num3 = rand.nextInt(9) + 1;
}

return num1 * 100 + num2 * 10 + num3;
}

public static ResultDto getResult(int answer, int guess) {
int strike = 0;
int ball = 0;
int[] answerArr = {answer / 100, (answer % 100) / 10, answer % 10};
int[] guessArr = {guess / 100, (guess % 100) / 10, guess % 10};

for (int i = 0; i < 3; i++) {
if (answerArr[i] == guessArr[i]) {
strike++;
} else if (guessArr[i] == answerArr[(i + 1) % 3] || guessArr[i] == answerArr[(i + 2)
% 3]) {
ball++;
}
}

return new ResultDto(strike, ball);
}
}
19 changes: 19 additions & 0 deletions src/main/java/ResultDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
public class ResultDto {

private final int strike;
private final int ball;

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


public int getStrike() {
return strike;
}

public int getBall() {
return ball;
}
}
20 changes: 20 additions & 0 deletions src/main/java/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
public class Validator {

private Validator() {}

public static void validateGuess(int num) {
if (num <= 100 || num >= 1000) {
throw new IllegalArgumentException("3자리 숫자를 입력해야 합니다.");
} else if (num/100 == (num%100)/10 || num/100 == num%10 || (num%100)/10 == num%10) {
throw new IllegalArgumentException("서로 다른 세 숫자를 입력해야 합니다.");
} else if ((num%100)/10 == 0 || num%10 == 0) {
throw new IllegalArgumentException("1부터 9까지의 숫자만 입력해야 합니다.");
}
}

public static void validateReGame(int num) {
if (num != 1 && num != 2) {
throw new IllegalArgumentException("1 또는 2를 입력해야 합니다.");
}
}
}
43 changes: 43 additions & 0 deletions src/main/java/View.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import java.io.InputStream;
import java.util.Scanner;

public class View {

private static Scanner sc = new Scanner(System.in);

private View() {}

public static int guessView() {
System.out.print("숫자를 입력해 주세요 : ");
int num = Integer.parseInt(sc.nextLine());
return num;
}

public static void hintView(ResultDto resultDto) {
int strike = resultDto.getStrike();
int ball = resultDto.getBall();

if (strike == 0 && ball == 0) {
System.out.println("낫싱");
} else if (strike == 0) {
System.out.println(ball + "볼");
} else if (ball == 0) {
System.out.println(strike + "스트라이크");
} else {
System.out.println(ball + "볼 " + strike + "스트라이크");
}
}

public static int successView() {
System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
int num = Integer.parseInt(sc.nextLine());
return num;
}

public static void resetScanner(InputStream inputStream) {
sc.close();
sc = new Scanner(inputStream);
}

}
22 changes: 22 additions & 0 deletions src/test/java/GameServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

class GameServiceTest {

@Test
void getNewAnswer() {
int answer = GameService.getNewAnswer();
Assertions.assertThatCode(() -> Validator.validateGuess(answer)).doesNotThrowAnyException();
}

@Test
void getResult() {
int answer = 123;
int guess = 135;

ResultDto resultDto = GameService.getResult(answer, guess);

Assertions.assertThat(resultDto.getBall()).isEqualTo(1);
Assertions.assertThat(resultDto.getStrike()).isEqualTo(1);
}
}
39 changes: 39 additions & 0 deletions src/test/java/ValidatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

class ValidatorTest {

@Test
void validateGuessSuccess() {
int guess = 123;
Assertions.assertThatCode(() -> Validator.validateGuess(guess)).doesNotThrowAnyException();
}

@Test
void validateGuessTwoDigit() {
int guess = 13;
Assertions.assertThatThrownBy(() -> Validator.validateGuess(guess))
.isInstanceOf(IllegalArgumentException.class);
}

@Test
void validateGuessSameDigit() {
int guess = 112;
Assertions.assertThatThrownBy(() -> Validator.validateGuess(guess))
.isInstanceOf(IllegalArgumentException.class);
}


@Test
void validateReGameSucess() {
int num = 1;
Assertions.assertThatCode(() -> Validator.validateReGame(num)).doesNotThrowAnyException();
}

@Test
void validateReGameFail() {
int num = 3;
Assertions.assertThatThrownBy(() -> Validator.validateReGame(num))
.isInstanceOf(IllegalArgumentException.class);
}
}
76 changes: 76 additions & 0 deletions src/test/java/ViewTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class ViewTest {

OutputStream out;

@BeforeEach
void beforeEach() {
out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
}

@Test
void guessView() {
InputStream in = new ByteArrayInputStream("123\n".getBytes());
View.resetScanner(in);

int num1 = View.guessView();

Assertions.assertThat(num1).isEqualTo(123);
}

@Test
void hintViewNothing() {
ResultDto resultDto = new ResultDto(0, 0);

View.hintView(resultDto);

Assertions.assertThat(out.toString().trim()).isEqualTo("낫싱");
}

@Test
void hintViewStrike() {
ResultDto resultDto = new ResultDto(2, 0);

View.hintView(resultDto);

Assertions.assertThat(out.toString().trim()).isEqualTo("2스트라이크");
}

@Test
void hintViewBall() {
ResultDto resultDto = new ResultDto(0, 3);

View.hintView(resultDto);

Assertions.assertThat(out.toString().trim()).isEqualTo("3볼");
}

@Test
void hintViewBoth() {
ResultDto resultDto = new ResultDto(1, 1);

View.hintView(resultDto);

Assertions.assertThat(out.toString().trim()).isEqualTo("1볼 1스트라이크");
}

@Test
void successView() {
InputStream in = new ByteArrayInputStream("1\n".getBytes());
View.resetScanner(in);

int num1 = View.guessView();

Assertions.assertThat(num1).isEqualTo(1);
}
}