Skip to content

lxxjn0/java-baseball-precourse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Precourse Week 1 - 숫자 야구 게임

미션 요구사항

자세히

기능 요구사항

  1. 기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다.

  2. 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 포볼 또는 낫싱이란 힌트를 얻고, 그 힌드를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.

    • [예시] 상대방(컴퓨터)의 수가 425일 때, 123을 제시한 경우 : 1 스트라이크, 456을 제시한 경우 : 1 스트라이크 1볼, 789를 제시한 경우 : 낫싱
  3. 위 숫자 야구게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 3개 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.

  4. 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.

  5. 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.

프로그래밍 요구사항

  1. 자바 코드 컨벤션을 지키면서 프로그래밍한다.

  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에서 모두 볼 수 있도록 작성.
  2. 구현해야 할 기능 목록에 대한 세부적인 추가 기능 및 예외 처리 목록 작성.

    • 구현 방법과 예외 처리에 대한 간략한 설명 및 계획 추가.
  3. 구현해야 할 기능 목록 순서대로 Class 생성 및 코드 작성 (기능의 함수화).

    • 구현해야 할 기능에 따른 Class 설정.

    • 최대한 Code Conventions를 지키면서 작성 (Naming에도 신경쓰기).

  4. 전체적인 리펙토링 (기능의 함수화 확인, 상수 사용 확인, 코드의 중복 여부 확인).

    • 전체 코드를 재확인하면서 기능을 좀 더 세분화시켜 함수화하는 리펙토링 진행 (1차 리펙토링).

    • 상수 사용되지 않은 부분을 수정하고 코드의 중복 사용 부분 수정.

    • 불필요하게 존재하는 if-else문을 if문으로 수정하여 코드의 간결화.

    • 클래스의 객체 지향 판단 후 static 함수 수정, 형식에 어긋나는 명명 일부 수정 및 일부 주석 수정.

  5. 프로그래밍 요구사항 중 코드 부분을 중점적으로 확인 (indent depth와 3항 연산자).

  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() 함수로 교체하여 해결.


추가 리펙토링 진행 - 클래스 분리 연습

자세히

우아한 형제들 기술 블로그의 생각하라, 객체지향처럼 참고

객체 지향 설계 원칙 참고


  • 클래스를 새로 분류 진행.

    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으로 반환 가능하기에 모든 코드들이 간결해짐.

About

⚾️ 프리코스 - 숫자 야구게임 미션을 진행하는 Repository

Topics

Resources

Stars

Watchers

Forks

Languages