옹실이의 개발이야기

Java

Java 퀴즈 : 주어진 시간동안 문제 맞추는 O,X 퀴즈(멀티 쓰레드 활용)

옹실 2020. 11. 11. 21:56

Java의 IO, 멀티 쓰레드를 활용한 퀴즈 프로그램을 만들어보았다.
멀티 쓰레드는 시간 체크용(10초)으로 활용, Task라는 별도의 java 파일을 만들어 구현했다.

* 게임 방식 *
1인당 10초동안 주어진 10개의 문제를 많이 맞추는 사람이 이기는 방식

1. 팀 이름을 입력받은 후
2. 문제 리스트(단어로 나와있음) 파일 가져와서 랜덤으로 문제 출제
3. 맞추면 O, 틀리면 X 를 입력받아 O일때만 1점 점수 획득
4. 다음 사람을 위해 맞춘 문제는 원본 파일 리스트에서 삭제된다. 
5. 주어진 시간은 10초이며, 10초가 되면 문제가 다 출제되지 않았더라도 프로그램은 자동 종료된다.




  
1. 팀 이름 입력받기
팀 이름을 System.in으로 입력받고
System.out으로 팀 이름을 다시 확인시켜주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.*;
import java.util.*;
 
class  Quiz_Study2 {
    String fname = "Q.txt";
    BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
 
 
    void readTeam(){
        try{
            System.out.println("팀 이름 입력하세용");
            String teamName = br1.readLine();
            System.out.println("팀 이름: "+teamName);
        }catch(IOException ie){}
    }
cs

 

1번 실행결과 ▼

팀 이름을 oo 입력했다ㅎㅎ;

10초, 9초는 밑에서 설명하겠지만 멀티 쓰레드를 활용한 부분으로
퀴즈를 푸는동안 시간이 얼마나 남았는지 체크할 수 있도록 표기했다.

2. 문제가 적힌 Q.txt파일을 가져와서 문제를 읽고, 중복을 방지한다.
Q.txt 파일을 읽은 후 띄어쓰기를 제거해주고, TreeSet에 넣어 중복을 방지하는 작업을 했다.
중복방지 체크가 완료된 문제는 ArrayList에 넣어 사용했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TreeSet<String> tSet = new TreeSet<String>();
    ArrayList<String> list = new ArrayList<String>(); //중복방지한 문제 넣을 리스트
    
    BufferedReader br2;
    FileReader fr;
 
    void readFile(){
        String line = "";
        try{
            fr = new FileReader(fname);
            br2 = new BufferedReader(fr);
            while( (line=br2.readLine()) != null ){
                if( line != null ){ //문제 띄어쓰기제거
                    line = line.trim();
                }
                if( line.length() != 0 ){ //문제가 있다면 treeset에넣기
                    tSet.add(line); //중복ㄴㄴ
                }
            }
            for(String item : tSet) list.add(item); //중복되지않는 문제 list에 넣기
        }catch(FileNotFoundException fe){
        }catch(IOException ie){}
    }
 
cs

 

3. 문제를 랜덤으로 출제하기 위해 랜덤수를 구한 후 문제를 출제한다.(1인당 10문제)
랜덤수 역시 중복 방지를 위해 TreeSet 사용했다.
O, X 값을 입력받고 O일 때 1점을 획득, O가 아닌 다른 문자를 입력했을때는 점수 획득 실패시켰다. 

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
    TreeSet<Integer> tSetInt = new TreeSet<Integer>();
    int n;
    int score=0;
 
    void random(){
        Random r = new Random();
        int size = list.size();
        for(int i=0; i<10; i++){ //10문제니까 10번 랜덤으로뽑는다
            n = r.nextInt(size); //리스트에 있는 문제 수 중에서 랜덤수 뽑는다
            tSetInt.add(n); //중복수 제거를 위해 TreeSet에 랜덤수 넣음
            if( tSetInt.size() < 10 ){
                i--;
            }
        }
        for(int j : tSetInt){ //랜덤수에 해당하는 문제 출제
            System.out.println("문제: "+list.get(j));
 
            BufferedReader br3 = new BufferedReader(new InputStreamReader(System.in));
            try{
                String line = "";
                line = br3.readLine();
                if(line != null) line = line.trim(); //문제 띄어쓰기 제거
                if(line.equalsIgnoreCase("O")){
                    score++//o 입력하면 점수 증가
                    System.out.println("1점 획득!");
                    list.remove(j); //맞춘 문제 리스트에서 제거
                    write(); //리스트 다시 원본 파일에 덮어쓰기
                } else { //O를 제외한 모든 문자는 점수 획득X
                    System.out.println("점수획득 실패ㅠㅠ");
                }
            }catch(IOException ie){}
 
            if(j == tSetInt.size()){
                System.exit(0); //10문제 모두 출제 완료되면 프로그램 종료
            }
        }
    }
cs

맞춘 문제는 다음 사람을 위해 문제 리스트에서 제거한 후(arrayList의 remove 메소드 사용)
write()메소드를 이용해 원본 파일에 덮어 씌웠다.(write()는 밑에 나올 예정) 
리스트에 있는 문제가 모두 다 나오면 프로그램을 자동으로 종료시켰다.

4. 리스트 다시 원본 파일에 덮어씌우는 작업
FileWriter와 PrintWriter로 리스트 다시 원본파일에 덮어쓰기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    FileWriter fw;
    PrintWriter pw;
    void write(){
        try{
            fw = new FileWriter(fname, false); //뒤에 나오는 true/false는 autoflush
            pw = new PrintWriter(fw, true);
 
            overwrite();
            for(String item : list){
                fw.write(item); //파일에 리스트 덮어씌운다
            }
        }catch(FileNotFoundException fe){
        }catch(IOException ie){}
    }
 
    void overwrite(){
        for(String item : list){
            pw.println(item);
            pw.flush();
        }
    }
cs

 

5. Quiz_Study2_User2라는 클래스를 따로 만들고
   메인 메소드에서 멀티 쓰레드(10초 돌리기), 1~4번 메소드 호출해준다.

마지막에 메인 메소드만 넣은 클래스를 따로 만들고
10초 스톱워치 기능을 넣기 위해 멀티 쓰레드와 함께 작동시켰다.
(멀티 쓰레드는 Task라는 java 파일을 별도로 만들었음, 6번 참고)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Quiz_Study2_User2 {
    public static void main(String[] args) {
        Quiz_Study2 qs2 = new Quiz_Study2();
 
        // 6. 10초동안 퀴즈 프로그램이 돌아가게 만든다.(Multi Thread)
        Task t = new Task();
        Thread thread = new Thread(t);
        thread.start();
 
        qs2.readTeam();
        qs2.readFile();
        qs2.random();
 
    }
}
cs

 

6. 1인당 10초동안 게임을 진행하도록 멀티 쓰레드 파일을 만든다.
멀티 쓰레드는 Runnable을 활용했음
Thread.sleep(1000)로 10초동안 진행하게 만들고,
time이 0이 되는 순간 System.exit(-1) 으로 프로그램을 강제 종료시켰다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Task implements Runnable {
    //
    public void run(){
        int time = 10;
        while(true){
        System.out.println(time-- + "초");
        try{
            Thread.sleep(1000);
        }catch(Exception e){
        }
        if(time == 0System.exit(-1);
        }
    }
}
 
cs

 

퀴즈 프로그램 실행 전 문제 리스트 ▼
총 11개의 문제가 리스트에 있다.

 

퀴즈 프로그램 실행 ▼
내가 static 이라는 문제를 맞춰서 1점을 획득했다. 
멀티 쓰레드로 시간이 얼마나 남았는지 확인시켜준다.

 

퀴즈 프로그램 실행 후 문제 리스트 ▼
내가 static을 맞췄더니
Q.txt파일을 다시 열었을때 리스트에 static이 빠진 것을 확인할 수 있었다.