Skip to content

Instantly share code, notes, and snippets.

@argius
Created Dec 4, 2015
Embed
What would you like to do?
コマンドラインのQuizゲーム (Java 7 and later)
package quiz;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public final class Quiz {
static PrintStream out = System.out;
public static void main(String[] args) {
// 準備
List<Question> questions = readQuestions(args);
final int qCount = questions.size();
// 質問をランダムに
Collections.shuffle(questions);
// 質問番号
int qNumber = 0;
// 正答数
int passedCount = 0;
// 開始
out.println("*** クイズゲーム ***");
out.printf("全%d題%n", qCount);
out.println();
for (Question q : questions) {
++qNumber;
if (question(qNumber, q)) {
++passedCount;
}
}
// 終了
out.println("終了。");
out.printf("正答率 %.1f %% (%d/%d)%n", passedCount * 100f / qCount, passedCount, qCount);
}
static boolean question(int qNumber, Question q) {
List<String> wrongAnswers = q.getWrongAnswers();
// 選択肢数の計算
final int choiceCount = wrongAnswers.size() + 1;
String choiceChars = "ABCDEFGHIJ".substring(0, choiceCount);
List<String> numbers = Arrays.asList(choiceChars.split(""));
Collections.shuffle(numbers);
String correctNumber = numbers.get(0); // 正解の番号
// 表示用の選択肢
List<String> choices = new ArrayList<>();
// 先に正解を追加
choices.add(String.format("%s. %s", correctNumber, q.getCorrectAnswer()));
// 不正解を追加
int i = 0;
for (String wrong : wrongAnswers) {
++i;
choices.add(String.format("%s. %s", numbers.get(i), wrong));
}
// 番号順に並べ直す
Collections.sort(choices);
// 出題
out.printf("[第%d問] %s%n", qNumber, q.getSentence());
for (String choice : choices) {
out.println(" " + choice);
}
out.println();
String choicedNumber;
while (true) {
choicedNumber = readLine("答え > ").toUpperCase();
if (numbers.contains(choicedNumber)) {
break;
}
out.println("正しい選択肢を入力してください。");
}
boolean correct = choicedNumber.equals(correctNumber);
out.println(correct ? "正解!!!" : "不正解!!!");
out.println();
out.println();
return correct;
}
static String readLine(String fmt, Object... args) {
out.printf(fmt, args);
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
return scanner.nextLine();
}
static List<Question> readQuestions(String... paths) {
List<Question> a = new ArrayList<>();
for (String pathString : paths) {
Path path = Paths.get(pathString);
if (!Files.isRegularFile(path)) {
out.printf(" 警告: ファイル[%s]は見つかりません。%n%n", path);
continue;
}
Queue<String> lines;
try {
lines = new LinkedList<>(Files.readAllLines(path, StandardCharsets.UTF_8));
} catch (IOException e) {
out.printf(" 警告: ファイル[%s]読み取り中にエラーが発生しました。 (%s)%n%n", path, e);
continue;
}
while (!lines.isEmpty()) {
String sentence = lines.poll();
String correctAnswer = lines.poll();
List<String> wrongAnswers = new ArrayList<>();
while (true) {
if (lines.isEmpty()) {
break;
}
final String line = lines.poll();
if (line.matches("\\s*")) {
break;
}
wrongAnswers.add(line);
}
if (sentence == null || correctAnswer == null || wrongAnswers.isEmpty()) {
out.printf(" 警告: ファイル[%s]の途中の不正なフォーマットをスキップします。%n%n", path);
}
else {
a.add(new Question(sentence, correctAnswer, wrongAnswers));
}
}
}
return a;
}
}
class Question {
private final String sentence;
private final String correctAnswer;
private final List<String> wrongAnswers;
public Question(String sentence, String correctAnswer, String... wrongAnswers) {
this(sentence, correctAnswer, Arrays.asList(wrongAnswers));
}
public Question(String sentence, String correctAnswer, List<String> wrongAnswers) {
this.sentence = sentence;
this.correctAnswer = correctAnswer;
this.wrongAnswers = wrongAnswers;
}
public String getSentence() {
return sentence;
}
public String getCorrectAnswer() {
return correctAnswer;
}
public List<String> getWrongAnswers() {
return wrongAnswers;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment