Skip to content

3️⃣ 숫자야구게임 다시 구현 - Sanghee #168

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,30 @@ git checkout main // 기본 브랜치가 main인 경우
git checkout -b 브랜치이름
ex) git checkout -b apply-feedback
```
---
4. 기능 목록 - TDD 구현
- 1~9의 숫자 중 랜덤으로 3개의 숫자를 구한다
- 사용자로부터 입력 받는 3개 숫자 예외처리
- 1~9의 숫자인가?
- 중복 값이 있는가?
- 3자리인가?
- 위치와 숫자 값이 같은 경우 -> 스트라이크
- 위치는 다른데 숫자 값이 같은 경우 -> 볼
- 숫자 값이 다른 경우 -> 낫싱
- 사용자가 입력한 값에 대한 실행 결과를 구한다

```jsx
com / user
123 / 123 -> 3 strike
123 / 142 -> 1 strike, 1 ball

# step 1
1 2 / 1 2 -> strike
3 2 / 1 2 -> ball
1 3 / 1 2 -> nothing

# step 2
123 / 1 1 -> strike
123 / 1 2 -> ball
123 / 1 5 -> nothing
```
35 changes: 35 additions & 0 deletions src/main/java/baseball/Ball.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package baseball;

public class Ball {
// Step 1

private final int position;
private final int ballNum;

public Ball(int position, int ballNum) {
this.position = position;
this.ballNum = ballNum;
}


public BallStatus playBall(Ball ball) {
if(this.equals(ball)) return BallStatus.STRIKE;
if(matchBallNum(ball.ballNum)) return BallStatus.BALL;
return BallStatus.NOTHING;
}

private boolean matchBallNum(int ballNum) {
return this.ballNum == ballNum;
}

@Override
public boolean equals(Object o) {
if(this == o)return true;
if(o == null || this.getClass() != o.getClass()) return false; // 실행 중인 클래스 객체의 정보를 확인
Ball ball = (Ball) o;
return position == ball.position &&
ballNum == ball.ballNum;
}


}
15 changes: 15 additions & 0 deletions src/main/java/baseball/BallStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package baseball;

public enum BallStatus {
NOTHING, STRIKE, BALL;

public boolean isNotNothing() {
return this != NOTHING;
}
public boolean isStrike() {
return this == STRIKE;
}
public boolean isBall() {
return this == BALL;
}
}
39 changes: 39 additions & 0 deletions src/main/java/baseball/Balls.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package baseball;

import java.util.ArrayList;
import java.util.List;

public class Balls {
private final List<Ball> balls; // computer balls

public Balls(List<Integer> computer) {
this.balls = getBalls(computer);
}


private static List<Ball> getBalls(List<Integer> computer) {
List<Ball> balls = new ArrayList<>();
for (int i = 0; i < 3; i++) {
balls.add(new Ball(i+1, computer.get(i)));
}
return balls;
}
public Score play(List<Integer> userInput) {
Balls userBalls = new Balls(userInput);
Score result = new Score();
// 비교 분석
for(Ball answer : balls){ // computerBall
BallStatus status = userBalls.playBalls(answer); // 앞 뒤에 들어갈 객체가 바뀌어도 strike,ball 판별에는 문제가 되지 않음
result.report(status);
}
return result;
}

public BallStatus playBalls(Ball userBall) {
return balls.stream()
.map(answer -> answer.playBall(userBall))
.filter(BallStatus::isNotNothing)
.findFirst()
.orElse(BallStatus.NOTHING);
}
}
48 changes: 48 additions & 0 deletions src/main/java/baseball/BallsNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package baseball;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BallsNumber {

public List<Integer> splitNumber(int userNumber) {
List<Integer> userNumList = new ArrayList<>();

while(userNumber > 0) {
userNumList.add(0, userNumber % 10);
userNumber /= 10;
}

return userNumList;
}
public static boolean validateNumber(List<Integer> ballNumbers) {
return areAllNumbersValid(ballNumbers) && areAllNumbersUnique(ballNumbers);
}

// 1~9사이 숫자인지 확인

private static boolean areAllNumbersValid(List<Integer> ballNumbers) {
return ballNumbers.stream().allMatch(BallsNumber::isValidNumber);
}
private static boolean isValidNumber(int x) {
if (!(0 < x && x < 10)) {
System.out.println("1~9 사이 숫자로 이루어진 수를 입력해주세요.");
return false;
}
return true;
}
// 숫자 중복 확인
private static boolean areAllNumbersUnique(List<Integer> ballNumbers) {
return ballNumbers.stream().allMatch(x -> isUniqueNumber(ballNumbers, x));
}
private static boolean isUniqueNumber(List<Integer> ballNumbers, int x) {
if (!(Collections.frequency(ballNumbers, x) == 1)) {
System.out.println("중복 숫자가 없는 수를 입력해주세요.");
return false;
}
return true;

}
}

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

import ui.InputView;
import ui.ResultView;
import utils.MakeRandomNum;

import java.util.List;
import java.util.Scanner;

import static baseball.BallsNumber.validateNumber;

public class BaseBall {
public void game(){
// computer num
MakeRandomNum randomNum = new MakeRandomNum();
Balls answer = new Balls(randomNum.makeRandomNum());

// user num
Scanner sc = new Scanner(System.in);
int strike = 0;

while(strike != 3) {
System.out.print("숫자를 입력해 주세요 : ");
int userInput = sc.nextInt();

// 유효성 검사
BallsNumber ball = new BallsNumber();

List<Integer> ballList = ball.splitNumber(userInput);
if(!validateNumber(ballList)) continue;

strike = ResultView.result(answer.play(ballList));
}

}
public BaseBall() {
while(true){
game();
if(InputView.inputNumber()!=1) return;
}
}

public static void main(String[] args) {
new BaseBall();
}
}
26 changes: 26 additions & 0 deletions src/main/java/baseball/Score.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package baseball;

public class Score {
private int strike = 0;
private int ball = 0;


public int getStrike() {
return this.strike;
}
public int getBall() {
return this.ball;
}

public void report(BallStatus status) {
if(status.isBall()) this.ball += 1;
if(status.isStrike()) this.strike += 1;

}
public boolean isGameEnd() {
return strike == 3;
}
public boolean isNothing() {
return this.strike == 0 && this.ball == 0;
}
}
12 changes: 12 additions & 0 deletions src/main/java/ui/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class InputView {
public static int inputNumber() {
Scanner sc = new Scanner(System.in);
return sc.nextInt();
}
}
29 changes: 29 additions & 0 deletions src/main/java/ui/ResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ui;

import baseball.Score;

public class ResultView {
public static int result(Score score) {
StringBuilder sb = new StringBuilder();
int result = 0;

if(score.isNothing()) {
sb.append("낫싱");
}
if(score.getBall() > 0) {
sb.append(score.getBall()).append("볼 ");
}
if(score.getStrike() > 0){
sb.append(score.getStrike()).append("스트라이크");
result = score.getStrike();
}
if(score.isGameEnd()) {
sb.append("\n")
.append("3개의 숫자를 모두 맞히셨습니다! 게임 종료").append("\n")
.append("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
}
System.out.println(sb);

return result;
}
}
31 changes: 31 additions & 0 deletions src/main/java/utils/MakeRandomNum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MakeRandomNum {
private List<Integer> numList;
private static boolean[] check; // true이면 값이 들어가있다
public MakeRandomNum() {
check = new boolean[10]; // 1~9 사이의 수 파악
}
public List<Integer> makeRandomNum(){
numList = new ArrayList<>();
Random random = new Random();
int idx = 0;
while(idx != 3) {
int num = random.nextInt(9)+1; // 1 ~ 4 까지의 무작위 int 값 리턴
idx = checkDuplicate(idx, num);
}
return numList;
}
public int checkDuplicate(int idx, int num) {
if(!check[num]) {
idx++;
check[num] = true;
numList.add(num);
}
return idx;
}
}
29 changes: 29 additions & 0 deletions src/test/java/baseball/BallTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package baseball;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

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

public class BallTest {
// Step 1.
@Test
@DisplayName("userball과 computerball 각각 1개씩 비교 - strike")
void strike() {
Ball computerBall = new Ball(1, 5);

assertThat(computerBall.playBall(new Ball(1, 5))).isEqualTo(BallStatus.STRIKE);
}
@Test
@DisplayName("userball과 computerball 각각 1개씩 비교 - ball")
void ball() {
Ball computerBall = new Ball(1, 5);
assertThat(computerBall.playBall(new Ball(2, 5))).isEqualTo(BallStatus.BALL);
}
@Test
@DisplayName("userball과 computerball 각각 1개씩 비교 - nothing")
void nothing() {
Ball computerBall = new Ball(1, 5);
assertThat(computerBall.playBall(new Ball(2, 6))).isEqualTo(BallStatus.NOTHING);
}
}
Loading