C++ lernen, Beispiel: RPG (Console)
-
cooky451 schrieb:
Was eine "Settings-Datei" angeht, da würde ich gar nicht erst versuchen irgendetwas in der Datei zu suchen, einfach komplett auslesen und am Ende wieder komplett überschreiben. Am besten so in der Art dass du eine Datei im Stil von
setting1=value1
setting2=value2etc. hast, dann liest du diese Key-Wert Paare einfach in eine std::map, und am Ende des Programms überschreibst du die Datei komplett mit neuen Key-Wert Paaren.
Beim Charakter, ein paar Monstern und NPCs, und den Settings kommt nicht viel zusammen, aber mein vorrangiges Ziel ist ja nicht, möglichst schnell auf schlechte Programmier-Art ein Spiel auf die Beine zu stellen, sondern es gleich von Anfang an richtig zu machen.
Mindestens bei der Map würde ich deshalb nur das Feld (+ vllt ein paar umliegende) in den Speicher laden, und die Tiles nur aufrufen, wenn der Charakter in die Nähe kommt.Das Programm müsste die Daten in einer bestimmten Zeile von/bis zu einem bestimmten Offset lesen.
Ich bin mir sicher, dass so etwas nicht schwer zu programmieren ist, ich kenne nur einfach die Befehle dafür nicht. Man braucht eigentlich nur:
- Datei öffnen (krieg ich hin)
- Zeile lesen (krieg ich auch hin)
- String auf eine bestimmte Zeichenfolge untersuchen (Settings)
- Zeile von/bis zu einem festgelegten Offset einlesen (Map)
- Daten innerhalb eines bestimmten Offset-Bereichs überschreiben
- Daten an einem bestimmten Offset zwischen vorhandene Zeichen einfügen, ohne zu überschreiben
- Datei schließen (krieg ich wieder hin)Bisher weiss ich zwar, wie ich in einer Zeile Zeichen einlesen kann, allerdings immer nur bis zum nächsten Whitespace.
cooky451 schrieb:
Ich gebe dir hier mal eine Klasse die ich irgendwann mal dafür benutzt habe, aber ich bin mir leider nicht sicher wie viel dir das hilft, denn du scheinst von Klassen und Templates noch nicht so viel Ahnung zu haben. Vielleicht lohnt es doch sich die Sprache noch ein bisschen weiter anzugucken.
Danke für den Code, ich werd mal versuchen, da durch zu steigen. Sieht auf den ersten Blick noch recht komplex aus.
-
Ich rede nur von einem config-file. Ein map-file ist etwas komplett anderes.
Da muss man sich dann erst mal überlegen wie man das aufbauen will, welche Daten man woher bekommt, welche Daten man überhaupt braucht etc. da gibt es unendlich viele Möglichkeiten das aufzuziehen. Mit seekg kannst du übrigens bestimmte Teile einer Datei lesen. http://en.cppreference.com/w/cpp/io/basic_ifstream
-
Jau, habs hinbekommen, mit seek/tellg/p, setw(), substr(), find().
Danke nochmal!Im Prinzip ist es also sinnvoll zu wissen, wie lang die Zeilen in einer Datei einmal sein werden, wenn man später an einzelnen Zeilen basteln will.
Mal eine generelle Frage: Gibt es eine Länge, nach der bei C++ automatisch ein '\n' erfolgt, oder könnte ich eine einzige Zeile mit 10.000 Zeichen schreiben?
-
Nein, Zeilenumbrüche sind oft nur eine Konzession an die Lesbarkeit. Du kannst beliebig große Textdateien erzeugen, die nur vom verfügbaren Speicherplatz begrenzt sind.
-
DocShoe schrieb:
_________________
Die fünf häufigsten Anzeichen für Faulheit:
1.Ich würde gerne eine "Sleep" Funktion aufrufen, aber keine der folgenden geht:
Sleep()
usleep()
sleep()
sleep_for()<chrono> <thread> <unisth.h> <ctime> und <windows.h> hab ich drin.
Weiss jemand Rat?
-
-
Biolunar schrieb:
Was heißt „geht nicht“?
Das heisst in diesem Fall die Meldung:
'sleep_for' undeclaredAusserdem bekomme ich:
chrono: No such file or directory
thread: No such file or directory
(obwohl ich beide #included habe)Versuche es gerade mit Dev-C++ 4.9.9.2 unter Windows.
-
origami schrieb:
Versuche es gerade mit Dev-C++ 4.9.9.2 unter Windows.
Diese IDE ist dermassen antik, da kannst du C++11 gleich vergessen.
Nimm Visual Studio 2013 Express oder eine neue Code::Blocks-Version.
-
Code::Blocks habe ich auch, allerdings bekomme ich da auch den Fehler:
'sleep_for' was not declared in this scope
-
Compilerflag
-std=c++11
-
Nexus schrieb:
Compilerflag
-std=c++11
Settings -> Compiler -> Häkchen bei
Have g++ follow the C++11 ISO C++ languale standard [-std=c++11]
Hab ich.
Muss ich das noch irgendwo setzen?
-
Hast du überprüft, ob deine g++-Version diese Features bereits unterstützt?
Und du machst nicht sonst einen unnötigen Fehler, wie z.B. Namensraum
std
vergessen? Zeig mal kompletten minimalen Code.
-
Nexus schrieb:
Hast du überprüft, ob deine g++-Version diese Features bereits unterstützt?
Wo seh ich meine g++ Version unter Windows?
Ich habe das aktuellste Code::Blocks mit MinGW installiert.Nexus schrieb:
Und du machst nicht sonst einen unnötigen Fehler, wie z.B. Namensraum
std
vergessen? Zeig mal kompletten minimalen Code.#include <iostream> #include <string> #include <cmath> #include <algorithm> #include <iomanip> #include <vector> #include <fstream> #include <cstdlib> #include <cstdio> #include <ctime> #include <conio.h> #include <unistd.h> #include <chrono> #include <thread> using namespace std; int main(){ sleep_for(1); return(0); }
-
Sollte eigentlich funktionieren, oder?
-
origami schrieb:
Sollte eigentlich funktionieren, oder?
Nein, sollte nicht funktionieren.
Sage mir in welchem Namespace sleep_for(..) dekl. ist und du findest raus, warum es nicht geht.Hier noch eine Hilfe:
http://en.cppreference.com/w/cpp/thread/sleep_for
-
origami schrieb:
Sollte eigentlich funktionieren, oder?
Nein.
#include <cassert> #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <ccomplex> #include <cfenv> #include <cinttypes> #include <cstdalign> #include <cstdbool> #include <cstdint> #include <ctgmath> #include <cwchar> #include <cwctype> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> #include <array> #include <atomic> #include <chrono> #include <condition_variable> #include <forward_list> #include <future> #include <initializer_list> #include <mutex> #include <random> #include <ratio> #include <regex> #include <scoped_allocator> #include <system_error> #include <thread> #include <tuple> #include <typeindex> #include <type_traits> #include <unordered_map> #include <unordered_set> using namespace std; int main(){ std::this_thread::sleep_for(std::chrono::seconds(1)); return ((0)); }
-
Ich mag dein dezentes return ((0)), viel besser als die ganzen Header.
-
-
theta schrieb:
Nein, sollte nicht funktionieren.
Sage mir in welchem Namespace sleep_for(..) dekl. ist und du findest raus, warum es nicht geht.Hier noch eine Hilfe:
http://en.cppreference.com/w/cpp/thread/sleep_forJetzt wo du´s sagst
Ist es möglich, mehrere namespaces zu nutzen, solange sich die Funktionen nicht überschneiden?
volkard schrieb:
Nein.
#include <cassert> #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <ccomplex> #include <cfenv> #include <cinttypes> #include <cstdalign> #include <cstdbool> #include <cstdint> #include <ctgmath> #include <cwchar> #include <cwctype> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> #include <array> #include <atomic> #include <chrono> #include <condition_variable> #include <forward_list> #include <future> #include <initializer_list> #include <mutex> #include <random> #include <ratio> #include <regex> #include <scoped_allocator> #include <system_error> #include <thread> #include <tuple> #include <typeindex> #include <type_traits> #include <unordered_map> #include <unordered_set> using namespace std; int main(){ std::this_thread::sleep_for(std::chrono::seconds(1)); return ((0)); }
-
origami schrieb:
Ist es möglich, mehrere namespaces zu nutzen, solange sich die Funktionen nicht überschneiden?
Du kannst mehrere namespaces nutzen, du kannst auch mehrere namespaces per using namespace ins Projekt holen, selbst wenn es Namenskollisionen gibt.
namespace A{ int bla; } namespace B{ double bla; } void foo(){ using namespace A; bla++; //geht } void blup(){ using namespace B; bla++; //geht } using namespace A; using namespace B; int main(){ bla++; //error: Welches bla? A::bla++; //geht B::bla++; //geht }
Solange es keine Kollisionen gibt kannst du alles per using rein holen, wenn es doch welche gibt sagt dir der Compiler bescheid und du must es ihm sagen.
Du solltest nur vermeiden per using sachen rein zu holen, die die entsprechende Datei gar nicht braucht. Aus diesem Grund sollte man kein using namespace global in den Header tun.