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

gene.y #47

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
HELP.md
.gradle
build/
bin/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**
!**/src/test/**
Expand Down
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,74 @@

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


## 기능 목록


### 1. GameRule : 숫자야구 게임 규칙상의 조건과 절차

- numbers 조건
- length 3
- letter range 1 ~ 9
- letter 중복 없음

- 2 numbers A, B 대조
- a in A is in B => ball += 1
- ai = bi => strike += 1
- ball -= strike

- 게임 결과 생성
- 스트라이크와 볼의 갯수
- 3스트라이크시 게임 종료 명시


### 2. UI : 입출력을 담당하는 인터페이스

- numbers 입력
- string 입력 받기
- GameRule을 참조하여 올바른 입력인지 검증하기
- 올바른 입력일 시 string을 array로 변환하여 리턴

- 인게임 결과 출력
- 인자로 받은 스트라이크 볼 갯수를 자연어로 번역
- 0인 경우 생략
- 둘 모두 0일 경우 낫싱
- 인게임 반복 여부 리턴
- 3 스트라이크일 경우 False
- 그 외 True

- 게임 종료 여부 입력
- 인게임 종료 알림 출력
- string 입력 루프
- 잘못된 입력인 경우 리로드
- 게임 종료 여부 리턴
- 1일 경우 False
- 2일 경우 True


### 3. Computer : 인게임 상대 역할
- 자신의 numbers 생성
- 새 게임 시작을 전달받았을 때 실행
- GameRule을 참조하여 numbers 필드 갱신
- 인게임 결과 전달
- numbers를 전달받았을 때 실행
- GameRule의 게임 결과 생성 메소드를 이용하여 인게임 결과 받기
- 인게임 결과 리턴


### 4. Control : 게임 흐름 제어

- 객체 생성, 게임 루프 시작
- 게임 루프
- Computer에게 새 게임 시작 알리기
- 인게임 루프 시작
- 인게임 루프
- UI 메소드 호출하여 numbers 받기
- numbers를 Computer에게 전달하여 인게임 결과 받기
- 인게임 결과를 인자로 UI 메소드 호출하여 인게임 반복 여부 받기
- 인게임 반복 여부에 따라 루프 반복 혹은 탈출
- 인게임 루프 탈출 = 게임 종료
- UI 메소드 호출하여 게임 재시작 여부 받기
- 게임 재시작 여부에 따라 루프 반복 혹은 탈출
- 게임 루프 탈출 = 프로세스 종료
8 changes: 8 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import game.Control;

public class Main {
public static void main(String[] args){
Control control = new Control();
control.start();
}
}
37 changes: 37 additions & 0 deletions src/main/java/game/Computer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package game;

import java.util.Random;
import java.util.HashSet;

public class Computer {
private GameRule gameRule;
private Random random;
private int[] numbers;

public Computer(GameRule gameRule) {
this.gameRule = gameRule;
this.random = new Random();
this.numbers = new int[gameRule.numbersLengh];
}

private int getNewNum(HashSet<Integer> appearedSet) {
Integer randomNum = gameRule.numbersRange[random.nextInt(gameRule.numbersRange.length)];
boolean isNew = appearedSet.add(randomNum);
while (!isNew) {
randomNum = gameRule.numbersRange[random.nextInt(gameRule.numbersRange.length)];
isNew = appearedSet.add(randomNum);
}
return randomNum;
}

public void updateNumbers() {
HashSet<Integer> appearedSet = new HashSet<Integer>();
for (int i = 0; i < gameRule.numbersLengh; i++) {
numbers[i] = this.getNewNum(appearedSet);
}
}

public GameRule.Result getResult(int[] inputNumbers) {
return gameRule.judgeResult(inputNumbers, numbers);
}
}
40 changes: 40 additions & 0 deletions src/main/java/game/Control.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package game;

public class Control {
private GameRule gameRule;
private UI ui;
private Computer computer;

public Control() {
this.gameRule = new GameRule();
this.ui = new UI(gameRule);
this.computer = new Computer(gameRule);
}

private boolean inGameLoop() {
int[] numbers = ui.getUserNumbers();
GameRule.Result result = computer.getResult(numbers);
ui.printResult(result);
if (result.isEnd)
return true;
return false;
}

private boolean gameLoop() {
boolean isEnd = false;
computer.updateNumbers();
while (!isEnd) {
isEnd = this.inGameLoop();
}
if (ui.getEndingStatus())
return true;
return false;
}

public void start() {
boolean isEnd = false;
while (!isEnd) {
isEnd = this.gameLoop();
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/game/GameRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package game;

public class GameRule {
public int numbersLengh = 3;
public int[] numbersRange = {1,2,3,4,5,6,7,8,9};


private int judgeStrike(int num1, int num2) {
if (num1 == num2)
return 1;
return 0;
}

private int judgeBall(int num, int[] numbers) {
boolean isBall = false;
for (int i = 0; i < numbersLengh; i++) {
isBall = isBall || num == numbers[i];
}
if (isBall)
return 1;
return 0;
}

public class Result {
public int strike;
public int ball;
public boolean isEnd;

public Result(int strike, int ball,boolean isEnd) {
this.strike = strike;
this.ball = ball;
this.isEnd = isEnd;
}
}

public Result judgeResult(int[] numbers1, int[] numbers2) {
int strike = 0;
int ball = 0;
for (int i = 0; i < numbersLengh; i++) {
strike += this.judgeStrike(numbers1[i], numbers2[i]);
ball += this.judgeBall(numbers1[i], numbers2);
}
ball -= strike;
return new Result(strike, ball, strike == numbersLengh);
}
}

111 changes: 111 additions & 0 deletions src/main/java/game/UI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package game;

import java.util.Scanner;
import java.util.HashSet;

public class UI {
private GameRule gameRule;
private Scanner scanner;

public UI(GameRule gameRule) {
this.gameRule = gameRule;
this.scanner = new Scanner(System.in);
}

private boolean verifyNumbersLength(String input) {
return input.length() == gameRule.numbersLengh;
}

private boolean verifyNumbersRangeOfLetter(int letter) {
boolean isInRange = false;
for (int num : gameRule.numbersRange) {
isInRange = isInRange || letter == num;
}
return isInRange;
}

private boolean verifyNumbersRange(String input) {
boolean isCorrect = true;
for (int i = 0; i < gameRule.numbersLengh; i++) {
isCorrect = isCorrect && this.verifyNumbersRangeOfLetter(input.charAt(i) - '0');
}
return isCorrect;
}

private boolean verifyNumbersDuplication(String input) {
boolean isCorrect = true;
HashSet<Character> appearedSet = new HashSet<Character>();
for (int i = 0; i < gameRule.numbersLengh; i++) {
Character letter = input.charAt(i);
isCorrect = isCorrect && appearedSet.add(letter);
}
return isCorrect;
}

private boolean verifyNumbers(String input) {
if (!this.verifyNumbersLength(input))
return false;
if (!this.verifyNumbersRange(input))
return false;
if (!this.verifyNumbersDuplication(input))
return false;
return true;
}

private int[] parseNumbers(String input) {
int[] numbers = new int[gameRule.numbersLengh];
for (int i = 0; i < gameRule.numbersLengh; i++) {
numbers[i] = input.charAt(i) -'0';
}
return numbers;
}

public int[] getUserNumbers() {
System.out.print("숫자를 입력해주세요 : ");
String input = scanner.nextLine();
boolean verification = this.verifyNumbers(input);
while (!verification) {
System.out.print("올바른 조건의 숫자를 입력해주세요 : ");
input = scanner.nextLine();
verification = this.verifyNumbers(input);
}
return this.parseNumbers(input);
}

public void printResult(GameRule.Result result) {
if (result.strike == 0 && result.ball == 0) {
System.out.println("낫싱");
return;
}
if (result.strike > 0)
System.out.print(result.strike + " 스트라이크 ");
if (result.ball > 0)
System.out.print(result.ball + " 볼");
System.out.println();
}

private boolean verifyEndingStatus(String input) {
if (input.equals("1") || input.equals("2"))
return true;
return false;
}

private boolean parseEndingStatus(String input) {
if (input.equals("2"))
return true;
return false;
}

public boolean getEndingStatus() {
System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
String input = scanner.nextLine();
boolean verification = this.verifyEndingStatus(input);
if (!verification) {
System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
input = scanner.nextLine();
verification = this.verifyEndingStatus(input);
}
return this.parseEndingStatus(input);
}
}
Loading