Backend/Java

[숫자야구게임 Step1] 정책을 정의내리고 테크스펙을 작성해보자.

Seyun(Marco) 2024. 4. 12. 02:13
728x90

서론

  • Java의 학습을 위해, 미션 학습을 진행하고 있습니다. 첫번째 미션으로는 “숫자야구게임”을 진행해보려고 합니다.
  • Step1부터 점진적으로 확장해 나가는것이 목표입니다.
  • 가장 중요한건 확장가능한 설계와 도메인 모델 정의, 테스트 코드 작성을 통한 안정적인 애플리케이션 구현을 가지고 해당 미션을 진행해보려고 합니다.
  • 의도적으로 꼼꼼한 테스트 코드와 원시값 포장을 진행하였습니다. 해당 부분은 참고해주시면 좋을거 같습니다.

미션 요구사항

  • 숫자야구게임이란?
    • 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임입니다.
    • 컴퓨터와 싸우는 게임으로 컴퓨터가 뽑은 랜덤의 숫자를 뽑을수 있도록 합니다.

상세 스펙

  • 명령어
    • 1을 입력하면 게임을 시작합니다.
    • 9를 입력하면 애플리케이션을 종료합니다.
  • 게임을 시작하면 1~9 서로 다른 임의의 수 3개를 선택합니다. 게임 플레이어는 컴퓨터가 생각하고 있는 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력해야 합니다.
  • 번호를 입력 한 뒤에 힌트에 대한 정의
    • 스트라이크: 이전에 뽑은 숫자에서 위치와 실제 숫자와 같은 경우
    • 볼: 이전에 뽑은 숫자에서 위치는 다르지만 숫자가 존재하는 경우
    • 낫싱: 이전에 뽑은 숫자에서 아예 존재하지 않은 경우
  • 애플리케이션을 종료하는 값(9)를 입력하지 전까지 게임을 계속 진행할 수 있다.
  • 콘솔 실행 결과
게임을 새로 시작하려면 1, 종료하려면 9를 입력하세요.
1

컴퓨터가 숫자를 뽑았습니다.

숫자를 입력해주세요 : 123
1볼 1스트라이크
숫자를 입력해주세요: 145
1볼
숫자를 입력해주세요: 671
2볼
숫자를 입력해주세요: 216
1스트라이크
숫자를 입력해주세요: 713
3스트라이크

3개의 숫자를 모두 맞히셨습니다.
-------게임 종료-------

게임을 새로 시작하려면 1, 종료하려면 9를 입력하세요.
9

애플리케이션이 종료되었습니다.

테크스펙

기술 스택

  • Java17 / Junit 5.9.1 / assertJ 3.25.3

모델링

  • Enum: Command
    • value: int
      • Commend를 실행할 수 있는 숫자를 정의내린다.
  • VO: Number
    • value: int
    • 숫자 야구게임에서 사용하는 1~9의 숫자를 정의내리는 Value Object입니다.
  • 일급컬렉션(VO): BaseBallNumbers
    • value: List<Number>
    • 실제 중복되지 않는 1~9의 3개의 상태를 가지고 있는 Value Object이자 일급컬렉션입니다.
  • Domain: Computer
    • numbers: BaseBallNumbers
    • 임의의 숫자 1~9까지 중에 3개를 뽑은 List를 상태로 가지고 있습니다.

정책 요구사항

  • 숫자야구게임에서 사용되는 숫자의 List는 중복되는 값이 들어가면 안된다.
    • 예제) 숫자가 1,2,3이면 가능하지만, 1,1,2면 에러가 발생해야 한다.
  • 숫자야구게임에서 사용되는 숫자는 3개이다.
    • 예제) 숫자가 1,2,3이면 가능하지만, 1,2 이면 에러가 발생해야 한다.
  • 애플리케이션을 종료하기 전까지는 게임이 계속 진행되어야 한다.
  • 컴퓨터가 가지고 있는 숫자들중에 위치와 숫자가 아예 같으면 스트라이크라고 한다.
    • 예를들어 컴퓨터가 1,2,3이라는 숫자를 가지고 있을때, 1,4,5를 사용자가 입력하면 1의 값은 스트라이크다.
  • 컴퓨터가 가지고 있는 숫자들중에 위치는 다르지만 숫자를 가지고 있다면 볼이라고 한다.
    • 예를들어 컴퓨터가 1,2,3이라는 숫자를 가지고 있을때, 4,5, 1를 사용자가 입력하면 1의 값은 볼이다.
  • 컴퓨터가 가지고 있는 숫자들과 사용자가 입력한 숫자들이 아예 다르면 낫싱이라고 한다.
    • 예를들어 컴퓨터가 1,2,3이라는 숫자를 가지고 있을때, 4,5,6을 사용자가 입력한 경우 해당 부분에서는 낫싱이다.
  • 모든 숫자가 스트라이크여야 사용자는 승리할 수 있다.
    • 예를들어 컴퓨터가 1,2,3이라는 숫자를 가지고 있을 때, 1,2,3을 사용자가 입력하면 해당 게임은 사용자의 승리로 종료된다.

기술적 부분

  • 컴퓨터는 1~9까지의 임의의 수중에 3개를 골라야 하는데, 해당 부분은 랜덤이기 떄문에 실제 테스트 코드를 작성할때 제어할수 없는 값으로 칭한다.
  • 관련되어서는 Interface를 도입해 확장 가능한 영역으로 처리한다.
  • 예를들어, BaseBallNumbersGenerator Interface를 만들어, 구현체를 만들어서 가장 밖에서 코드를 제어할수 있게 한다.
  • 1~9까지의 Number에 대한 값은 변경되지 않을 값으로써 성능(메모리 공간 확보)를 위해 캐싱을 진행한다.
  • 랜덤으로 3개의 숫자를 빼는 방법은 두가지가 있다. 관련해서 밴치마킹을 진행해 어떤것이 더 좋을지 판단해본다.
    1. 1~9의 숫자를 가지고 있는 List를 Shuffle을 진행하고, 앞에서 3개의 숫자를 추출한다.
    2. index를 랜덤으로 만들어서 index를 이용해 랜덤으로 숫자를 추출한다.

결론

  • 의도적으로 맨처음 테크스펙을 작성하고 관련된 흐름으로 흘러가도록 노력해보려고 한다.
  • 2편에서는 실제 도메인을 어떻게 설계하였는지 작성해보려고 합니다.
728x90
728x90