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

[숫자야구게임] 김준서 미션 제출합니다. #340

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c1a59da
docs: 구현해야 하는 기능 목록 작성
Nov 30, 2020
0c4404f
feat: 컴퓨터가 3자리의 랜덤 값 생성
Nov 30, 2020
ca41834
feat: 사용자에게 3자리 숫자 입력받기
Nov 30, 2020
e8b9eb7
feat: 올바른 입력이 들어온 경우 유저 숫자 저장
Nov 30, 2020
a395663
feat: 유저의 입력이 숫자인지 확인
Nov 30, 2020
fa21cc8
feat: 유저의 입력이 올바른 길이(3)를 가지는 지 확인
Nov 30, 2020
d326562
feat: 유저의 입력이 중복되는 숫자를 가지는지 확인
Nov 30, 2020
842f43d
feat: 유저의 입력이 1 ~ 9 사이의 숫자로만 이루어져있는지 확인
Nov 30, 2020
29dc4ac
feat: Hint 클래스 생성
Nov 30, 2020
f21d783
feat: 정답과 유저의 입력값을 비교
Nov 30, 2020
9d3383d
feat: strike 수 세기
Nov 30, 2020
82000b6
feat: ball 수 세기
Nov 30, 2020
011c8d6
feat: Hint 결과 출력
Nov 30, 2020
31fccca
feat: strike 개수 가져오기
Nov 30, 2020
20d62d3
refactor: strike & ball 개수 세기 전 초기화해주기
Nov 30, 2020
265fbed
feat: 실제로 게임을 진행시키는 클래스 생성
Nov 30, 2020
6b8bfd4
feat: 게임 진행하는 메소드
Nov 30, 2020
7d5995a
feat: 게임 종료시 재시작 여부를 처리하는 메소드
Nov 30, 2020
c5bb322
refactor: 유저에게 3자리 수를 입력받을 때 next()로 수정
Nov 30, 2020
f27d4d9
refactor: Constant 클래스로 상수 관리
Nov 30, 2020
d104cbb
refactor: 잘못된 입력이 들어왔을때 Exception을 Constant 클래스로 관리
Nov 30, 2020
ba0cf3a
refactor: 사용자 입력이 1 ~ 9까지 범위의 수인지 확인할 때 Constant 클래스로 관리
Nov 30, 2020
798d97e
refactor: hint 출력을 Constant 클래스로 관리
Nov 30, 2020
cdacdb7
refactor: 컴퓨터가 정답 생성하는 기능을 메소드로 분리
Dec 1, 2020
3582a4e
refactor: Computer 클래스의 지역변수 private 으로 변경 & getter 추가
Dec 1, 2020
9acf10d
refactor: 사용자의 입력 변수를 private으로 변경 & getter 추가
Dec 1, 2020
0a44910
refactor: 유저 입력의 타당성 검사를 Validation 클래스로 분리
Dec 1, 2020
fb69dad
refactor: hint 초기화 중복부분 삭제
Dec 1, 2020
45fbfe4
refactor: hint 지역변수 private으로 변경
Dec 1, 2020
8cdf435
style: formatting 수정
Dec 1, 2020
dd04acc
style: formatting 수정
Dec 1, 2020
70b8f26
feat: 종료 메세지 추가
Dec 1, 2020
ce60db8
style: 변수 명 변경
Dec 1, 2020
0dd9cde
style: formatting 수정
Dec 1, 2020
8b0e076
style: 게임을 진행하는 클래스 이름 변경
Dec 1, 2020
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
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# 미션 - 숫자 야구 게임

## 구현해야 하는 기능 목록

### 힌트 설명
- 스트라이크
3자리의 랜덤 수와 사용자가 입력한 3자리의 수 중 위치와 수가 모두 같은 경우
- 볼
3자리의 랜덤 수와 사용자가 입력한 3자리의 수 중 위치는 다르지만 수가 같은 경우
- 낫싱
3자리의 랜덤 수와 사용자가 입력한 3자리의 수가 모두 다른 경우

### 게임 진행
- 게임은 '랜덤 값 생성 -> 입력 -> 결과 확인' 과정을 거친다.

#### 랜덤 값 생성
- 컴퓨터가 임의의 3자리의 랜덤 수 생성
- 각 자리는 1 ~ 9까지의 수로 이루어져 있다.
- 각 자리는 서로 다른 수로 이루어져 있다.
- 3자리 수보다 적거나 많은 자리의 수는 허용되지 않는다.

#### 입력
- 사용자에게 3자리의 수 입력받기
- 각 자리는 1 ~ 9까지의 수로 입력받아야 한다.
- 각 자리는 서로 다른 수로 입력받아야 한다.
- 3자리 수보다 적거나 많은 자리의 수는 허용되지 않는다.

#### 결과 확인
- 사용자의 입력과 컴퓨터가 생성한 수를 비교하여 힌트 출력
- 승리
- 3 스트라이크 발생
- 새로운 게임 시작(1), 게임 종료(2)를 선택하게 된다.
- 계속 진행
- 승리하지 않은 경우 '입력'으로 다시 돌아간다.

<br>

## 🚀 기능 요구사항
- 이 게임은 프로그램이 1에서 9까지 서로 다른 임의의 수 3개를 정하고 이를 플레이어가 맞추는 게임이다.
- 정답을 맞추기 위해 3자리수를 입력하고 힌트를 받는다.
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/baseball/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
public class Application {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO 구현 진행

BaseballGame baseballGame = new BaseballGame(scanner);
baseballGame.start();
}
}
55 changes: 55 additions & 0 deletions src/main/java/baseball/BaseballGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package baseball;

import java.util.Scanner;

public class BaseballGame {
private Computer computer;
private User user;
private Hint hint;
private boolean running;
private Scanner scanner;

public BaseballGame(Scanner scanner) {
this.computer = new Computer();
this.user = new User();
this.hint = new Hint();
this.running = true;
this.scanner = scanner;
}

public void start() {
do {
computer.generateAnswer();
startGame();
} while (isRestart());
}

private void startGame() {
while (running) {
user.enterNumber(scanner);
hint.countHint(computer.getAnswer(), user.getUserNumber());
hint.printResult();

if (hint.getStrike() == Constant.VICTORY_CONDITION) {
System.out.println(Constant.VICTORY_MESSAGE);
running = false;
}
}
}

private boolean isRestart() {
System.out.println(Constant.RESTART_MESSAGE);

int restart = scanner.nextInt();

if (restart == Constant.RESTART) {
this.running = true;
return true;
} else if (restart == Constant.EXIT) {
System.out.println(Constant.EXIT_MESSAGE);
return false;
} else {
throw new IllegalArgumentException(Constant.WRONG_INPUT);
}
}
}
25 changes: 25 additions & 0 deletions src/main/java/baseball/Computer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package baseball;

import utils.RandomUtils;

public class Computer {
private int[] answer = new int[Constant.NUMBER_LENGTH];
private boolean[] alreadyUse = new boolean[Constant.MAX_VALUE + 1];

public void generateAnswer() {
for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
int number = RandomUtils.nextInt(Constant.MIN_VALUE, Constant.MAX_VALUE);

if (!alreadyUse[number]) {
alreadyUse[number] = true;
answer[i] = number;
} else {
i--;
}
}
}

public int[] getAnswer() {
return this.answer;
}
}
22 changes: 22 additions & 0 deletions src/main/java/baseball/Constant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package baseball;

public class Constant {
public static final int NUMBER_LENGTH = 3;
public static final int MIN_VALUE = 1;
public static final int MAX_VALUE = 9;

public static final int RESTART = 1;
public static final int EXIT = 2;
public static final int VICTORY_CONDITION = 3;

public static final String INPUT_MESSAGE = "숫자를 입력해주세요 : ";
public static final String VICTORY_MESSAGE = "3개의 숫자를 모두 맞히셨습니다! 게임 종료";
public static final String RESTART_MESSAGE = "게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.";
public static final String EXIT_MESSAGE = "게임이 종료되었습니다.";

public static final String STRIKE = "스트라이크 ";
public static final String BALL = "볼 ";
public static final String NOTHING = "낫싱";

public static final String WRONG_INPUT = "잘못된 입력입니다.";
}
51 changes: 51 additions & 0 deletions src/main/java/baseball/Hint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package baseball;

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

public void countHint(int[] answer, int[] userNumber) {
initCount();

for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
countStrike(answer[i], userNumber[i]);
countBall(answer, userNumber[i], i);
}
}

private void initCount() {
this.strike = 0;
this.ball = 0;
}

private void countStrike(int computer, int user) {
if (computer == user) {
this.strike++;
}
}

private void countBall(int[] answer, int user, int userIdx) {
for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
if (i != userIdx && answer[i] == user) {
this.ball++;
}
}
}

public void printResult() {
if (this.ball > 0) {
System.out.print(this.ball + Constant.BALL);
}
if (this.strike > 0) {
System.out.print(this.strike + Constant.STRIKE);
}
if (this.ball == 0 && this.strike == 0) {
System.out.print(Constant.NOTHING);
}
System.out.println();
}

public int getStrike() {
return this.strike;
}
}
31 changes: 31 additions & 0 deletions src/main/java/baseball/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package baseball;

import java.util.Scanner;

public class User {
private int[] userNumber = new int[Constant.NUMBER_LENGTH];

public void enterNumber(Scanner scanner) {
System.out.println(Constant.INPUT_MESSAGE);

String number = scanner.next();

if (Validation.isValidInput(number)) {
setUserNumber(number);
} else {
throw new IllegalArgumentException(Constant.WRONG_INPUT);
}
}

public int[] getUserNumber() {
return this.userNumber;
}

private void setUserNumber(String number) {
for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
int eachNum = Character.getNumericValue(number.charAt(i));

userNumber[i] = eachNum;
}
}
}
52 changes: 52 additions & 0 deletions src/main/java/baseball/Validation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package baseball;

public class Validation {
public static boolean isValidInput(String number) {
return isNumber(number) && isRightLength(number)
&& isNotDuplicate(number) && isRightRange(number);
}

private static boolean isNumber(String number) {
for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
char eachDigit = number.charAt(i);

if (!Character.isDigit(eachDigit)) {
return false;
}
}

return true;
}

private static boolean isRightLength(String number) {
return number.length() == Constant.NUMBER_LENGTH;
}

private static boolean isNotDuplicate(String number) {
boolean[] alreadyUse = new boolean[Constant.MAX_VALUE + 1];

for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
int eachDigit = Character.getNumericValue(number.charAt(i));

if (!alreadyUse[eachDigit]) {
alreadyUse[eachDigit] = true;
} else {
return false;
}
}

return true;
}

private static boolean isRightRange(String number) {
for (int i = 0; i < Constant.NUMBER_LENGTH; i++) {
int eachDigit = Character.getNumericValue(number.charAt(i));

if (eachDigit < Constant.MIN_VALUE || eachDigit > Constant.MAX_VALUE) {
return false;
}
}

return true;
}
}