임의의 세자리 수를 맞춰 나가는 게임. 3자리수를 입력해서 같은수가 같은 자리에 있으면 strike, 다른 자리에 있으면 ball, 같은 수가 없으면 nothing이다.
조건 1) 세자리 수
조건 2) 1~9 숫자만 사용(0은 포함안됨)
조건 3) 중복된 수 없어야 함
조건 1) 메서드 하나의 크기가 10 line을 넘지 않아야한다.
조건 2) 메서드가 한가지의 일만 하도록 최대한 작게 만들어야 한다.
조건 3) indent가 2 이하여야 한다.
조건 4) 지역 변수만을 사용한다.
import java.util.Scanner;
public class Baseball {
private boolean chkNumber(String str) {
if (str.length() != 3) return false;
if (str.contains("0")) return false;
char a = str.charAt(0);
char b = str.charAt(1);
char c = str.charAt(2);
if (a != b && a != c && b != c) return true;
else return false;
}
private String randomNumber() {
String answer;
while (true) {
answer = (int) (Math.random() * 900) + 100 + "";
if (chkNumber(answer)) break;
}
return answer;
}
private String input() {
Scanner s = new Scanner(System.in);
String input;
while (true) {
System.out.print("input(3자리 수, 중복 불가, 1-9) >> ");
input = s.nextLine();
if (chkNumber(input)) break;
}
return input;
}
private void compare(String input, String answer) {
int strike = 0, ball = 0;
for (int i = 0; i < input.length(); i++) {
char c1 = input.charAt(i);
if (c1 == answer.charAt(i)) strike++;
else if (answer.contains(c1 + "")) ball++;
}
if (strike == 3) System.out.println("3 strike!! game success!");
else if (strike == 0 && ball == 0) System.out.println("nothing");
else System.out.printf("%2d strikes, %2d balls\n", strike, ball);
}
public void game() {
int cnt = 0;
String input = "";
String answer = randomNumber();
System.out.println("game start!");
while (!input.equals(answer)) {
input = input();
compare(input, answer);
System.out.println("도전 횟수 : " + ++cnt);
}
}
}
이렇게 세자리수를 각각 변수에 저장하니까 문제가 발생했다. 처음에는 boolean 변수를 선언해서 각 조건문마다 변수에 true or false를 초기화시켜줬었는데 그렇게 하게 되면 변수를 지정해 준 것 때문에 오류가 난다.
private boolean chkNumber(String str) {
boolean condition;
if (str.length() != 3) condition = false;
if (str.contains("0")) condition = false;
char a = str.charAt(0);
char b = str.charAt(1);
char c = str.charAt(2);
if (a != b && a != c && b != c) condition = true;
else condition = false;
return condition;
}
compare 메서드는 input값과 answer값을 비교하여 strike,ball,nothing을 판별하는 메서드이다. 이 메서드를 만드는데 시간을 가장 많이 쓴 것 같다. 먼저 for문을 이용해서 같은 인덱스에 같은 문자가 있으면 strike를 1 더하고, 다른 인덱시에 같은 문자가 있으면 ball에 1을 더했다. 그 후에, strike가 3이면 정답을 맞춘 것이므로 성공을 출력하고, strike, ball 둘 다 0이면 nothing을 출력, 그 이외는 strike와 ball수를 출력한다.
처음에는 매게변수를 input값 하나만 두고, 메서드 내에 answer값을 randomNumber메서드로 초기화한 후, 비교하였다. 하지만 이렇게 하면 큰 오류가 생긴다. compare메서드는 최종적으로 game메서드에서 사용되서 input값과 answer값이 같아질 때까지 계속 반복해서 사용될텐데 compare메서드 내에 answer값을 초기화 해버리면 반복문이 돌아갈 때마다 answer값이 달라질 것이기 때문이다. 왜 이렇게 코드를 짰었는지 지금 생각해보니까 이해가 안된다.
private void compare(String input, String answer) {
int strike = 0, ball = 0;
for (int i = 0; i < input.length(); i++) {
char c1 = input.charAt(i);
for (int j=0; j < answer.length(); j++) {
char c2 = input.char(j);
if (c1 == c2 && i == j) strike++;
else if (c1 == c2) ball++;
}
}
...
}