기능 요구 사항
## 🚀 기능 요구 사항
기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다.
- 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.
- 예) 상대방(컴퓨터)의 수가 425일 때
- 123을 제시한 경우 : 1스트라이크
- 456을 제시한 경우 : 1볼 1스트라이크
- 789를 제시한 경우 : 낫싱
- 위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한
결과를 출력한다.
- 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.
- 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.
- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료되어야 한다.
라이브러리
### 라이브러리
- `camp.nextstep.edu.missionutils`에서 제공하는 `Randoms` 및 `Console` API를 사용하여 구현해야 한다.
- Random 값 추출은 `camp.nextstep.edu.missionutils.Randoms`의 `pickNumberInRange()`를 활용한다.
- 사용자가 입력하는 값은 `camp.nextstep.edu.missionutils.Console`의 `readLine()`을 활용한다.
기능 목록 정의
개인적으로 지키려고 노력했던 부분들
1. depth는 최대 1까지
public Hint compare(BaseballNumber computerNumbers, BaseballNumber playerNumbers) {
int strike = 0;
int ball = 0;
for (int i = 0; i < MAX_NUMBER_SIZE; i++) {
if (computerNumbers.getNumberByIndex(i) == playerNumbers.getNumberByIndex(i)) {
strike++;
continue;
}
if (computerNumbers.isNumberContains(playerNumbers.getNumberByIndex(i))) {
ball++;
}
}
return new Hint(strike, ball);
}
설계가 잘못됐는지 for문 안에 if문들을 빼보려고 노력했지만 오히려 더 이해하기 난해한 코드가 나와서 너무 아쉽다..ㅠㅠ
2. 매개변수는 최대 2개
private void appendStrikeAndBall(StringBuilder result, int strikeCount, int ballCount) {
if (hint.isBallCountBiggerThanZero()) {
result.append(ballCount).append(BALL);
}
if (hint.isStrikeCountBiggerThanZero()) {
if (hint.isBallCountBiggerThanZero()) {
result.append(" ");
}
result.append(strikeCount).append(STRIKE);
}
if (hint.isStrikeCountZero() && hint.isBallCountZero()) {
result.append(NOTHING);
}
}
이 부분도 depth가 2.. StringBuilder를 사용해 버려서 매개변수가 3개가 넘어가 버렸다.. 다음 미션까지 꼭 리팩터링 방법을 찾고 싶다.
3. 가장 신경을 많이 쓴 테스트 코드
설계대로 구현을 다한 후 리팩터링을 하다가 몸소 느낀 점이 있다!
구현할 때 시간이 더 들고 귀찮겠지만 리팩터링을 할 때 이렇게 고마울 수가 없고 오히려 시간이 더 줄어든다!!
다음 미션땐 TDD를 적용해볼까 한다..!!
4. 네이밍
상대방이 봤을 때, 가장 쉽게 의도를 파악하는 방법은 네이밍이라고 생각한다! 미션이 끝나고 코드 리뷰를 할 때 상대방이 보기 쉽고 이해하기 쉽게 네이밍을 해봤다! 몇 번의 변경이 있었지만 아직도 개선할 여지가 있는 거 같다. 다음 미션엔 꼭 누구나 알 수 있게 할 거다!
아쉬운 점
1. 원시값 포장
private final List<Integer> numbers;
public BaseballNumber(List<Integer> numbers) {
validateNumber(numbers);
this.numbers = numbers;
}
이 부분은 컴퓨터의 숫자와 사용자 숫자를 가지고 있는 객체인데 List <Integer> 말고 List <BaseballNumber>로 바꾼 후, 클래스 명을 BaseballNumbers가 더 나은 설계가 아닐까 싶다!!
궁금한 점
1. toString 은 과연 테스트를 해야 하는가??
2. 공통적으로 사용되는 상수들은 한 곳에서 관리하는 방법 외에도 다른 방법이 있을까??
3. Randoms.pickNumberInRange <== 이것도 의심해 봐야 한다. 이걸 테스트해 볼 수 있는 방법이 있을까?
=> 예를 들어 Randoms.pickNumberInRange(1,9); 면 1에서 9만 나오면 되는 건데 할 수 있겠는데??라는 생각을 했다가 큰코다쳤다 ㅠㅠ 운 좋게 테스트를 돌려서 그때만 1~9가 나왔을 수도 있고 내가 딱 실제 코드를 돌려보는데 0이 나올 수도 있는 걸 간과했다!!
전략 패턴을 사용하면 된다고 하는데 이해 부족으로 인해 적용을 못했다 ㅠㅠ 다음 미션까지 공부해서 꼭 적용해 볼 생각이다
후기
정말 재밌다!!!! 알아가는 것도 많고 지식이 늘어갈수록 그리고 그 지식을 적용해 볼수록 성장하는 내가 뿌듯하다!!
다음 미션은 과연 뭐가 나올까 정말 기대된다!
그리고 얼른 미션이 끝나서 다른 분들과 얘기해보고 싶다!! 그걸로 나는 더 성장할 수 있음에 너무 좋다.
'대외 활동 > 우아한테크코스 6기 BE' 카테고리의 다른 글
우아한테크코스 6기 4주차 프리코스 회고록 (0) | 2023.11.16 |
---|---|
우아한테크코스 6기 3주차 프리코스 회고록 (0) | 2023.11.09 |
우아한테크코스 6기 2주차 프리코스 회고록 (0) | 2023.11.02 |