Skip to content
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 숫자야구 (Number Baseball)

## 프로젝트 소개
컴퓨터가 랜덤으로 생성한 3자리 숫자를 사용자가 입력해서 맞추는 게임입니다.
숫자와 자리 모두 맞으면 스트라이크, 숫자만 맞으면 볼, 아무것도 맞지 않으면 미스로 판정합니다.

## 기능
- 1~9 사이의 서로 다른 숫자 3개를 랜덤으로 생성
- 사용자가 숫자 3자리를 입력하면 결과를 출력
- 스트라이크, 볼, 미스 판정
- 정답을 맞추면 게임을 재시작하거나 종료할 수 있음
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제 진행 요구사항에 아래와 같은 요구 사항이 있어요.

  • 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리합니다.
  • Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가합니다.

현재 작성하신 기능 목록에 맞춰 해당 기능을 구현한 후 이를 커밋해 보면 어떨까요?
지금은 혼자 개발하셔서 크게 상관없을 수 있지만, 나중에 팀 프로젝트를 진행할 때 큰 도움이 될 거예요.
각 기능마다 구현한 후 커밋을 하면 무슨 기능이 구현되었는지 쉽게 파악할 수 있고, 어떤 코드에 에러가 있다면 그 시점으로 되돌아갈 수도 있어요.

그 외에 다양한 git 기능들이 많으니 이번에 수정할 때나 다음 과제부터 적용해보면 좋을 것 같아요.
우선은 기능마다 커밋하는 것에 익숙해지면 다음엔 좀 더 자세히 커밋하는 방법을 알려드릴게요.


## 실행 방법
1. `Application.java` 파일을 실행합니다.
2. 콘솔 창에 출력되는 안내에 따라 3자리 숫자를 입력하여 게임을 진행합니다.
64 changes: 62 additions & 2 deletions src/main/java/baseball/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,67 @@
package baseball;

import java.util.*;

public class Application {
public static void main(String[] args) {
// TODO: 코드 구현
System.out.println("숫자 야구 게임을 시작합니다.");
Scanner sc = new Scanner(System.in);

while (true) {
List<Integer> computer = generateRandomDigits();
boolean correct = false;

while (!correct) {
System.out.print("숫자 3자리를 입력하세요 (예: 123): ");
String input = sc.next();
List<Integer> user = new ArrayList<>();
for (int i = 0; i < 3; i++) {
user.add(input.charAt(i) - '0');
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용자의 입력에 대한 예외 처리가 안되어 있어요.
기능 요구 사항 중 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 합니다. 라는 요구 사항이 있는데, 이 부분을 놓치신 것 같아요.
원활한 프로그램 실행을 위해 예외 처리는 필수로 해주시는 것이 좋아요.

참고할만한 예외 처리로는

  • 사용자 입력이 3자리여야 한다.
  • 입력에 문자가 입력되면 안된다.
  • 랜덤 숫자 값은 1~9 이므로 0이 입력되면 안된다.
  • 랜덤 숫자는 중복 값이 없으므로 중복 숫자 입력에 대한 예외처리.

등을 생각할 수 있겠네요.


int strike = 0;
int ball = 0;

for (int i = 0; i < 3; i++) {
if (user.get(i).equals(computer.get(i))) {
strike++;
} else if (computer.contains(user.get(i))) {
ball++;
}
}

if (strike == 0 && ball == 0) {
System.out.println("미스");
} else {
System.out.println(strike + " 스트라이크 " + ball + " 볼");
}

if (strike == 3) {
System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
System.out.print("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요: ");
int choice = sc.nextInt();
if (choice == 2) {
System.out.println("게임을 종료합니다.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 모든 출력이 붙어있어 가독성이 좋지 않은 것 같아요. print에 \n 또는 System.out.println()를 한 줄씩 포함해 출력에 가독성을 챙겨주는 것도 좋다고 생각해요

return;
} else {
break;
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 말하는 내용은 아직 어려울 수 있으나, 추후 팀 프로젝트를 원활하게 진행하려면 알아둘 필요가 있는 내용이니 참고하시고 공부해 보시면 좋을 것 같아요.

프로그래밍 요구사항에 프로그램 실행의 시작점은 Application의 main() 입니다. 라는 요구사항이 있어요.
그리고 객체지향 원칙(OOP)에서 단일 책임 원칙(SRP)이라는 것이 있어요.

위 두 문장을 보면 Application의 main() 함수는 프로그램을 실행하는 역할을 수행해요.
즉, 25번 라인부터 49번 라인의 숫자 판별 및 출력까지 하는 역할과,
54번 라인부터 66번 라인까지의 랜덤 숫자를 생성하는 역할,
그리고 모든 입력과 출력의 역할까지 맡기에는 Application 클래스와 main 함수에 책임이 과다한 게 됩니다.

25번 라인부터 49번 라인은 실제 야구로 치면 심판이 하는 역할이죠? 숫자 야구로 보면 게임의 룰이 된다고 볼 수 있죠.
그럼 BaseballJudge나 GameRule 이라는 클래스가 해당 기능들을 맡으면 좋을 것 같단 생각이 들어요.

굳이 왜 그래야하지? 라고 생각이 들 수 있는데, 현재 과제는 쉬운 편이고 이에 대한 코드도 짧은 편이에요.
그런데 코드가 길어지고(최소100 라인 이상) 역할들이 다양해 진다면 하나의 파일에서 코드를 찾기도 힘들고, 어떤 기능이 어디에 있고 어떻게 실행되는지 한 눈에 파악하기가 어려워요.

추후 팀 프로젝트를 진행할 때 모든 기능을 한 파일에 때려 박는다면 리팩토링 하기도, 유지보수 하기도, 재사용 하기도 힘들 거예요. 현재 과제가 어렵게 느껴지실 수도 있지만 팀 프로젝트에 비하면 훨씬 쉬운 편이니 한 번 생각해보시고 학습해 본다면 크게 성장할 수 있을 거예요.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한번 브랜치를 새로 따서 말씀주신 사항 반영해보려 했는데, 시간 괜찮으시다면 이것도 한번 확인 부탁드릴게요..!! (shinseojin.ver2)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전보다 훨씬 보기 좋아졌네요. 각 함수 명에 맞는 기능만 잘 넣은 것 같아요.
현재는 이정도로 발전한 것도 충분하다고 생각하고, 어떻게 기능을 분할해야 하는지에 대해 익숙해지는 것이 먼저라고 생각해요.
그래도 혹시 욕심이 있다면 static, 파일 분리 등 다음으로 알아두면 좋을 내용도 알려드릴게요~
리팩터링 고생하셨습니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인해주셔서 감사드려요!

}
}
}

public static List<Integer> generateRandomDigits() {
List<Integer> digits = new ArrayList<>();
Random random = new Random();

while (digits.size() < 3) {
int num = random.nextInt(9) + 1; // 1~9
if (!digits.contains(num)) {
digits.add(num);
}
}

return digits;
}
}
}