코드 그라데이션

230327 숫자야구 배열에서 궁금증 해결 본문

Java, SpringBoot 추가 공부

230327 숫자야구 배열에서 궁금증 해결

완벽한 장면 2023. 3. 28. 22:43

숫자야구 배열 코드

package megait.backend_lecture.Day08;

import java.util.Random;
import java.util.Scanner;
//배열 숫자 야구

//1. 컴퓨터 랜덤 숫자 생성 단, 중복제거 필요
//2. 유저 숫자 입력 단, 1~9값만 허용, 중복허용 X
//3. 컴퓨터 랜덤 숫자와 유저 입력 숫자 비교
//3-1. 자리와 숫자가 같으면 strike
//3-2. 숫자는 같지만 자리가 다르면 ball
//3-3. strike, ball이 없으면 out
//3-4. 3 strike -> 홈런 프로그램 종료
//3-5. 홈런이 나오기 전까지는 strike ball을 출력 or out 출력

public class BaseballArray_T {

  public static void main(String[] args) {
    Random r = new Random();
    Scanner sc = new Scanner(System.in);
    // 값 저장할 배열 생성
    int[] com = new int[3];
    int[] user = new int[3];

    //1. 컴퓨터 랜덤 숫자 생성 단, 중복제거 필요
    // 1-1. 랜덤수 생성
    for (int i = 0; i < com.length; i++) {
      com[i] = r.nextInt(9) + 1;

      // 1-2. 두 번재 반복문 생성 : 숫자 중복 방지를 위한 검사
      for (int j = 0; j < i; j++) {
        if (com[i] == com[j]) {
          i--;
          break;
        }
      }
    }
    System.out.println(com[0] + ", " + com[1] + ", " + com[2]); // 정답 숫자 출력

    //3. 컴퓨터 랜덤 숫자와 유저 입력 숫자 비교
    int strike = 0;
    int ball = 0; // 카운트 변수 미리 초기화

    while (strike < 3) {
      for (int i = 0; i < user.length; i++) {
        System.out.println((i + 1) + "번째 숫자 입력 : ");
        user[i] = sc.nextInt();

        // 범위가 잘못된 경우(1~9가 x)
        if (user[i] < 1 || user[i] > 9) {
          System.out.println("잘못된 입력입니다."); // 헷갈리지 않으려면 "범위를 벗어났습니다."
          i--; // 횟수에서 제외
          continue; // 다시 입력받도록 함.
        }

        // 값이 중복된 경우
        for (int j = 0; j < i; j++) {
          if (user[i] == user[j]) {
            System.out.println("잘못된 입력입니다."); // 헷갈리지 않으려면 "값이 중복됩니다. 다시 입력해야 합니다."
            i--; // 횟수에서 차감
            break; // 값이 중복된 경우 이후에 검사할 필요가 없으므로 반복문 탈출(다시 입력하는 곳으로 가겠네)
          }
        }
      }
      //3-1. 자리와 숫자가 같으면 strike
      //3-2. 숫자는 같지만 자리가 다르면 ball
      strike = 0;
      ball = 0;
      // 현재 조건,
      //  숫자 && 자리  => 스트라이크 / 숫자 같으면 => 볼
      // 여기서 공통된 것은 숫자!. 그래서 숫자를 보는 거다.
      for (int i = 0; i < user.length; i++) {
        for (int j = 0; j < com.length; j++) {
          if (user[i] == com[j]) { // 숫자가 같으면
            if (i == j) { // (숫자 +)자리까지 같으면
              strike++;
            } else { // 숫자만 같고 자리가 다르면,
              ball++;
            }
          }
        }
      }
      //3-3. 3-4. 3-5
      // if-else if로 묶을 수 있음.
      if(strike == 0 && ball == 0) { // 모두 겹치는 게 없으면
        System.out.println("OUT 입니다.");
      }
      else if(strike == 3) { // 모두 겹친다면
        System.out.println("홈런입니다.");
      }
      else { // 겹치는 게 있으나 스트라이크가 아닌 경우
        System.out.println("strike : "+strike+", ball : "+ball);
      }

    }

  }
}

 

질문 1. 
 1. 랜덤 수 생성 부분에서  두 번째 for문에서 조건식이 j<i인 이유(의미)
 


요기서 i가 의미하는 건, 몇 번째 뽑힌 숫자인지이다.
중복 제거를 하려면, 뽑힌 수를 몽땅 다 검사해야한다!!!
그러니까, 0부터 나 앞에 있는 수까지(나 직전)까지
그 의미가 j<i
// 0       i-1  i // 지금 i-1이 j가 된 것
// 5  4  2  1  3

그래서
if (com[i] == com[j]) { // com[i] : 지금의 나 , com[j] : 과거에 뽑혔던 수
          i--; // 중에서 중복이 하나라도 있으면, i의 카운트 하지 말고 다시 뽑아라!!

 for (int j = 0; j < i; j++) { // 이것도, 나 직전까지라고 했으니까
  for (int j = 1; j < i-1; j++) { // 이렇게 리펙토링해도 무방하다.


  더 쉽게 이해하자면 한 번에 하지 말고, 아예 변수를 새로 초기화 해서 더 직관적으로 보이게 만들수도 있다.
      for (int i = 0; i < com.length; i++) {
      com[i] = r.nextInt(9) + 1;
      int now = com[i];

      for (int j = 0; j < i; j++) {
        int before = com[j]
        if (now == before) {
          i--;
          break;

          이렇게 리펙토링도 가능하다.

          정리하자면, 바깥쪽 for문은 숫자를 뽑기 위한 반복문.
          안쪽 for문은 여태까지 뽑힌 수 중에 중복이 있는지를 전부 검사하기 위한 반복문.
          이렇게 정리할 수 있다.

 

질문 2.

while(strike<3) 안쪽의 for문에서
  첫 번째(i) for문은 continue; 이고
  두 번째(j) for문은 break; 가 사용되었는데,
  어쨌든 둘 다 실행이 되면
  user[i] = sc.nextInt(); 부분으로 가게 되는지
  
  
  정확하다.

 

 

질문 3. strike, ball 판별하는 for문에서
  user 배열이 com 배열보다 바깥쪽에 있는 이유는 무엇인가?

사실 정답인지(strike)만 확인하려면 중첩 for문이 사실 필요가 없다.
그런데 ball까지 판단해야 하므로 필요한 것인데
지금 user에 뽑은 각 요소를 기준으로 한바퀴 돌면서 같은 수가 있는지를 비교하는 매커니즘이잖아 숫자야구가.
사실 어떤 것을 기준으로 비교해도 상관은 없으니까.
그냥 아까처럼 두 개를 비교해야 하므로 이중  for문을 썼다. 이 수준으로 정리하고 넘어가면 된다.

 

728x90
Comments