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

6기 1주차 숫자야구 #2816

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
56 changes: 56 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# 📝설계 구조
- Application : 애플리케이션 실행을 관리한다.
- MainController : 데이터 전달 및 중계 역할을 한다.
- view
- InputView : 입력과 관련된 책임 관리한다.
- OutputView : 출력과 관련된 책임 관리한다.
- message
- ErrorMessage : 에러 메시지를 관리한다.
- ViewMessage : 출력 메시지를 관리한다.
- domain
- Computer : List<Integer>를 멤버변수로 갖는다
- User : List<Integer>를 멤버변수로 갖는다
- Numbers : List<Integer>를 관리하는 일급 컬렉션
# 💪 프로젝트 개요
숫자 야구 게임을 구현한다. <br>
서로 다른 3자리의 수를 맞춰야한다. 실패시 힌트가 나온다.
게임끝난경우 재시작 or 종료를 1,2 를 선택할수있다.

# 📝 구현 기능 목록
### 게임 초기화

- [x] 랜덤한 3자리 숫자 생성가눙

- [x] 사용자 입력받기
- [x] `출력 문구` : "숫자를 입력해주세요 : "
- [x] 서로 다른 3자리수 입력받기
- [x] `예외처리` : 빈 문자열 입력 검증
- [x] `예외처리` : 3자리 초과 입력 검증
- [x] `예외처리` : 숫자외 문자 입력 검증
- [x] `예외처리` : 음수 입력 검증
- [x] `예외처리` : 중복되는 숫자 검증


### 게임 진행
- [x] 게임시작 문구 출력
- [x] `출력문구' : "숫자 야구 게임을 시작합니다."

- [x] 매 실행결과 출력 한다.


- [x] 게임 기능
- [x] 사용자가 입력과 컴퓨터 입력 숫자 비교
- [x] 같은 수가 같은 자리에 있으면 스트라이크
- [x] 다른 자리에 있으면 볼
- [x] 같은 수가 전혀 없으면 낫싱
- [x] 실패시 힌트 제공




### 게임 종료
- [x] `출력문구` : 3개의 숫자를 모두 맞히셨습니다! 게임 종료
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.

- [x] 재시작 기능
- [ ] 1 또는 2 이외의 값입력시 예외처리
3 changes: 2 additions & 1 deletion src/main/java/baseball/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
MainController controller = new MainController();
controller.run();
}
}
114 changes: 114 additions & 0 deletions src/main/java/baseball/MainController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package baseball;

import baseball.domain.Computer;
import baseball.domain.Numbers;
import baseball.domain.User;
import baseball.view.OutputView;
import camp.nextstep.edu.missionutils.Console;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MainController {
public void run() {
Computer computerNumbers = gameInit();
gameProceed(computerNumbers);
askForRestart(computerNumbers);
}


private static void gameProceed(Computer computerNumbers) {
boolean isCorrect;
do {
User userNumbers = new User(readUserNumbers());
isCorrect = computerNumbers.compareNumbers(userNumbers);
} while (!isCorrect);


}


private static Computer gameInit() {
Computer computerNumbers = new Computer(Numbers.createRandomNumber());
System.out.println("숫자 야구 게임을 시작합니다.");
return computerNumbers;
}
private static void askForRestart(Computer computerNumbers) {
System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
String input = Console.readLine();

if (input.equals("1")) {
computerNumbers.resetNumbers();
gameProceed(computerNumbers);
}
if (input.equals("2")) {
System.out.println("게임 종료");
}
}


private static Numbers readUserNumbers() {
System.out.printf("숫자를 입력해주세요 : ");
String userInput = Console.readLine();

validateisPositiveInteger(userInput);

validateStringBlank(userInput);
validateStringLegnth(userInput);
validateDuplicatedInput(userInput);

return readStringToNumbers(userInput);
}

private static Numbers readStringToNumbers(String userInput) {
List<Integer> userNumbers = new ArrayList<>();

for (int i = 0; i < userInput.length(); i++) {
int number = Integer.parseInt(String.valueOf(userInput.charAt(i)));
userNumbers.add(number);
}
return new Numbers(userNumbers);
}

private static void validateisPositiveInteger(String userInput) {
// 문자열이 정확히 3자여야 함을 확인
if (userInput.length() != 3) {
throw new IllegalArgumentException("입력은 반드시 3개를 초과할수없습니다.");
}

// 문자열의 모든 문자가 '1'에서 '9' 사이의 숫자인지 확인
for (char c : userInput.toCharArray()) {
if (c < '1' || c > '9') {
throw new IllegalArgumentException("문자열은 1부터 9까지의 숫자만 포함해야 합니다.");
}
}
}

private static void validateDuplicatedInput(String userInput) {
Set<Character> uniqueChar = new HashSet<>();
for (int i = 0; i < userInput.length(); i++) {
char currentChar = userInput.charAt(i);

if (uniqueChar.contains(currentChar)) {
throw new IllegalArgumentException("중복된 숫자가 포함되어 있습니다.");
}
uniqueChar.add(currentChar);
}

}

private static void validateStringBlank(String userInput) {
if (userInput.isBlank()) {
throw new IllegalArgumentException("빈값은 입력할 수 없습니다.");
}
}

private static void validateStringLegnth(String userInput) {
if (userInput.length() != 3) {
throw new IllegalArgumentException("입력은 반드시 3개의 숫자여야 합니다.");
}
}


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

import baseball.view.OutputView;
import camp.nextstep.edu.missionutils.Console;
import java.util.List;

public class Computer {

private static Numbers computerNumbers;

public Computer(Numbers computerNumbers) {
Computer.computerNumbers = computerNumbers;
}

public List<Integer> getComputerNumbers() {
return computerNumbers.getNumbers();
}

public static boolean compareNumbers(User userNumbers) {
List<Integer> computerNumberList = computerNumbers.getNumbers();
List<Integer> userNumberList = userNumbers.getUserNumbers();

int strikes = 0;
int balls = 0;
boolean result = false;

//스트라이크, 볼 체크로직
for (int i = 0; i < userNumberList.size(); i++) {
int userNumber = userNumberList.get(i);

if (computerNumberList.contains(userNumber) && computerNumberList.indexOf(userNumber) != i) {
balls++; // 값은 일치하지만 위치가 다르면 볼
}
if (userNumberList.get(i) == computerNumberList.get(i)) {
strikes++; // 값과 위치가 모두 일치하면 스트라이크
}
}
if (strikes == 3){
result = true;
}
OutputView.printGameResult(strikes,balls);
return result;
}

public void resetNumbers() {
computerNumbers =Numbers.createRandomNumber();
}
}
25 changes: 25 additions & 0 deletions src/main/java/baseball/domain/Numbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package baseball.domain;

import camp.nextstep.edu.missionutils.Randoms;
import java.util.ArrayList;
import java.util.List;

public record Numbers(List<Integer> numbers) {
public List<Integer> getNumbers() {
return numbers;
}
public static Numbers createRandomNumber() {
List<Integer> numbers = new ArrayList<>();

while (true) {
int randomNumber = Randoms.pickNumberInRange(1, 9);
if (!numbers.contains(randomNumber)) {
numbers.add(randomNumber);
}
if (numbers.size() == 3) {
break;
}
}
return new Numbers(numbers);
}
}
14 changes: 14 additions & 0 deletions src/main/java/baseball/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package baseball.domain;

import java.util.List;

public class User {
private final Numbers userNumbers;

public User(Numbers userNumbers) {
this.userNumbers = userNumbers;
}
public List<Integer> getUserNumbers() {
return userNumbers.getNumbers();
}
}
4 changes: 4 additions & 0 deletions src/main/java/baseball/message/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package baseball.message;

public enum ErrorMessage {
}
4 changes: 4 additions & 0 deletions src/main/java/baseball/message/ViewMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package baseball.message;

public enum ViewMessage {
}
4 changes: 4 additions & 0 deletions src/main/java/baseball/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package baseball.view;

public class InputView {
}
26 changes: 26 additions & 0 deletions src/main/java/baseball/view/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package baseball.view;

import baseball.domain.Computer;

public class OutputView {


public static void printGameResult(int strikes, int balls) {
if (strikes == 3) {
System.out.println("3스트라이크");
System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
}
if (strikes == 0 && balls == 0) {
System.out.println("낫싱");
}
if (balls !=0 && strikes ==0 ) {
System.out.println(balls+"볼");
}
if (balls ==0 && strikes !=0 ) {
System.out.println(strikes+"스트라이크");
}
if (balls != 0 && strikes != 0) {
System.out.println(balls +"볼 "+ strikes + "스트라이크");
}
}
}
57 changes: 57 additions & 0 deletions src/test/java/baseball/domain/ComputerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package baseball.domain;

import static baseball.domain.Computer.compareNumbers;
import static org.junit.jupiter.api.Assertions.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;

class ComputerTest {
private static Computer computerNumbers;
private static User user;

@BeforeEach
void setUp() {
// 예시로 컴퓨터가 선택한 3자리 숫자를 설정
computerNumbers = new Computer(new Numbers(Arrays.asList(1, 2, 3)));
}

@Test
@DisplayName("3 스트라이크 테스트")
void compareNumbersIsTrueTest() {
user = new User(new Numbers(Arrays.asList(1, 2, 3)));
assertTrue(compareNumbers(user));
}


@DisplayName("3볼, 스트라이크,볼 혼합, 전혀다른경우 테스트")
@ParameterizedTest
@MethodSource("provideUserNumbers")
void compareNumbersIsFalseTest() {
user = new User(new Numbers(Arrays.asList(3, 1, 2)));
assertFalse(compareNumbers(user));
}
static Stream<List<Integer>> provideUserNumbers() {
return Stream.of(
Arrays.asList(3, 1, 2), // 3 볼
Arrays.asList(1, 3, 2), // 2 스트라이크, 1 볼
Arrays.asList(4, 5, 6) // 전혀 다른 경우.
);
}




@Test
@Disabled
void resetNumbers() {
}
}
Loading