103 lines
4.4 KiB
C#
103 lines
4.4 KiB
C#
namespace Game.Data {
|
|
public class Database {
|
|
public List<Question> questions = new List<Question>();
|
|
public static Database ReadFromFile(string filename) {
|
|
var db = new Database();
|
|
using (StreamReader rd = new StreamReader(filename)) {
|
|
string? line;
|
|
int lineNumber = 1;
|
|
while ((line = rd.ReadLine()) != null) {
|
|
int i = 0;
|
|
int len = line.Length;
|
|
int state = 0;
|
|
int correctAnswer = -1;
|
|
List<string> answers = new List<string>();
|
|
|
|
// read question
|
|
while (i < len + 1) {
|
|
if (i == len) {
|
|
throw new DatabaseReadException(I18n.Message.ERROR_NO_ANSWER_OPTIONS, lineNumber, i);
|
|
} else if (line[i] == '|')
|
|
if (state == 1) {
|
|
++i;
|
|
break;
|
|
} else {
|
|
state = 1;
|
|
}
|
|
else state = 0;
|
|
++i;
|
|
}
|
|
string question = line.Substring(0, i - 2);
|
|
|
|
int currentAnswer = 0;
|
|
while (i < len) {
|
|
// read answer text
|
|
state = 0;
|
|
int answerStart = i;
|
|
while (i < len + 1) {
|
|
if (i == len) {
|
|
throw new DatabaseReadException(I18n.Message.ERROR_EXPECTED_ARROW_TOKEN, lineNumber, i);
|
|
} else if (state == 0) {
|
|
if (line[i] == '=')
|
|
state = 1;
|
|
} else if (state == 1) {
|
|
if (line[i] == '>') {
|
|
++i;
|
|
break;
|
|
} else {
|
|
state = 0;
|
|
}
|
|
}
|
|
++i;
|
|
}
|
|
string answer = line.Substring(answerStart, i - answerStart - 2);
|
|
// read True or False
|
|
if (line[i] == 'T') {
|
|
if (i + 3 < len && line[i + 1] == 'r' && line[i + 2] == 'u' && line[i + 3] == 'e') {
|
|
correctAnswer = currentAnswer;
|
|
i += 4;
|
|
} else {
|
|
throw new DatabaseReadException(I18n.Message.ERROR_EXPECTED_TRUE_OR_FALSE, lineNumber, i);
|
|
}
|
|
} else if (line[i] == 'F') {
|
|
if (i + 4 < len && line[i + 1] == 'a' && line[i + 2] == 'l' && line[i + 3] == 's' && line[i + 4] == 'e') {
|
|
i += 5;
|
|
} else {
|
|
throw new DatabaseReadException(I18n.Message.ERROR_EXPECTED_TRUE_OR_FALSE, lineNumber, i);
|
|
}
|
|
}
|
|
// consume separator
|
|
if (i + 1 < len && (line[i] != '|' || line[i + 1] != '|'))
|
|
throw new DatabaseReadException(I18n.Message.ERROR_EXPECTED_ANSWER_SEPARATOR, lineNumber, i);
|
|
i += 2;
|
|
answers.Add(answer);
|
|
++currentAnswer;
|
|
}
|
|
|
|
lineNumber++;
|
|
db.questions.Add(new Question(question, answers, correctAnswer));
|
|
}
|
|
}
|
|
return db;
|
|
}
|
|
}
|
|
|
|
public class DatabaseReadException : Exception {
|
|
public readonly int line, column;
|
|
public readonly I18n.Message messageId;
|
|
|
|
public DatabaseReadException(I18n.Message messageId) {
|
|
this.messageId = messageId;
|
|
line = -1;
|
|
column = -1;
|
|
}
|
|
|
|
public DatabaseReadException(I18n.Message messageId, int line, int column) {
|
|
this.messageId = messageId;
|
|
this.line = line;
|
|
this.column = column;
|
|
}
|
|
}
|
|
|
|
public record Question (string question, List<string> answers, int correctAnswer);
|
|
} |