https://github.com/lxxjn0/java-baseball-precourse
⚾️ 프리코스 - 숫자 야구게임 미션을 진행하는 Repository
https://github.com/lxxjn0/java-baseball-precourse
baseball java
Last synced: 12 months ago
JSON representation
⚾️ 프리코스 - 숫자 야구게임 미션을 진행하는 Repository
- Host: GitHub
- URL: https://github.com/lxxjn0/java-baseball-precourse
- Owner: lxxjn0
- Created: 2020-12-28T09:21:15.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-12-28T09:21:40.000Z (over 5 years ago)
- Last Synced: 2025-07-09T11:53:58.940Z (12 months ago)
- Topics: baseball, java
- Language: Java
- Homepage: https://github.com/woowacourse/java-baseball-precourse
- Size: 104 KB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Precourse Week 1 - 숫자 야구 게임
## 미션 요구사항
자세히
> ### 기능 요구사항
>
> 1. 기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다.
>
> 2. 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 포볼 또는 낫싱이란 힌트를 얻고, 그 힌드를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.
>
> - [예시] 상대방(컴퓨터)의 수가 425일 때, 123을 제시한 경우 : 1 스트라이크, 456을 제시한 경우 : 1 스트라이크 1볼, 789를 제시한 경우 : 낫싱
>
> 3. 위 숫자 야구게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 3개 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.
>
> 4. 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.
>
> 5. 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.
> ### 프로그래밍 요구사항
>
> 1. 자바 코드 컨벤션을 지키면서 프로그래밍한다.
>
> - [Google Java Style Guide 참고](https://google.github.io/styleguide/javaguide.html)
>
> - [자바 코딩 규칙(Java Code Conventions) 참고](https://myeonguni.tistory.com/1596)
>
> 2. indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
>
> 3. 3항 연산자를 쓰지 않는다.
>
> 4. 함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게 만들어라.
## 구현해야 할 기능 목록
1. (기능 3) **1부터 9까지 서로 다른 수**로 이루어진 **3자리의 수**를 생성하는 기능.
- (구현) 숫자 생성시 **0**이 포함되지 않도록 생성.
- (구현) 각 자리의 수가 **서로 다른 3자리의 수** 생성 (이전 자리의 수와 비교 필요).
2. (기능 3) 사용자로부터 **3자리 수를 입력**받는 기능.
- (예외) **1부터 9까지의** 3자리 수가 입력되지 **않은** 경우 (문자 또는 3자리 미만, 초과의 경우, **0이 들어올 경우**).
- (예외) 3자리 수 중에서 **같은 수가 입력**된 경우.
- ~~(예외) **0**이 입력된 경우~~ - 첫번째 예외와 병합.
3. (기능 2) **스트라이크**의 개수를 구하는 기능.
- (구현) 생성된 수와 입력된 수 비교 후 **동일한 자리 - 동일한 수** 의 개수 측정.
4. (기능 2) **볼**의 개수를 구하는 기능.
- (구현) 생성된 수와 입력된 수 비교 후 **서로 다른 자리 - 동일한 수** 의 개수 측정.
5. (기능 2) **포볼**(낫싱)인지 여부를 판단하는 기능.
- (구현) 스트라이크의 개수와 볼의 **개수가 0**일 경우로 판단.
6. (기능 3) 스트라이크, 볼, 또는 포볼(낫싱)에 대한 결과를 **출력**.
- (구현) 포볼(낫싱)일 경우를 출력.
- (구현) 위 경우가 아닐 시 스트라이크와 볼의 개수를 출력.
7. (기능 4) 답과 일치하면 게임을 **종료**하는 기능.
- (구현) **스트라이크의 개수가 3개**이면 답과 일치하므로 게임 종료 ("게임 종료" 출력문도 함께 출력).
8. (기능 5) 게임을 종료한 후 **다시 시작**하거나 완전히 **종료**하는 기능.
- (구현) **1번**을 입력 받으면 게임을 **다시 시작** ([구현해야 할 기능](#구현해야-할-기능-목록)을 처음부터 다시 진행).
- (구현) **2번**을 입력 받으면 게임(프로그램) **종료**.
- (예외) **1또는 2가 아닌 입력**이 들어올 경우.
## 개발 진행 계획
자세히
1. 어떤 프로젝트인지와 구현해야 할 기능을 대략적으로 작성.
- 과제에 진행에 필요한 내용들을 [README.md](./README.md)에서 모두 볼 수 있도록 작성.
2. [구현해야 할 기능 목록](#구현해야-할-기능-목록)에 대한 세부적인 추가 기능 및 예외 처리 목록 작성.
- 구현 방법과 예외 처리에 대한 간략한 설명 및 계획 추가.
3. [구현해야 할 기능 목록](#구현해야-할-기능-목록) 순서대로 Class 생성 및 코드 작성 ([기능의 함수화](#프로그래밍-요구사항)).
- 구현해야 할 기능에 따른 Class 설정.
- 최대한 Code Conventions를 지키면서 작성 (Naming에도 신경쓰기).
4. 전체적인 리펙토링 ([기능의 함수화](#프로그래밍-요구사항) 확인, 상수 사용 확인, 코드의 중복 여부 확인).
- 전체 코드를 재확인하면서 기능을 좀 더 세분화시켜 함수화하는 리펙토링 진행 (1차 리펙토링).
- 상수 사용되지 않은 부분을 수정하고 코드의 중복 사용 부분 수정.
- 불필요하게 존재하는 if-else문을 if문으로 수정하여 코드의 간결화.
- 클래스의 객체 지향 판단 후 static 함수 수정, 형식에 어긋나는 명명 일부 수정 및 일부 주석 수정.
5. ~~[프로그래밍 요구사항](#프로그래밍-요구사항) 중 코드 부분을 중점적으로 확인 (indent depth와 3항 연산자).~~
- [개발 진행 계획 4 (1차 리펙토링)](##-개발-진행-계획)를 진행하면서 함께 수정 (indent가 3인 부분들을 2로 수정).
6. [프로그래밍 요구사항](#프로그래밍-요구사항) 중 Convention을 중점적으로 확인.
- code fommat을 통한 1차 code convention 체크.
- code convention 2차 체크 (파일 구조, 들여쓰기, 주석, 선언, 복합문, 빈 공간에 대하여 수정).
- code convention 3차 체크 (명명 규칙, 좋은 프로그래밍 습관), 클래스, 메서드, 변수의 이름에서 최대한 역할이 드러나도록 명명 수정.
- code convention 4차 체크 (oracle의 java code convention example code 참고).
7. 추가적인 리펙토링 계속 진행.
- 가독성을 위해 유효성 검사 부분 전체 수정 (계속 stack을 쌓으면서 안으로 들어가는 형식을 수정).
- 변수의 추가 또는 불필요한 변수 삭제, 반환문 수정을 통한 조건문 축소, 일부 주석과 메서드 수정.
- Scanner.next() 함수에서 버퍼에 쌓이는 문제를 nextLine() 함수로 교체하여 해결.
## 추가 리펙토링 진행 - 클래스 분리 연습
자세히
> 우아한 형제들 기술 블로그의 [생각하라, 객체지향처럼](http://woowabros.github.io/study/2016/07/07/think_object_oriented.html) 참고
>
> [객체 지향 설계 원칙](https://gmlwjd9405.github.io/2018/07/05/oop-solid.html) 참고
- 클래스를 새로 분류 진행.
1. 입력 타입
2. 출력 타입
3. 게임 관리자 타입
4. 게임 타입
5. 컴퓨터 타입
6. ~~유저 타입~~
- '세자리 수를 입력해라'라는 메시지를 유저에게 보는 것보다 '세자리 수를 유저로부터 입력 받아와라'라는 메시지를 Input UI에게 보내는 것이 더 적절하다고 생각이 들어 해당 클래스 삭제.
- 입력의 유효성은 게임 타입에서 판단하는 것이 더 적절하다고 생각.
7. 심판 타입
8. 유효성 검증 타입
- 전체적인 리펙토링 완료
- 최대한 각각의 역할을 생각하고 객체지향적으로 클래스 분류 작업 진행.
- UI 로직과 비즈니스 로직을 한 클래스에 담지 않고 분리 진행.
- 추후에, Exception 오버라이딩을 통한 예외 처리 진행.
## 오프라인 테스트 준비 - 최종 리팩토링 연습
### 중점적인 연습 진행 부분
1. 원시타입과 문자열 포장 연습
- Enum 또는 클래스로 포장.
2. 일급 컬렉션 사용
- 컬렉션 단 하나만 인스턴스 변수로 가지는 클래스.
### 클래스 분리 계획
1. 1부터 9까지의 수 1개를 저장할 야구공 객체인 Baseball.
2. Baseball을 List로 가질 일급 컬렉션 객체인 Baseballs.
3. Baseball을 Random하게, 또는 사용자의 입력을 통해 생성할 클래스인 BaseballFactory.
4. 게임이 종료된 후 새로 시작 여부를 저장할 객체인 ResumeOrNot.
5. 이전에 역할을 그대로 수행할 Computer, GameManager, BaseballGame.
6. UI 로직을 담당하여 Static으로 수정한 클래스인 Input, Output.
7. 결과를 계산하여 돌려주는 객체인 Result(기존의 Referee).
### 중점으로 수정을 진행한 부분
1. Baseball 객체로 야구공에 해당하는 숫자 하나를 포장.
- 처음 생성할 때 유효성 검증을 진행할 수 있어서 코드가 상당히 깔끔해짐.
- 오버라이딩 연습을 진행해봄.
2. Baseball 객체를 List Collection으로 가지는 일급 컬렉션 객체 Baseballs.
- 생성된 숫자들을 저장하면서 유효성 검사 동시 진행가능.
- 3개의 숫자(Baseball)만 저장되도록 검증하면, 이후 스트라이크와 볼의 개수를 구하는 것도 이 객체에서 모두 가능 -> 3개의 공에 대한 확인의 책임은 모두 해당 클래스가 지도록!
- 역시 eqauls() 오버라이딩을 통해 정답 여부를 쉽게 equals로만 확인 가능.
3. ResumeOrNot 객체로 사용자의 재진행 여부 입력 포장.
- 원시타입 또는 문자열을 포장함으로서 가장 크게 편해지는 부분은 유효성 검증인듯.
- 생성하면서 유효하지 않은 객체들은 생성을 막기 때문에 해당 입력이 발행하는 부분마다 유효성 테스트를 진행할 필요가 없어짐.
- 객체 자체에서 재진행 여부 입력인지 확인하여 boolean으로 반환 가능하기에 모든 코드들이 간결해짐.