JAVA

[내일 배움 캠프, JAVA 달리기 반] Lv.3 단어 맞추기 게임

kimyongjun0129 2025. 4. 4. 17:58

1. 문제

 

 

 

2. 풀이

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Main {
    public static boolean contains(char[] array, char target) {
        for (char c : array) {
            if (c == target) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        String[] wordList = {
                "airplane", "apple", "arm", "bakery", "banana", "bank", "bean", "belt",
                "bicycle", "biography", "blackboard", "boat", "bowl", "broccoli", "bus",
                "car", "carrot", "chair", "cherry", "cinema", "class", "classroom",
                "cloud", "coat", "cucumber", "desk", "dictionary", "dress", "ear", "eye",
                "fog", "foot", "fork", "fruits", "hail", "hand", "head", "helicopter",
                "hospital", "ice", "jacket", "kettle", "knife", "leg", "lettuce",
                "library", "magazine", "mango", "melon", "motorcycle", "mouth",
                "newspaper", "nose", "notebook", "novel", "onion", "orange", "peach",
                "pharmacy", "pineapple", "plate", "pot", "potato", "rain", "shirt",
                "shoe", "shop", "sink", "skateboard", "ski", "skirt", "sky", "snow",
                "sock", "spinach", "spoon", "stationary", "stomach", "strawberry",
                "student", "sun", "supermarket", "sweater", "teacher", "thunderstorm",
                "tomato", "trousers", "truck", "vegetables", "vehicles", "watermelon", "wind"
        };

        Random random = new Random();
        Scanner scanner = new Scanner(System.in);

        String targetWord = wordList[random.nextInt(wordList.length)];
        int wordLength = targetWord.length();
        int remainingLives = 9;
        char[] guessedLetters = new char[wordLength];
        Arrays.fill(guessedLetters, '_');

        System.out.println("단어의 길이: " + wordLength + " 글자");

        while (remainingLives > 0) {
            System.out.print("알파벳 한 글자를 입력하세요: ");
            String inputStr = scanner.nextLine().toLowerCase(); // 대소문자 구분 없이 처리

            if (inputStr.isEmpty()) {
                System.out.println("글자를 입력해주세요.");
                continue;
            }
            if (inputStr.length() > 1) {
                System.out.println("한 글자만 입력하세요.");
                continue;
            }

            char inputChar = inputStr.charAt(0);

            if (!Character.isLetter(inputChar)) {
                System.out.println("알파벳을 입력하세요.");
                continue;
            }

            if (targetWord.indexOf(inputChar) == -1) { // 단어에 포함되지 않는 경우
                System.out.println("틀렸습니다!");
                remainingLives--;
                System.out.println("남은 목숨: " + remainingLives);
            } else if (contains(guessedLetters, inputChar)) {
                System.out.println("이미 입력한 글자입니다.");
            } else {
                for (int i = 0; i < wordLength; i++) {
                    if (targetWord.charAt(i) == inputChar) {
                        guessedLetters[i] = inputChar;
                    }
                }
                System.out.println("현재 상태: " + new String(guessedLetters));

                if (!contains(guessedLetters, '_')) {
                    System.out.println("🎉 Victory! 정답: " + targetWord);
                    break;
                }
            }

            if (remainingLives == 0) {
                System.out.println("💀 Game Over! 정답은 '" + targetWord + "'였습니다.");
            }
        }
        scanner.close();
    }
}

 

위 코드의 전체 로직 중, 이번 문제를 풀면서 공부했던 거 위주로 정리하겠다.

- Arrays.fill(배열, 초기화 값) : 배열의 모든 값을 지정한 값으로 초기화하는 Arrays class의 메서드이다. 

- " ".toLowerCase() : 문자열이 영어인 경우 대소문자 구분없이 다 소문자로 바꿔주는 문자열 메서드이다.

- " ".CharAt(index) : 문자열 중 특정 인덱스의 문자를 반환해주는 문자열 메서드이다. 

- Character.isLetter(Char c) : 문자가 알파벳(문자)인지 확인하는 Character class 메서드이다.

 

 

 

3. GPT 풀이

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        String[] wordList = {
                "airplane", "apple", "arm", "bakery", "banana", "bank", "bean", "belt",
                "bicycle", "biography", "blackboard", "boat", "bowl", "broccoli", "bus",
                "car", "carrot", "chair", "cherry", "cinema", "class", "classroom",
                "cloud", "coat", "cucumber", "desk", "dictionary", "dress", "ear", "eye",
                "fog", "foot", "fork", "fruits", "hail", "hand", "head", "helicopter",
                "hospital", "ice", "jacket", "kettle", "knife", "leg", "lettuce",
                "library", "magazine", "mango", "melon", "motorcycle", "mouth",
                "newspaper", "nose", "notebook", "novel", "onion", "orange", "peach",
                "pharmacy", "pineapple", "plate", "pot", "potato", "rain", "shirt",
                "shoe", "shop", "sink", "skateboard", "ski", "skirt", "sky", "snow",
                "sock", "spinach", "spoon", "stationary", "stomach", "strawberry",
                "student", "sun", "supermarket", "sweater", "teacher", "thunderstorm",
                "tomato", "trousers", "truck", "vegetables", "vehicles", "watermelon", "wind"
        };

        Scanner scanner = new Scanner(System.in);
        Random random = new Random();
        String targetWord = wordList[random.nextInt(wordList.length)];
        char[] guessedLetters = new char[targetWord.length()];
        Arrays.fill(guessedLetters, '_');
        int remainingLives = 9;

        System.out.println("단어의 길이: " + targetWord.length() + " 글자");

        while (remainingLives > 0) {
            printGameState(guessedLetters, remainingLives);
            System.out.print("알파벳 한 글자를 입력하세요: ");
            String inputStr = scanner.nextLine().toLowerCase();

            if (!isValidInput(inputStr, guessedLetters)) continue;

            char inputChar = inputStr.charAt(0);

            if (targetWord.indexOf(inputChar) == -1) {
                System.out.println("틀렸습니다!");
                remainingLives--;
            } else {
                updateGuessedLetters(targetWord, guessedLetters, inputChar);
            }

            if (String.valueOf(guessedLetters).equals(targetWord)) {
                System.out.println("🎉 Victory! 정답: " + targetWord);
                break;
            }
        }

        if (remainingLives == 0) {
            System.out.println("💀 Game Over! 정답은 '" + targetWord + "'였습니다.");
        }
        scanner.close();
    }

    private static boolean isValidInput(String inputStr, char[] guessedLetters) {
        if (inputStr.isEmpty()) {
            System.out.println("글자를 입력해주세요.");
            return false;
        }
        if (inputStr.length() > 1) {
            System.out.println("한 글자만 입력하세요.");
            return false;
        }
        char inputChar = inputStr.charAt(0);
        if (!Character.isLetter(inputChar)) {
            System.out.println("알파벳을 입력하세요.");
            return false;
        }
        if (new String(guessedLetters).indexOf(inputChar) != -1) {
            System.out.println("이미 입력한 글자입니다.");
            return false;
        }
        return true;
    }

    private static void updateGuessedLetters(String targetWord, char[] guessedLetters, char inputChar) {
        for (int i = 0; i < targetWord.length(); i++) {
            if (targetWord.charAt(i) == inputChar) {
                guessedLetters[i] = inputChar;
            }
        }
    }

    private static void printGameState(char[] guessedLetters, int remainingLives) {
        System.out.println("현재 상태: " + new String(guessedLetters));
        System.out.println("남은 목숨: " + remainingLives);
    }
}

내 코드를 GPT한테 리펙토링 시켰더니, 위와 같은 코드가 나왔다. 한 편 살펴보자.

  • 우선, 클래스 내 정적 메서드를 전부 메인 아래에 만들었다. → 메인코드를 우선으로 하여, 전체적인 코드의 흐름 파악 향상  ✅
  • updaetGuressedLetters, printGameState, isValidInput 메서드를 만들어서 기능 분리 → 가독성 및 유지보수성 향상 ✅
  • contains 메서드를 없애고 String.indexOf()를 활용 → 중복코드 제거 ✅

- String.indexOf(Char c or String d) : 문자열에서 특정 문자(c) 또는 문자열(d)이 처음으로 등장하는 위치(인덱스)를 반환하는 메서드이다. 만약 찾는 문자가 존재하지 않으면 -1을 반환한다.