[플레이그라운드] TDD, 클린 코드 (2) - 숫자야구게임 구현
2023, Sep 20
기능별 구현내용을 정리해보겠음
전체코드
https://github.com/Kyuyoung11/java-baseball-playground/tree/firstTry
[기능목록]
- 난수 3개 생성
- 입력 받고 정답 확인
2-1. 볼인지 스트라이크인지 분류
1. 난수 3개 생성
처음 생각한 흐름
- ArrayList의 .contains를 이용해 중복을 제거하려고 했음 -> while문안에 if가 들어가니 인덴트 1에서 막힘
-> 자료구조 라이브러리를 이용해서 해결해보기로 결정
최종 흐름
- HashSet을 사용하면 중복없이 들어갈테니 구현 → 순서가 보장되지않아서 안됨
-
구글링해보니 LinkedHashSet이 중복x, 순서보장o라고 하길래 사용 → 됨!
https://doompok.tistory.com/6private LinkedHashSet<Integer> _makeRandomNumbers() { LinkedHashSet<Integer> randomNums = new LinkedHashSet<Integer>(); Random rd = new Random(); while (randomNums.size()<3) { randomNums.add(rd.nextInt(9)); } return randomNums; }
2. 입력 받고 정답 확인
처음 생각한 흐름
while(true) {
//1. 숫자 입력 받기
//2. ball or strike 확인
// 2-1. if) strike인지 확인, 카운트
// 2-2. else) ball인지 확인, 카운트
//3. 카운트 결과 print
//4. 3 스트라이크이면, break
}
문제점
- 인덴트 1 못지킴
- else 사용
최종 흐름
- 인덴트 1 못지킴 -> 정답확인 부분 메소드 추출
- else 사용 -> strike/ball 분류 및 카운트 메소드 추출
public void init() {
LinkedHashSet<Integer> randomNums = makeRandomNumbers();
boolean flag = false;
while(!flag) {
//1. 숫자 입력 받기
String numString = _getInputNumString();
flag = tryAnswer(numString, randomNums);
}
...
}
public boolean tryAnswer(String numString, LinkedHashSet<Integer> randomNums) {
HashMap<String, Integer> count = new HashMap<>();
count.put("ball", 0);
count.put("strike", 0);
for (int i=0; i<numString.length(); i++) {
Integer num = Integer.parseInt(numString.substring(i,i+1));
//2. ball or strike 확인
_countBallOrStrike(count, randomNums, num, i);
}
//3. 카운트 결과 print
_printResult(count);
//4. 3 스트라이크 check
return count.get("strike") == SIZE;
}
strike/ball 분류
고민 내용
- 어떻게 하면 분류랑 카운트를 같이할 수 있을까
→ 카운트용 Map 활용하는 방법으로 가기로 결정 (call by reference 방식으로 하는게 썩 마음에 들진 않지만….) - strike를 체크하려면 index값이 필요
→ parameter가 너무 많아지는 것 같지만… 일단 이렇게 하고 피드백 강의를 보기로 결정
private void _countBallOrStrike(HashMap<String, Integer> count, LinkedHashSet<Integer> randomNums, Integer num, int index) {
Integer[] randomNumArray = randomNums.toArray(new Integer[randomNums.size()]);
if (randomNumArray[index] == num) {
count.put("strike",count.get("strike")+1);
return;
}
if (randomNums.contains(num)) {
count.put("ball", count.get("ball")+1);
}
}
개선할 점
- 상수를 사용할거면 final로 하기
- 재시작 입력도 메소드를 분리하기
- 의미있는 변수명을 사용하기
- 클래스 나누기
생활체조 지키는거 너무 어렵다… 흣차흣차