Neues Beispiel: Wörter raten
authorAndreas Bilke <andreas@bilke.org>
Sun, 30 Jul 2017 15:12:38 +0000 (17:12 +0200)
committerAndreas Bilke <andreas@bilke.org>
Sun, 30 Jul 2017 15:12:38 +0000 (17:12 +0200)
Wort-Raten/cpp/Makefile [new file with mode: 0644]
Wort-Raten/cpp/beispielwörter.txt [new file with mode: 0644]
Wort-Raten/cpp/raten.cpp [new file with mode: 0644]

diff --git a/Wort-Raten/cpp/Makefile b/Wort-Raten/cpp/Makefile
new file mode 100644 (file)
index 0000000..a2f77e0
--- /dev/null
@@ -0,0 +1,5 @@
+all:
+       g++ -Wall -o raten ../../common/cpp/file.cpp raten.cpp
+
+clean:
+       -rm raten
diff --git a/Wort-Raten/cpp/beispielwörter.txt b/Wort-Raten/cpp/beispielwörter.txt
new file mode 100644 (file)
index 0000000..4816abe
--- /dev/null
@@ -0,0 +1,3 @@
+Mississippi
+Tintenstrahldrucker
+Maus
diff --git a/Wort-Raten/cpp/raten.cpp b/Wort-Raten/cpp/raten.cpp
new file mode 100644 (file)
index 0000000..c769fd8
--- /dev/null
@@ -0,0 +1,139 @@
+/*!
+ * \file raten.cpp
+ * \brief Liest Wörter aus einer Datei und lässt den Benutzer das Wort raten
+ *
+ * \author Andreas Bilke, M. Sc.
+ * \copyright GNU Public License
+ */
+
+#include "../../common/cpp/file.hpp"
+
+#include <cctype>
+#include <cstdlib>
+
+#include <algorithm>
+#include <exception>
+#include <iostream>
+#include <regex>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+class Wort {
+    private:
+        std::vector<bool> bisherErraten;
+        std::string wort;
+
+        bool istErraten() {
+            return (size_t)std::count(bisherErraten.begin(), bisherErraten.end(), true) == wort.size();
+        }
+
+        void passeSichtbarkeitAn(char buchstabe) {
+            for (unsigned int i = 0; i < wort.size(); i++) {
+                if (std::tolower(wort[i]) == std::tolower(buchstabe)) {
+                    bisherErraten[i] = true;
+                }
+            }
+        }
+
+    public:
+        Wort(std::string pWort) : wort(pWort) {
+            for (unsigned int i = 0; i < wort.size(); i++) {
+                // bisher wurde nichts erraten
+                bisherErraten.push_back(false);
+            }
+        }
+
+        bool liesUndPruefNaechstenBuchstaben() {
+            std::cout << "Rate den nächsten Buchstaben: ";
+            std::string zeile;
+            std::getline(std::cin, zeile);
+
+            if (zeile.size() != 1) {
+                return false;
+            }
+
+            passeSichtbarkeitAn(zeile[0]);
+
+            return istErraten();
+        }
+
+        void zeigeBisherigesWort() {
+            for (unsigned int i = 0; i < wort.size(); i++) {
+                if (bisherErraten[i]) {
+                    std::cout << wort[i];
+                } else {
+                    std::cout << "_";
+                }
+            }
+            std::cout << std::endl;
+        }
+};
+
+std::vector<Wort> erstelleWoerter(std::vector<std::vector<std::string>> zeilen);
+
+/*!
+ * \brief Einstiegspunkt für das Programm "raten".
+ *
+ * \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: raten <wortdatei>" << std::endl;
+        return EXIT_FAILURE;
+    }
+
+    std::string ratedatei = std::string(argv[1]);
+    std::vector<Wort> woerter = erstelleWoerter(liesDatei(ratedatei));
+
+    std::random_shuffle(woerter.begin(), woerter.end());
+    // TODO das geht nicht
+
+    for (auto wort : woerter) {
+        std::cout << "Neues Wort!" << std::endl;
+        wort.zeigeBisherigesWort();
+
+        while(!wort.liesUndPruefNaechstenBuchstaben()) {
+            wort.zeigeBisherigesWort();
+        }
+
+        wort.zeigeBisherigesWort();
+        std::cout << "Du hat das Wort erraten!" << std::endl;
+    }
+
+    std::cout << "Das Spiel ist zu Ende." << std::endl;
+
+    return EXIT_SUCCESS;
+}
+
+/*!
+ * \brief Extrahiert Wörter aus dem std::vector
+ *
+ * \ref zeilen enthält die nach ";" getrennten Zeilen einer Datei. Es wird dabei
+ * ein Wort pro Zeile erwartet. Wörter dürfen nur aus Buchstaben des deutschsprachigen
+ * Alphabets bestehen.
+ *
+ * \param zeilen die gesamte Datei zeilenweise gespeichert, jede Zeile nach ";" getrennt
+ */
+std::vector<Wort> erstelleWoerter(std::vector<std::vector<std::string>> zeilen) {
+    std::vector<Wort> woerter;
+    std::regex regexWort("^[A-Za-zßÄÖÜäöü]+$");
+
+    for (auto zeile : zeilen) {
+        if (zeile.size() != 1) {
+            throw std::logic_error("Das Dateiformat stimmt nicht. Es muss pro Zeile nur ein Wort!");
+        }
+
+        std::string wort = zeile[0];
+        if (!std::regex_match(wort, regexWort)) {
+            throw std::logic_error("Ein Wort darf nur aus den Buchstaben A-Z und den Umlauten bestehen!");
+        }
+        Wort wortObj = Wort(wort);
+
+        woerter.push_back(wortObj);
+    }
+
+    return woerter;
+}