이지은님의 블로그
[JAVA] 달리기반 퀘스트 - Lv3. 단어 맞추기 게임 본문
단어를 주어진 기회 안에 맞추는 게임을 만들어보세요
- 컴퓨터가 랜덤으로 영어단어를 선택합니다.
- 영어단어의 자리수를 알려줍니다.
- ex ) PICTURE = 7자리 ⇒ _ _ _ _ _ _ _
- 사용자는 A 부터 Z 까지의 알파벳 중에서 하나를 입력합니다.
- 입력값이 A-Z 사이의 알파벳이 아니라면 다시 입력을 받습니다
- 입력값이 한 글자가 아니라면 다시 입력을 받습니다
- 이미 입력했던 알파벳이라면 다시 입력을 받습니다.
- 입력값이 정답에 포함된 알파벳일 경우 해당 알파벳이 들어간 자리를 전부 보여주고, 다시 입력을 받습니다.
- ex ) 정답이 eyes 인 경우에 E 를 입력했을 때
- _ _ _ _ → E _ E _
- ex ) 정답이 eyes 인 경우에 E 를 입력했을 때
- 입력값이 정답에 포함되지 않은 알파벳일 경우 기회가 하나 차감되고, 다시 입력을 받습니다.
- 사용자가 9번 틀리면 게임오버됩니다.
- 게임오버 되기 전에 영어단어의 모든 자리를 알아내면 플레이어의 승리입니다.
▷ 구현과정 1 : 생성자 + 초기화, 사용할 변수
private int count;
private String[] wordList;
private int countLimit = 9;
private String queString;
private char[] hiddenWord;
private char[] ansWord;
private ArrayList<Character> ansList = new ArrayList<>();
사용할 변수는 다음과 같다.
변수 | 설명 | 사용 |
int count | 사용한 기회 | 0부터 시작 |
String[] wordList | 단어 맞추기 문제들 | 랜덤수를 뽑아서 문제를 랜덤추출 |
int countLimit | 사용할 수 있는 기회 | 고정된 수(final로 사용할 수 있음) |
String queString | 문제로 선정된 단어 | 랜덤 추출된 단어 |
char[] hiddenWord | 문제로 선정된 단어를 char자료형으로 저장 | 정답기준 |
char[] ansWord | 맞춘 알파벳을 char자료형으로 저장 | hiddenWord와 비교하여 정답판단 |
ArrayList<> ansList | 답한 알파벳을 저장 | 중복값 판단 |
public HangMan() {
count = 0;
wordList = new String[] {
"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"
};
int ran = (int) (Math.random()*(wordList.length));
queString = wordList[ran].toUpperCase();
hiddenWord = new char[queString.length()];
hiddenWord = queString.toCharArray();
ansWord = new char[queString.length()];
}
생성자는 다음과 같다. 클래스가 한번 선언될때 게임 한번, 정답이 될 수 있는 단어 하나이므로, 생성자에 문제가 될 단어를 지정해주도록 했다. 랜덤 수를 뽑아서 대문자로 만들어 queString에 저장한다.
그리고 정답의 기준이 될 hiddenWord에 정답인 단어를 queString.toCharArray()를 이용해 char배열의 형태로 저장해준다.
내가 맞춘 답은 ansWord에 변수 선언을 해준다. 이후 ansWord에 내가 맞춘 알파벳을 저장함으로 정답을 맞출 것이다.
▷ 구현과정 2 : 메인 실행
public void run(){
Scanner sc = new Scanner(System.in);
System.out.println("*** 단어 맞추기 게임을 시작합니다. ***");
while(true){
System.out.println();
questPrint();
System.out.println("현재 남은 기회: "+(countLimit-count));
System.out.print("A-Z 중 하나를 입력하세요 >> ");
String s = sc.nextLine();
if(s.equals("그만")){
System.out.println("[안내] 단어 맞추기 게임을 종료합니다.");
break;
} else if(s.length() != 1){
System.out.println("[안내] 알파벳 하나를 입력해주세요.");
continue;
}
char c = s.charAt(0);
if(!Character.isLetter(c)) {
System.out.println("[안내] 알파벳을 입력해주세요.");
continue;
}
if(!Character.isUpperCase(c)) c = Character.toUpperCase(c);
if(isDupli(c)){
System.out.println("[안내] 이미 입력한 알파벳입니다.");
continue;
}
ansList.add(c);
jubge(c);
if(complete()){
System.out.print("정답입니다! ");
questPrint();
break;
}
else if((countLimit-count)==0){
System.out.println();
System.out.println("정답은 " + queString);
System.out.println("기회를 모두 소진했습니다. 게임을 종료합니다.");
break;
}
}
sc.close();
}
크게 현재상황 출력, 알파벳 입력, 입력한 알파벳 판단, 답인지 판단, 문제해결 성공 및 실패 판단 으로 나뉘어 있다. 모두 메소드 단위로 실행 시킬 수 있을 것 같지만 문제를 해결하는데 집중했으므로 코드를 그대로 쓰기로 했다.
(1) 현재상황 출력
// (1) 현재 상황 출력
questPrint(); // 문제 상황 출력
System.out.println("현재 남은 기회: "+(countLimit-count));
questPrint()는 작성한 메소드로 자세한 기능은 나중에 후술하도록 하겠다. 문제와 기회를 출력하도록 했다.
(2) 알파벳 입력
System.out.print("A-Z 중 하나를 입력하세요 >> ");
String s = sc.nextLine();
Scanner를 이용하여 알파벳을 입력하도록 했다.
(3) 입력한 알파벳의 판단
if(s.equals("그만")){
System.out.println("[안내] 단어 맞추기 게임을 종료합니다.");
break;
} else if(s.length() != 1){
System.out.println("[안내] 알파벳 하나를 입력해주세요.");
continue;
}
char c = s.charAt(0);
if(!Character.isLetter(c)) {
System.out.println("[안내] 알파벳을 입력해주세요.");
continue;
}
if(!Character.isUpperCase(c)) c = Character.toUpperCase(c);
if(isDupli(c)){
System.out.println("[안내] 이미 입력한 알파벳입니다.");
continue;
}
의도에 맞추어 알파벳을 입력했는지 조건문을 통해 검사하는 부분이다.
1) "그만"이라는 입력을 받으면 단어맞추기 게임을 바로 종료할 수 있다.
2) 입력받은 문자열이 1단어가 아닐 때 알파벳 하나를 입력해달라는 안내문구를 출력한다.
이후 입력받은 문자열을 한 단어 char로 바꾸며
3) 알파벳이 아닐 경우, 알파벳을 입력해달라는 안내문구를 출력한다.
4) 소문자를 입력했을 경우, 대문자로 바꾼다. (문제를 출력할때 대문자의 형태로 출력하기 때문에 기준을 대문자로 바꾸었다.)
5) 이미 입력했던 알파벳일 경우, 이미 입력한 알파벳이라는 안내문구를 출력한다.(isDuplic()은 이후 후술)
(4) 답 판단
jubge(c);
이 메소드 또한 후술로 설명하도록 하겠다. hiddenWord에 내가 작성한 알파벳이 맞는지 확인 할 수 있다.
(5) 문제 해결 성공 및 실패 판단
if(complete()){
System.out.print("정답입니다! ");
questPrint();
break;
}
else if((countLimit-count)==0){
System.out.println();
System.out.println("정답은 " + queString);
System.out.println("기회를 모두 소진했습니다. 게임을 종료합니다.");
break;
}
정답일 경우 현재 문제 상황을 출력하고 break문으로 반복문을 빠져나온다.
만약 할당된 기회를 모두 소진 했다면 정답과 함께 게임을 종료한다.
▷ 구현과정 3 : 현재 문제 상황 출력 메소드 - questPrint()
public void questPrint(){
System.out.print("[ ");
for(int i = 0 ; i<hiddenWord.length;i++){
if (hiddenWord[i] == ansWord[i]){
System.out.print(" \'" + ansWord[i] + "\' ");
}
else System.out.print(" \'__\' ");
}
System.out.println("]");
}
hiddenWord와 ansWord를 비교하여 현재 문제 상황을 출력한다.
위 스크린샷은 hiddenWord에 HELICOPTER가, ansWord에는 -ELI----ER(-은 NULL)가 저장되어 있을 때 출력된다.
▷ 구현과정 4 : 중복값 판단 메소드 - isDuplic(Char c)
public boolean isDupli(Character c){
for (Character ch : ansList) {
if (ch.equals(c)) {
return true;
}
}
return false;
}
앞서 ansList를 ArrayList의 형태로 선언한 적이 있다. 알파벳을 입력하면서 ansList.add(c)로 계속 입력한 알파벳을 어레이리스트에 추가했는데 그 이유가 앞서 입력한 알파벳을 입력했는지를 판단하기 위해서다.
해당 메소드에서 for-each반복문을 통해 앞서 입력했던 알파벳과 이번 라운드에 입력한 알파벳이 같은지를 판단하고 이를 참 또는 거짓으로 리턴한다. 앞에 입력했던 알파벳을 또 입력했다면 다시 입력해달라는 안내문구가 뜬다.
▷ 구현과정 5 : 답 판단 - judge(Char c)
public void jubge(Character c){
int chance = 0;
for(int i = 0; i<hiddenWord.length;i++){
if(hiddenWord[i]==c){
ansWord[i] = c;
chance++;
}
}
if(chance==0){
count++;
System.out.println("정답에 포함된 알파벳이 아닙니다. 기회가 1 차감됩니다.");
} else{
questPrint();
}
}
입력한 알파벳이 정답 단어에 포함되는지 판단하는 메소드다. 포함이 된다면 ansWord에 입력한 알파벳을 저장하고 chance를 1증가하게 한다.(참-거짓 자료형으로 해도 됨) 만약 chance가 0이라면 정답단어에 포함이 되지 않는다는 뜻이므로 기회를 소진한다. 정답이라면 기회를 소진 하지 않고 맞춘 상황을 프린트한다.
▷ 구현과정 6 : 문제 해결 성공 판단 메소드 - complete()
public boolean complete(){
int comCount = 0;
for(int i = 0; i<ansWord.length; i++){
if(ansWord[i] != '\0') comCount++;
}
if(comCount == ansWord.length) return true;
else return false;
}
정답으로 입력된 ansWord에서 모든 배열에 null값이 없다면 comCount를 증가시킨다. comCount가 ansWord의 크기와 같다면 모든 알파벳을 맞췄다는 뜻이므로 참값을 리턴한다. 이후 정답을 맞췄다는 안내문구와함께 게임을 종료한다.
전체 코드
import java.util.ArrayList;
import java.util.Scanner;
class HangMan {
private int count;
private String[] wordList;
private int countLimit = 9;
private String queString;
private char[] hiddenWord;
private char[] ansWord;
private ArrayList<Character> ansList = new ArrayList<>();
public HangMan() {
count = 0;
wordList = new String[] {
"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"
};
int ran = (int) (Math.random()*(wordList.length));
queString = wordList[ran].toUpperCase();
hiddenWord = new char[queString.length()];
hiddenWord = queString.toCharArray();
ansWord = new char[queString.length()];
}
public void questPrint(){
System.out.print("[ ");
for(int i = 0 ; i<hiddenWord.length;i++){
if (hiddenWord[i] == ansWord[i]){
System.out.print(" \'" + ansWord[i] + "\' ");
}
else System.out.print(" \'__\' ");
}
System.out.println("]");
}
public void jubge(Character c){
int chance = 0;
for(int i = 0; i<hiddenWord.length;i++){
if(hiddenWord[i]==c){
ansWord[i] = c;
chance++;
}
}
if(chance==0){
count++;
System.out.println("정답에 포함된 알파벳이 아닙니다. 기회가 1 차감됩니다.");
} else{
questPrint();
}
}
public boolean isDupli(Character c){
for (Character ch : ansList) {
if (ch.equals(c)) {
return true;
}
}
return false;
}
public boolean complete(){
int comCount = 0;
for(int i = 0; i<ansWord.length; i++){
if(ansWord[i] != '\0') comCount++;
}
if(comCount == ansWord.length) return true;
else return false;
}
public void run(){
Scanner sc = new Scanner(System.in);
System.out.println("*** 단어 맞추기 게임을 시작합니다. ***");
while(true){
System.out.println();
questPrint();
System.out.println("현재 남은 기회: "+(countLimit-count));
System.out.print("A-Z 중 하나를 입력하세요 >> ");
String s = sc.nextLine();
if(s.equals("그만")){
System.out.println("[안내] 단어 맞추기 게임을 종료합니다.");
break;
} else if(s.length() != 1){
System.out.println("[안내] 알파벳 하나를 입력해주세요.");
continue;
}
char c = s.charAt(0);
if(!Character.isLetter(c)) {
System.out.println("[안내] 알파벳을 입력해주세요.");
continue;
}
if(!Character.isUpperCase(c)) c = Character.toUpperCase(c);
if(isDupli(c)){
System.out.println("[안내] 이미 입력한 알파벳입니다.");
continue;
}
ansList.add(c);
jubge(c);
if(complete()){
System.out.print("정답입니다! ");
questPrint();
break;
}
else if((countLimit-count)==0){
System.out.println();
System.out.println("정답은 " + queString);
System.out.println("기회를 모두 소진했습니다. 게임을 종료합니다.");
break;
}
}
sc.close();
}
}
public class run_3 {
public static void main(String[] args) {
HangMan hm = new HangMan();
hm.run();
}
}
'사전캠프 퀘스트' 카테고리의 다른 글
[JAVA] 달리기반 퀘스트 - 보너스 문제: 가위 바위 보 (0) | 2024.12.18 |
---|---|
[JAVA] 달리기반 퀘스트 - Lv2. 스파르타 자판기 (0) | 2024.12.17 |
[JAVA] 달리기반 퀘스트 - Lv1. 랜덤 닉네임 생성기 (0) | 2024.12.06 |
[JAVA] 걷기반 퀘스트 (0) | 2024.12.06 |
달리기반 퀘스트 - Lv5. 예산이 가장 큰 프로젝트는? (0) | 2024.12.02 |