프로그래밍 언어/<Java>영어단어장 project

3. java로 영어단어장 만들기, 테스트 부분 만들기와 메뉴 만들기(math.random(), switch())

창조적생각 2021. 7. 28. 15:07

<이전 내용>

 

새로운 단어를 외부에 저장하는 장치와 그 것을 불러 와 벡터에 저장하는 장치는 모두 만들었습니다.

아래에 링크를 달아 드릴테니 혹시 궁금한 점이 있다면 다시 가서 찾아 보는 것도 좋을 것입니다.

 

1. InputStreamReader,FileInputStream 를 이용한 메모장의 내용 불러오기, String 클래스의 split을 이용해 문자열 구분하여 배열로 만들기.

https://operstu1.tistory.com/53

 

1.java 메모장 읽어오기, 단어 구분하기, 벡터에 저장하기

<시작> java를 통해서 영어단어장을 만들어보는 프로젝트를 진행하고 있습니다. 이전에 배웠던 것들을 토대로 swing의 기능을 이용하여 단어장을 만들어보긴 했는데, 부족한 점도 많고, 스스로도

operstu1.tistory.com

 

2. FileWriter() 사용시의 인코딩 오류, OutputStreamWriter(),FileOutputStream()를 이용하여 메모장에 문자 저장하기

 

https://operstu1.tistory.com/54

 

2. java 단어장에 글 입력, 저장하기(FileWriter(),OutputStreamWriter(),FileOutputStream())

목차 1. 전체 코드 2. FileWriter()의 사용과 인코딩 오류 3. OutputStreamWriter(),FileOutputStream() 사용하기 4. 마치며... ☆ [완성된 입력 및 외부 저장 장치] 지난 번 java 단어장에 저장된 글을 읽어 오기..

operstu1.tistory.com

 

오늘은 벡터에 저장된 영어 단어와 뜻으로 객관식형 테스트를 만들어 볼 것입니다.

* 객관식형 테스트를 만드는 것은 명품 자바 프로그래밍 7장 오픈 챌린지를 참고하여 만들었습니다.

 

<목차>

●오늘의 전체 코드

 

1. 객관식 테스트 만들기(Math.random()을 이용한 중복없는 무작위 수 만들기, 보기 중에 정답 심기)

 

 1-1 makeExample()

 

 1-2 run()

 

2. 첫 시작 메뉴 만들기(swich()를 이용해 단어장 보기, 추가하기, 테스트하기, 종료하기 선택하는 화면 만들기)

 

 2-1 swithing_manu() 

 

3. 다음 시간에 알아볼 것

 

●오늘의 전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    private int makeExample(int ex[], int answerIndex) { //(1) 해설 바로 가기
        int n[] = {-1-1-1-1}; 
        int index;
        for(int i=0; i<n.length; i++) {
            do {
                index = (int)(Math.random()*v.size());
            } while(index == answerIndex || exists(n, index)); 
            n[i] = index;
        }
 
        for(int i=0; i<n.length; i++) ex[i] = n[i];
        return (int)(Math.random()*n.length); 
    }
 
    private boolean exists(int n[], int index) {
        for(int i=0; i<n.length; i++) {
            if(n[i] == index)
                return true;
        }
        return false;
    }
 
    public void run() { //(2) 해설 바로 가기
        
        System.out.println"단어 테스트를 시작합니다. -1을 입력하면 종료합니다.");
        System.out.println("현재 " + v.size() + "개의 단어가 들어 있습니다.");
        while(true) { 
            int answerIndex = (int)(Math.random()*v.size());
            String eng = v.get(answerIndex).getEnglish(); 
            
            
            int example[] = new int [4];
            
            int answerLoc = makeExample(example, answerIndex); 
            example[answerLoc] = answerIndex; 
 
            
            System.out.println(eng + "?");
            for(int i=0; i<example.length; i++)
                System.out.print("(" + (i+1+ ")" + v.get(example[i]).getKorean() + " ");
            
            System.out.print(":>"); 
            try {
                int in = sc.nextInt(); 
                if(in == -1) {
                    break
                }
 
                
                in--
                if(in == answerLoc)
                    System.out.println("잘하셨습니다. ");
                else
                    System.out.println("다시 생각해보세요.");
            }
            catch(InputMismatchException e) {
                sc.next(); 
                System.out.println("숫자를 입력하세요 !!");
                
            }
        }
        System.out.print("단어 테스트를 종료합니다...");        
            
    }
    
    void swiching_menu() { //(3) 해설 바로 가기
        Question_R();
        addvector();
        while(true) {
        System.out.println("성우의 단어장에 오신것을 환영합니다.");
        System.out.println("메뉴에서 시행할 작업을 선택해 주세요.");
        System.out.println("1. 단어장의 단어보기");
        System.out.println("2. 단어장에 단어 추가하기");
        System.out.println("3. 단어 시험 시작!");
        System.out.println("4. 종료하기");
        int select_menu = sc.nextInt();
        switch (select_menu) {
        case 1:
            
            for (int i = 0; i < v.size(); i++) {
                String M = v.get(i).getEnglish();
                String N =v.get(i).getKorean();
                System.out.println(M+"   "+N);
                }
            System.out.println(v.size()+"개의 단어가 있습니다.");
            break;
        case 2:
            System.out.println("영어 <Enter> 한글 <Enter> 형식으로 입력해주세요");
            Question_W();
            System.out.println("시스템을 껐다 켜면 반영이 됩니다.");
            
            break;
        case 3:
            
            run();
            break;
        case 4:
            System.out.println("단어장을 종료합니다. 수고하셨습니다.");
            System.exit(0);
            
        }
        }
    }
cs

 

[해설]

 

1. 객관식 테스트 만들기(Math.random()을 이용한 중복없는 무작위 수 만들기, 보기 중에 정답 심기)

객관식 테스트를 만드는데 그 목표는

 

  1. 문제로 영어 단어가 출력되어야 하고 보기로는 한글 뜻이 나와야 하며, 그 순서는 무작위로 한다.

 

  2. 보기는 4개여야 하며, 그 중 하나는 반드시 문제로 출력된 영어단어와 뜻이 일치해야 한다.

 

 3. 보기가 중복되어서는 안된다.

 

입니다.

 

그렇기에 중복되지 않는 무작위 수를 만드는 사용자 지정함수 int makeExample() 를 작성해줍니다.

 

1-1 makeExample()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 private int makeExample(int ex[], int answerIndex) { 
        int n[] = {-1-1-1-1}; 
        int index;
        for(int i=0; i<n.length; i++) {
            do {
                index = (int)(Math.random()*v.size());
            } while(index == answerIndex || exists(n, index)); 
            n[i] = index;
        }
        for(int i=0; i<n.length; i++) ex[i] = n[i];
        return (int)(Math.random()*n.length); 
    }
    private boolean exists(int n[], int index) { 
        for(int i=0; i<n.length; i++) {
            if(n[i] == index)
                return true;
        }
        return false;
    }
cs

>>1. int makeExample(int ex[], int answerIndex) 에서 int ex[]는 보기의 숫자들이 들어갈 int형 배열입니다.

 

>> int answerIndex는 문제로 나온 영어의 벡터 값과 같은 한글 뜻의 벡터값을 저장합니다.

 

 * 우리가 이전에 영어와 한글을 벡터에 함께 저장했던 것은 여기를 위한 것이었습니다.

 

>>2. int n[] = {-1-1-1-1}; int n[]을 초기화 해줍니다.

 

>>3. int index; 는 벡터의 순서를 랜덤으로 뽑아서 저장하기 위한 int형 변수입니다.

 

>>do{ 시행문 } while( 조건 ) 은 조건일 때까지 시행문을 시행하라는 명령입니다.

 

>>5.do {

    6.          index = (int)(Math.random()*v.size());

    7.      } while(index == answerIndex || exists(n, index));

는 해석해 보면 index에 vector의 번호에서 정수값으로 랜덤값을 뽑아내라. 단 그 값이 정답의 번호와 같거나, 이미 n 배열 안에 있어서는 안된다 입니다.

 

>>여기서  exists(n, index) 배열안에 값이 있는지 없는지를 알아내는 함수는 직접 작성해주셔야 합니다.

 

>>그래서 아래에 13. boolean exists(int n[], int index) 함수를 작성해줍니다.

 

>>14. for(int i=0; i<n.length; i++) {

    15.       if(n[i] == index)

    16.           return true;

    17.         }

    18.   return false;

는 n배열의 길이만큼 반복하여 n 배열 안에 index값이 있다면 참으로 반환, 그 외에는 거짓으로 반환하는 함수입니다.

 

>>8. n[i] = index; 

그렇게 해서 중복되지 않고, 정답의 번호를 가지지 않는 숫자index들을 n배열에 넣어줍니다.

 

>>10. for(int i=0; i<n.length; i++) ex[i] = n[i]; 그 숫자들을 다시 ex 배열로 옮겨줍니다.

 

>>11. return (int)(Math.random()*n.length); 그리고 함수 자체에 반환값으로 n길이 즉, 0~3 사이에서 무작위 정수를 받습니다.

 

* 이렇게 해서 보기 4개가 무작위로 중복되지 않게 출력되게 함수를 짰습니다.

[오늘의 코드에서 보기]

[완성된 코드에서 보기]

 

이제는 문제를 제시하고 보기가 출력되고 보기를 고르면 맞고 틀리고를 알려주는 함수를 작성해야 합니다.

 

1-2 run() 작성하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public void run() { 
        
        System.out.println"단어 테스트를 시작합니다. -1을 입력하면 종료합니다.");
        System.out.println("현재 " + v.size() + "개의 단어가 들어 있습니다.");
        while(true) { 
            int answerIndex = (int)(Math.random()*v.size());
            String eng = v.get(answerIndex).getEnglish();
            
            
            int example[] = new int [4];
            
            int answerLoc = makeExample(example, answerIndex);
            example[answerLoc] = answerIndex;
            
            System.out.println(eng + "?");
            for(int i=0; i<example.length; i++)
                System.out.print("(" + (i+1+ ")" + v.get(example[i]).getKorean() + " ");
            
            System.out.print(":>"); 
            try {
                int in = sc.nextInt(); 
                if(in == -1) {
                    break
                }
                
                in--
                if(in == answerLoc)
                    System.out.println("잘하셨습니다. ");
                else
                    System.out.println("다시 생각해보세요.");
            }
            catch(InputMismatchException e) {
                sc.next(); 
                System.out.println("숫자를 입력하세요 !!");
                
            }
        }
        System.out.print("단어 테스트를 종료합니다...");   
cs

 

>> 3~4번째 줄에는 단어테스트를 시행했을 시 커맨드에 대한 안내문이 출력되도록 했습니다.

 

>> 단어 테스트를 한 문제만 할 것이 아님으로 while(true) 5번째 줄부터 묶어두겠습니다.

 

>> 6. int answerIndex = (int)(Math.random()*v.size()); 정답이 들어있는 벡터의 번호를 무작위로 생성합니다.

 

** int answerIndex는 int makeExample(int ex[], int answerIndex)에서 정답이 들어있는 벡터의 번호로 정의했습니다.

 

>>7. String eng = v.get(answerIndex).getEnglish();  그리고 정답 번호의 벡터에 있는 영어 문제를 가지고 옵니다.

 

>>10. int example[] = new int [4];

            

    12.        int answerLoc = makeExample(example, answerIndex);

    13.        example[answerLoc] = answerIndex;

10~13 번째 줄은 이제 int makeExample(int ex[], int answerIndex) 함수에서 만들었던 보기를 섞는 알고리듬을 이용하여 보기를 만드는 것입니다. example 배열에 makeExample()의 알고리듬에 의해 보기를 만듭니다.

 

>> 12. int answerLoc = makeExample(example, answerIndex); 는 makeExample의 리턴 값을 정답의 위치로 만들기 위해서 사용합니다. 바로 아래에

13. example[answerLoc] = answerIndex;를 보면 알 수 있습니다.

 

>> 이제 문제와 보기를 출력합니다.

 15.     System.out.println(eng + "?");

 16.          for(int i=0; i<example.length; i++)

 17.               System.out.print("(" + (i+1+ ")" + v.get(example[i]).getKorean() + " ");

 

>> 정답 번호를 입력할 수 있는 입력창을 만듭니다.

 System.out.print(":>"); 

>> 이제 입력을 받아 그 조건들에 맞게 결과값을 출력할 수 있는 조건식들과 오류를 잡기 위한 try catch만 하면 완성입니다.

try {

                int in = sc.nextInt(); 

                if(in == -1) {

                    break

                }

                

                in--

                if(in == answerLoc)

                    System.out.println("잘하셨습니다. ");

                else

                    System.out.println("다시 생각해보세요.");

            }

            catch(InputMismatchException e) {

                sc.next(); 

                System.out.println("숫자를 입력하세요 !!");

                

            }

        }

        System.out.print("단어 테스트를 종료합니다...");  

 

[오늘의 코드에서 보기]

[완성된 코드에서 보기]

 

 

2. 첫 시작 메뉴 만들기(swich()를 이용해 단어장 보기, 추가하기, 테스트하기, 종료하기 선택하는 화면 만들기)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void swiching_menu() {
        Question_R();
        addvector();
        while(true) {
        System.out.println("성우의 단어장에 오신것을 환영합니다.");
        System.out.println("메뉴에서 시행할 작업을 선택해 주세요.");
        System.out.println("1. 단어장의 단어보기");
        System.out.println("2. 단어장에 단어 추가하기");
        System.out.println("3. 단어 시험 시작!");
        System.out.println("4. 종료하기");
        int select_menu = sc.nextInt();
        switch (select_menu) {
        case 1:
            
            for (int i = 0; i < v.size(); i++) {
                String M = v.get(i).getEnglish();
                String N =v.get(i).getKorean();
                System.out.println(M+"   "+N);
                }
            System.out.println(v.size()+"개의 단어가 있습니다.");
            break;
        case 2:
            System.out.println("영어 <Enter> 한글 <Enter> 형식으로 입력해주세요");
            Question_W();
            System.out.println("시스템을 껐다 켜면 반영이 됩니다.");
            
            break;
        case 3:
            
            run();
            break;
        case 4:
            System.out.println("단어장을 종료합니다. 수고하셨습니다.");
            System.exit(0);
            
        }
        }
    }
cs

>>이제 간단하게 메뉴만 만들면 됩니다.

 

>>메모장을 불러오는 Question_R() 과 벡터로 만드는 addvector() 함수를 실행합니다.

 

>> 반복을 해야함으로 while로 묶어줍니다.

 

>> int select_menu를 입력 받아 switch (select_menu) 로 지정된 숫자의 메뉴로 가게 지정합니다.

 

>>1. 단어보기 에서는 벡터내의 모든 값들을 짝지어 출력해줍니다. 그리고 현재 단어 수가 얼마인지도 표기해줍니다.

 

>>2. 단어 추가는 사용하는 방법을 알려주고 Question_W()를 실행해 줍니다.

 

  다만, 추가된 단어는 다음 사용 시에 추가되어 나온다는 것을 명시해줍니다.

 

>>3. 단어 테스트는 run()함수를 시행해줍니다.

 

>>4. 단어장 종료를 위해 System.exit(0)를 작성합니다.

[오늘의 코드에서 보기]

[완성된 코드에서 보기]

 

☆ 중요한 부분은 다 완성되었습니다. 아직 소소한 오류들을 잡고 디테일을 잡아야 하지만 그 것은 좀 더 다음으로 미루고 다음시간에는 GUI, 그래픽을 이용하여 인터페이스를 구현하고 위 프로그램을 이식해보겠습니다.

 

*긴글 읽어주셔서 감사합니다.

**전체 코드는 너무 길어서 아래에 적어놓겠습니다.

***귀하의 앞길에 무한한 발전이 있기를 기원하겠습니다.

**** 실행결과는 아래에 사진으로 남기겠습니다.

[프로그램 전체 코드]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    import java.util.*;
import java.io.*;
class Word{
    private String english; 
    private String korean; 
    public Word(String english, String korean) {
        this.english = english;
        this.korean = korean;
    }
    public String getEnglish() { return english; }
    public String getKorean() { return korean; }
}
public class question_box {
    question_box(){
        
        swiching_menu();
    }
    Scanner sc = new Scanner(System.in);
    
    Vector<Word> v = new Vector<Word>();
    Vector<String> V_eng = new Vector<String>();
    Vector<String> V_kor = new Vector<String>();
    
    String meta ="";
 
    
    void Question_R() {
        InputStreamReader in = null;
        FileInputStream fin = null;
        try {
            fin = new FileInputStream("c:\\Temp\\test.txt");
            in = new InputStreamReader(fin,"UTF-8");
            int c;
            
            while((c = in.read()) != -1) {
                meta += (char)c;
            }
        
            fin.close();
            in.close();
        }
        catch(IOException e) {
            System.out.println("입출력오류");
        }
    }
    void addvector() {
        String [] tokens = meta.split("/");
        for(int i =0; i<tokens.length;i++) {
            if(i%2 == 0)
                V_eng.add(tokens[i]);
            else V_kor.add(tokens[i]);
                
        }
        for(int i =0; i < V_kor.size();i++) {
            String Kor = V_kor.get(i);
            String Eng = V_eng.get(i);
            v.add(new Word(Eng,Kor));
            
            
            
        }
        
    }
    void Question_W() {
        OutputStreamWriter out = null;
        FileOutputStream fos = null;
        
        try {
            fos = new FileOutputStream("c:\\Temp\\test.txt",true);
            out = new OutputStreamWriter(fos,"UTF-8");
            String in_eng = sc.next();
            String in_kor = sc.next();
            out.write("/");
            out.write(in_eng);
            out.write("/");
            out.write(in_kor);
            
            out.close();
        }
        catch(IOException e){
            System.out.println("입출력오류");
        }
    }
    private int makeExample(int ex[], int answerIndex) {
        int n[] = {-1-1-1-1}; 
        int index;
        for(int i=0; i<n.length; i++) {
            do {
                index = (int)(Math.random()*v.size());
            } while(index == answerIndex || exists(n, index)); 
            n[i] = index;
        }
 
        for(int i=0; i<n.length; i++) ex[i] = n[i];
        return (int)(Math.random()*n.length); 
    }
    public void run() {
        
        System.out.println"단어 테스트를 시작합니다. -1을 입력하면 종료합니다.");
        System.out.println("현재 " + v.size() + "개의 단어가 들어 있습니다.");
        while(true) { 
            int answerIndex = (int)(Math.random()*v.size());
            String eng = v.get(answerIndex).getEnglish();
            
            
            int example[] = new int [4];
            
            int answerLoc = makeExample(example, answerIndex);
            example[answerLoc] = answerIndex; 
 
            
            System.out.println(eng + "?");
            for(int i=0; i<example.length; i++)
                System.out.print("(" + (i+1+ ")" + v.get(example[i]).getKorean() + " ");
            
            System.out.print(":>"); 
            try {
                int in = sc.nextInt(); 
                if(in == -1) {
                    break
                }
 
                
                in--
                if(in == answerLoc)
                    System.out.println("잘하셨습니다. ");
                else
                    System.out.println("다시 생각해보세요.");
            }
            catch(InputMismatchException e) {
                sc.next(); 
                System.out.println("숫자를 입력하세요 !!");
                
            }
        }
        System.out.print("단어 테스트를 종료합니다...");        
            
    }
    
    
    private boolean exists(int n[], int index) {
        for(int i=0; i<n.length; i++) {
            if(n[i] == index)
                return true;
        }
        return false;
    }
    
    void swiching_menu() {
        Question_R();
        addvector();
        while(true) {
        System.out.println("성우의 단어장에 오신것을 환영합니다.");
        System.out.println("메뉴에서 시행할 작업을 선택해 주세요.");
        System.out.println("1. 단어장의 단어보기");
        System.out.println("2. 단어장에 단어 추가하기");
        System.out.println("3. 단어 시험 시작!");
        System.out.println("4. 종료하기");
        int select_menu = sc.nextInt();
        switch (select_menu) {
        case 1:
            
            for (int i = 0; i < v.size(); i++) {
                String M = v.get(i).getEnglish();
                String N =v.get(i).getKorean();
                System.out.println(M+"   "+N);
                }
            System.out.println(v.size()+"개의 단어가 있습니다.");
            break;
        case 2:
            System.out.println("영어 <Enter> 한글 <Enter> 형식으로 입력해주세요");
            Question_W();
            System.out.println("시스템을 껐다 켜면 반영이 됩니다.");
            
            break;
        case 3:
            
            run();
            break;
        case 4:
            System.out.println("단어장을 종료합니다. 수고하셨습니다.");
            System.exit(0);
            
        }
        }
    }
    
    
    
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new question_box();
        
    }
 
}
 
cs

 

 

[실행결과]

728x90