From 862186ae7cbbd922057fa5f6b49509c36f9ade36 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 30 Oct 2024 14:07:01 +0100 Subject: generate dungeon kinda works --- frontend/DB.cpp | 37 ++++++++++++++++++++++++++++- frontend/DB.h | 55 +++++++++++++++++++++++-------------------- frontend/GameData.cpp | 41 ++++++++++++++++++++++++++++++++ frontend/GameData.h | 5 ++++ frontend/generate_dungeon.cpp | 25 +++++++++++++++++++- 5 files changed, 135 insertions(+), 28 deletions(-) diff --git a/frontend/DB.cpp b/frontend/DB.cpp index d4527b8..d51315b 100644 --- a/frontend/DB.cpp +++ b/frontend/DB.cpp @@ -75,7 +75,6 @@ DBQueryRow DBStatement::row() { DBQueryRow::DBQueryRow(DBStatement & parent) : parent(parent) { } - template <> const char * DBQueryRow::col(int index, const char * const & default_value) { int type = sqlite3_column_type(this->parent.stmt.get(), index); @@ -98,3 +97,39 @@ int DBQueryRow::col(int index) { return this->col(index, 0); } +DBQueryRowRange DBStatement::rows() { + return { *this }; +} + +DBQueryRowRange::DBQueryRowIterator & DBQueryRowRange::DBQueryRowIterator::operator ++ () { + int ret = sqlite3_step(this->parent.parent.stmt.get()); + if (ret == SQLITE_DONE) { + this->end = true; + return *this; + } + if (ret != SQLITE_ROW) + throw Exception("sqlite3_step: %d", ret); + return *this; +} + +bool DBQueryRowRange::DBQueryRowIterator::operator != (const DBQueryRowIterator &) const { + return !this->end; +} + +DBQueryRow & DBQueryRowRange::DBQueryRowIterator::operator * () const { + return this->parent.row; +} + +DBQueryRowRange::DBQueryRowIterator DBQueryRowRange::begin() { + DBQueryRowRange::DBQueryRowIterator it = { *this }; + return ++it; +} + +DBQueryRowRange::DBQueryRowIterator DBQueryRowRange::end() { + return { *this }; +} + +DBQueryRowRange::DBQueryRowRange(DBStatement & parent) : parent(parent), row(parent) { } + +DBQueryRowRange::DBQueryRowIterator::DBQueryRowIterator(DBQueryRowRange & parent) : parent(parent) { } + diff --git a/frontend/DB.h b/frontend/DB.h index f6907bc..0164e34 100644 --- a/frontend/DB.h +++ b/frontend/DB.h @@ -21,34 +21,37 @@ private: DBStatement & parent; }; -// class DBQueryRowRange { -// public: -// DBQueryRowRange(); -// -// private: -// class DBQueryRowIterator { -// public: -// DBQueryRowIterator(DBQueryRow & row); -// -// public: -// DBQueryRow & operator * () const; -// DBQueryRowIterator & operator ++ (); -// bool operator != (const DBQueryRowIterator &) const; -// -// private: -// DBQueryRow & row; -// }; -// -// public: -// DBQueryRowIterator begin() const; -// DBQueryRowIterator end() const; -// -// private: -// DBQueryRow row; -// }; +class DBQueryRowRange { +public: + DBQueryRowRange(DBStatement & stmt); + +private: + class DBQueryRowIterator { + public: + DBQueryRowIterator(DBQueryRowRange & parent); + + public: + DBQueryRow & operator * () const; + DBQueryRowIterator & operator ++ (); + bool operator != (const DBQueryRowIterator &) const; + + private: + bool end = false; + DBQueryRowRange & parent; + }; + +public: + DBQueryRowIterator begin(); + DBQueryRowIterator end(); + +private: + DBStatement & parent; + DBQueryRow row; +}; class DBStatement { friend class DBQueryRow; + friend class DBQueryRowRange; public: DBStatement(DB &, const std::string & query); @@ -60,7 +63,7 @@ public: public: void execute(); DBQueryRow row(); - // DBQueryRowRange rows(); + DBQueryRowRange rows(); private: std::unique_ptr> stmt; diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp index c8f47e3..edcd854 100644 --- a/frontend/GameData.cpp +++ b/frontend/GameData.cpp @@ -3,6 +3,7 @@ #include "backend/Enemy.h" #include "backend/EnemyFactory.h" +#include "backend/LocationFactory.h" #include "backend/Object.h" #include "backend/ObjectFactory.h" @@ -21,6 +22,7 @@ GameData::GameData() { Enemy * GameData::create_enemy(const string & name) { Enemy * enemy = EnemyFactory::create_enemy(); + // TODO: fill fields return enemy; } @@ -66,6 +68,27 @@ Object * GameData::create_object(const string & name) { } } +Location * GameData::create_location(const string & name) { + static DBStatement query = this->db->prepare(R"( + select + naam, + beschrijving + from Locaties + where lower(naam) = lower(?) + limit 1 + )"); + query.reset() + .bind(name) + ; + + try { + auto row = query.row(); + return LocationFactory::create_location(row.col(0), row.col(1)); + } catch (...) { + return LocationFactory::create_location(name.c_str(), ""); + } +} + void GameData::leaderbord_add(const string & name, unsigned int gold) { static DBStatement stmt = this->db->prepare(R"( insert into Leaderboard (naam, goudstukken) @@ -78,3 +101,21 @@ void GameData::leaderbord_add(const string & name, unsigned int gold) { stmt.execute(); } +vector GameData::random_locations(unsigned count) { + static DBStatement query = this->db->prepare(R"( + select naam + from Locaties + order by random() + limit ? + )"); + query.reset() + .bind(count) + ; + + vector names = {}; + for (DBQueryRow & row : query.rows()) { + names.push_back(row.col(0)); + } + return names; +} + diff --git a/frontend/GameData.h b/frontend/GameData.h index 383de00..81e16c1 100644 --- a/frontend/GameData.h +++ b/frontend/GameData.h @@ -6,6 +6,7 @@ class Enemy; class Object; +class Location; class GameData { public: @@ -14,7 +15,11 @@ public: public: Enemy * create_enemy(const std::string & name); Object * create_object(const std::string & name); + Location * create_location(const std::string & name); + +public: void leaderbord_add(const std::string & name, unsigned int gold); + std::vector random_locations(unsigned count = 1); private: GameData(); diff --git a/frontend/generate_dungeon.cpp b/frontend/generate_dungeon.cpp index e2a7c74..80eb0cb 100644 --- a/frontend/generate_dungeon.cpp +++ b/frontend/generate_dungeon.cpp @@ -2,16 +2,39 @@ #include "backend/Dungeon.h" +#include "rl.h" +#include "print.h" #include "generate_dungeon.h" #include "GameData.h" +#include "Exception.h" using namespace std; unique_ptr generate_dungeon() { unique_ptr dungeon = make_unique(); - GameData & gd = GameData::get_instance(); + lprtf("Hoeveel locaties moet de kerker hebben?\n"); + unsigned location_count = 1; + try { + string filename = rl(); + location_count = stoul(filename); + } catch (...) { + throw Exception("Geen geldig aantal ingevoerd"); + } + if (location_count < 1) + throw Exception("Meer dan 1 locatie nodig"); + + vector locations = gd.random_locations(location_count); + for (const string & name : locations) { + Location * location = gd.create_location(name); + dungeon->add_location(location); + } + + // TODO: connect locations + // TODO: optionally add enemy + // TODO: generate items + return dungeon; } -- cgit v1.2.3