First work on 'Quiz'
authorAndreas Bilke <andreas@bilke.org>
Tue, 25 Jul 2017 13:26:03 +0000 (15:26 +0200)
committerAndreas Bilke <andreas@bilke.org>
Tue, 25 Jul 2017 13:26:03 +0000 (15:26 +0200)
Quiz/cpp/Makefile [new file with mode: 0644]
Quiz/cpp/beispielfrageantwort.txt [new file with mode: 0644]
Quiz/cpp/quiz.cpp [new file with mode: 0644]

diff --git a/Quiz/cpp/Makefile b/Quiz/cpp/Makefile
new file mode 100644 (file)
index 0000000..83f67bc
--- /dev/null
@@ -0,0 +1,5 @@
+all:
+       g++ -Wall -o quiz quiz.cpp
+
+clean:
+       -rm quiz
diff --git a/Quiz/cpp/beispielfrageantwort.txt b/Quiz/cpp/beispielfrageantwort.txt
new file mode 100644 (file)
index 0000000..f977b97
--- /dev/null
@@ -0,0 +1,2 @@
+Wie heißt die Hauptstadt von Österreich?;1;Wien;Salzburg;Linz;Innsbruck
+Wie hoch ist der Brocken?;3;1898 m;1200 m;1142 m;743 m;3200 m
diff --git a/Quiz/cpp/quiz.cpp b/Quiz/cpp/quiz.cpp
new file mode 100644 (file)
index 0000000..baeb7b7
--- /dev/null
@@ -0,0 +1,144 @@
+/*!
+ * \file quiz.cpp
+ * \brief Liest Fragen/Antworten aus einer Textdatei und lässt den Nutzer spielen.
+ *
+ * \author Andreas Bilke, M. Sc.
+ * \copyright GNU Public License
+ */
+
+#include <cstdlib>
+
+#include <algorithm>
+#include <exception>
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+
+class FrageAntworten {
+    private:
+        std::string frage;
+        std::vector<std::string> antworten;
+        unsigned int korrekteantwort;
+
+    public:
+        FrageAntworten(std::string pFrage, std::vector<std::string> pAntworten, int pKorrekteAntwort) : frage(pFrage), antworten(pAntworten), korrekteantwort(pKorrekteAntwort) { }
+
+        void stelleFrage() {
+            std::cout << "> " << frage << std::endl << std::endl;
+
+            for (size_t i = 0; i < antworten.size(); i++) {
+                std::cout << char(97 + i) << ") " << antworten[i] << std::endl;
+            }
+        }
+
+        bool liesAntwort() {
+            std::string zeilenpuffer;
+
+            std::cout << "Was ist die Antwort? ";
+            std::getline(std::cin, zeilenpuffer);
+
+            char antwort = zeilenpuffer[0];
+            unsigned int antwortNummer = antwort - 97 + 1;
+
+            if (antwortNummer == korrekteantwort) {
+                std::cout << "Antwort korrekt" << std::endl;
+                return true;
+            } else {
+                std::cout << "Antwort falsch" << std::endl;
+                return false;
+            }
+        }
+};
+
+std::vector<FrageAntworten> liesDatei(std::string& dateiname);
+std::vector<std::string> teileZeile(std::string& zeile);
+
+/*!
+ * \brief Einstiegspunkt für das Programm "quiz".
+ *
+ * \param argc Die Anzahl der Kommandozeilenparameter
+ * \param argv Die Kommandozeilenparameter
+ * \return Den Erfolgsstatus des Programms
+ */
+int main(int argc, char** argv) {
+    if (argc != 2) {
+        std::cerr << "Benutzung: quiz <frageantwortdatei>" << std::endl;
+        return EXIT_FAILURE;
+    }
+
+    std::string quizdatei = std::string(argv[1]);
+    std::vector<FrageAntworten> frageantworten = liesDatei(quizdatei);
+
+    std::vector<size_t> fragenreihenfolge(frageantworten.size());
+    for (size_t i = 0; i < frageantworten.size(); i++) {
+        fragenreihenfolge[i] = i;
+    }
+    std::random_shuffle(fragenreihenfolge.begin(), fragenreihenfolge.end());
+
+    int korrekteAntworten = 0;
+    for (size_t i = 0; i < fragenreihenfolge.size(); i++) {
+        frageantworten[i].stelleFrage();
+        std::cout << std::endl;
+        bool korrekt = frageantworten[i].liesAntwort();
+        if (korrekt) {
+            korrekteAntworten++;
+        }
+    }
+
+    std::cout << "Das Spiel ist zu Ende. Du hattest " << korrekteAntworten << " korrekte Antworten." << std::endl;
+
+    return EXIT_SUCCESS;
+}
+
+std::vector<FrageAntworten> liesDatei(std::string& dateiname) {
+    std::ifstream dateistream(dateiname);
+    if (!dateistream.good()) {
+       throw std::ios_base::failure("Kann Datei nicht lesen.");
+    }
+
+    std::vector<FrageAntworten> frageantworten;
+
+    std::string zeile;
+    while (std::getline(dateistream, zeile).good()) {
+        std::vector<std::string> getrennteElemente = teileZeile(zeile);
+        if (getrennteElemente.size() < 3) {
+            throw std::logic_error("Das Dateiformat stimmt nicht. Es muss pro Zeile Eine Frage, eine korrekte Antwort und mindestens eine Antwortmöglichkeit geben.");
+        }
+
+        std::reverse(getrennteElemente.begin(), getrennteElemente.end());
+
+        std::string frage = getrennteElemente.back();
+        getrennteElemente.pop_back();
+        unsigned int korrekteantwort = std::stoi(getrennteElemente.back());
+        getrennteElemente.pop_back();
+
+        if (korrekteantwort < 0 || korrekteantwort >= getrennteElemente.size()) {
+            throw std::logic_error("Das Dateiformat stimmt nicht. Die Angabe der korrekten Antwort referenziert auf eine nicht existierende Antwortmöglichkeit in der Datei.");
+        }
+
+        std::reverse(getrennteElemente.begin(), getrennteElemente.end());
+        FrageAntworten frageantwort = FrageAntworten(frage, getrennteElemente, korrekteantwort);
+
+        frageantworten.push_back(frageantwort);
+    }
+
+    return frageantworten;
+}
+
+std::vector<std::string> teileZeile(std::string& zeile) {
+    std::string::size_type letztePos = zeile.find_first_not_of(";", 0);
+    std::string::size_type pos = zeile.find_first_of(";", letztePos);
+
+    std::vector<std::string> getrennteElemente;
+
+    while (std::string::npos != pos || std::string::npos != letztePos)  {
+        getrennteElemente.push_back(zeile.substr(letztePos, pos - letztePos));
+        letztePos = zeile.find_first_not_of(";", pos);
+        pos = zeile.find_first_of(";" , letztePos);
+    }
+
+    return getrennteElemente;
+}