Skip to content

2️⃣ 숫자야구게임 구현 - Sanghee #167

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 13 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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,29 @@ git checkout main // 기본 브랜치가 main인 경우
git checkout -b 브랜치이름
ex) git checkout -b apply-feedback
```
4. 구현할 기능 목록

### InputView
```jsx
- 3자리의 난수 생성 (조건 : 각 숫자가 겹치지 않는다)
- 사용자의 입력값 받고 저장
- 입력값 검증 :
- 3자리의 각 자리가 중복이 안되는지,
- 1~9 사이의 수 인지
```
### NumbersBaseball
```jsx
- 난수와 입력값 비교
- 같은 위치에 같은 숫자라면 strike
- 다른 위치에 같은 숫자가 있으면 ball
- 아무것도 겹치지 않으면 낫싱
- 3 strike가 아니라면 다시 입력값 받기
- 3 strike라면 게임이 끝
- 게임을 다시 시작하거나 완전히 종료할 수 있다
```
### ResultView
```jsx
- strike, ball, nothing 점수 혹은 결과 출력
- 3 strike일 때 종료 메세지 출력
```

1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repositories {
dependencies {
testImplementation "org.junit.jupiter:junit-jupiter:5.7.2"
testImplementation "org.assertj:assertj-core:3.19.0"
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
}

test {
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/numbersBaseball/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package numbersBaseball;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class InputView {
public static int[] check = new int[10]; // 1 ~ 9

// 3자리 수 입력 받기
public static int inputNumber() {
Scanner sc = new Scanner(System.in);
return sc.nextInt();
}

// 랜덤 수 3자리 생성
public static int duplicateCheck(int[] randomNum, int idx, int num) {
if(check[num] == 0) {
randomNum[idx] = num;
check[num] = idx + 1; // random number 각 인덱스값 저장
idx++;
}
return idx; //현재 idx 반환
}
public static void makeRandomNumber(int[] randomNum) {
int idx = 0;

while (idx != 3) {
int cur = ((int)(Math.random()*8)+1); // random number 생성
idx = duplicateCheck(randomNum, idx, cur);
}
}


// validation
public static boolean validateNumber(ArrayList<Integer> numList) {
boolean verification = false;

if(!(numList.size()==3)) return verification;
for (Integer number: numList) {
if(!(Collections.frequency(numList, number) == 1)) {
System.out.println(ValidationError.duplication);
return verification;
}
if(!((0 < number) && (number < 10))) {
System.out.println(ValidationError.intermediateValue);
return verification;
}
}

return true;
}

// 정수 쪼개기
public static ArrayList<Integer> splitNumber(int inputNum) {
// int[] numList = new int[4];
ArrayList<Integer> arr = new ArrayList<>();
arr.add(inputNum / 100);
arr.add((inputNum % 100) / 10);
arr.add((inputNum % 10));

return arr;
}
}
54 changes: 54 additions & 0 deletions src/main/java/numbersBaseball/NumbersBaseball.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package numbersBaseball;

import java.util.ArrayList;

public class NumbersBaseball {

public static int compareTo(ArrayList<Integer> compareNum){
// 초기화
int strike = 0, ball = 0;

for (int i = 1; i <= 3; i++) {
int cur = compareNum.get(i-1);

if(InputView.check[cur] != 0 && InputView.check[cur] == i) {
strike++;
continue;
}
if(InputView.check[cur] != 0) {
ball++;
}
}
System.out.println(ResultView.scoreResult(strike, ball));
return strike;
}

public void game(int[] randomNum) {
int strike = 0, ball = 0;
InputView.makeRandomNumber(randomNum);

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

int inputNum = InputView.inputNumber();
ArrayList<Integer> inputList = InputView.splitNumber(inputNum);

if(!InputView.validateNumber(inputList)) continue;

strike = compareTo(inputList);
}
}

public NumbersBaseball() {
int[] randomNum = new int[3];
while (true) {
game(randomNum);
ResultView.ending();
if(InputView.inputNumber() == 2) return;
}
}

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

public class ResultView {
public static String scoreResult(int strike, int ball) {
StringBuilder sb = new StringBuilder();

if(ball != 0) sb.append(ball).append("볼 ");
if(strike != 0) sb.append(strike).append("스트라이크");
if(ball == 0 && strike == 0) return "낫싱";

return sb.toString();
}

public static void ending() {
System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
}
}
7 changes: 7 additions & 0 deletions src/main/java/numbersBaseball/ValidationError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package numbersBaseball;

public class ValidationError {
public static String intermediateValue = "1 ~ 9 사이의 숫자를 입력해주세요.";
public static String duplication = "중복된 값 없이 입력해주세요.";

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

import java.util.Scanner;

public class StringCalculator {
// 사칙연산
public int add(int a, int b){ return a + b;}
public int subtract(int a, int b){ return a - b;}
public int multiply(int a, int b){ return a * b;}
public int divide(int a, int b){
try {
return a / b;
} catch (Exception e) {
System.out.println("0으로 나눌 수 없습니다.");
}return 0;
}
// 분할 메소드
public String[] split(String str) {
return str.split(" ");
}
public int toInt(String input) {
return Integer.parseInt(input);
}
public int transform(String[] values) {
int result = toInt(values[0]);
for (int i = 1; i < values.length; i += 2) {
result = operator(result, values[i],toInt(values[i+1]));
}
return result;
}
// 더하기, 곱하기, 나누기, 빼기 함수
public int operator(int firstValue, String operator, int secondValue) {
switch (operator) {
case "+":
return add(firstValue, secondValue);
case "-":
return subtract(firstValue, secondValue);
case "*":
return multiply(firstValue, secondValue);
case "/":
return divide(firstValue, secondValue);
default:
System.out.println("사칙 연산자가 아닙니다.");

}
return 0;
}

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String value = sc.nextLine();
StringCalculator T = new StringCalculator();
T.transform(T.split(value));
}
}
50 changes: 50 additions & 0 deletions src/test/java/numbersBaseball/InputViewTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package numbersBaseball;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;

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

class InputViewTest {
// 난수 생성 테스트
@Test
void makeRandomNumTest() {
int[] randomNum = new int[3];

InputView.makeRandomNumber(randomNum);
for (int i = 0; i < randomNum.length; i++) {
assertThat(0 < randomNum[i] && randomNum[i] <10).isEqualTo(true);
assertThat(InputView.check[randomNum[i]]).isNotZero();
}
}
// 각 자리수를 정수 배열로 생성하는 테스트
@Test
void splitNumTest() {
int num = 235;
ArrayList<Integer> numList = InputView.splitNumber(num);
assertThat(numList.toString()).isEqualTo("[0, 2, 3, 5]"); // idx 1~3 사용
}

/**
* 입력값 유효성 검증 테스트
*/
@Test
void validateNumTest_success() {
ArrayList<Integer> numList = InputView.splitNumber(146);
assertThat(InputView.validateNumber(numList)).isEqualTo(true);
}

// 사용자가 중복값 입력 시 false
@Test
void validateNumTest_fail1() {
ArrayList<Integer> numList = InputView.splitNumber(444);
assertThat(InputView.validateNumber(numList)).isEqualTo(false);
}
// 사용자가 1~9 이외의 값 입력 시
@Test
void validateNumTest_fail2() {
ArrayList<Integer> numList = InputView.splitNumber(405);
assertThat(InputView.validateNumber(numList)).isEqualTo(false);
}
}
35 changes: 35 additions & 0 deletions src/test/java/numbersBaseball/NumbersBaseballTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package numbersBaseball;

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

import java.util.ArrayList;
import java.util.Arrays;

import static numbersBaseball.NumbersBaseball.compareTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;


class NumbersBaseballTest {
// 각 자리수 비교 테스트
@Test
void compareToTest() {
// given
int[] randomNum = new int[3];
InputView.makeRandomNumber(randomNum);


ArrayList<Integer> sameList = new ArrayList<>();
for (int x:
randomNum) {
sameList.add(x);
}

// expected
// strike의 개수가 0 이상?
assertEquals(compareTo(sameList), 3);

}

}
47 changes: 47 additions & 0 deletions src/test/java/study/SetTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package study;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.HashSet;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class SetTest {
private Set<Integer> numbers;
@BeforeEach
void setUp() {
numbers = new HashSet<>();
numbers.add(1);
numbers.add(1);
numbers.add(2);
numbers.add(3);
}
// test case 구현
@Test
@DisplayName("set 중복을 허용하지 않는 자료구조")
void size() {
assertThat(numbers.size()).isEqualTo(3);
}


@ParameterizedTest
@DisplayName("ParameterizedTest - 중복소거")
@ValueSource(ints = {1, 2, 3})
void contains1(Integer integer) {
assertThat(numbers).contains(integer); //contains 메소드 결과 값이 true인 경우만 테스트 가능
}

@ParameterizedTest
@DisplayName("ParameterizedTest - 입력 값에 따라 결과 값이 다른 경우")
@CsvSource(value = {"1:true", "2:true", "3:true", "4:false", "5:false"}, delimiter = ':')
void contains2(String input, String output) {
boolean actualNum = numbers.contains(Integer.parseInt(input));
assertEquals(Boolean.parseBoolean(output),actualNum);
}
}
Loading