aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 14:07:01 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 14:07:01 +0100
commit862186ae7cbbd922057fa5f6b49509c36f9ade36 (patch)
tree10193494e1c4bdff793a2daafc2b3359e8794303
parentb1d5d7936bed17a684daff15b0294ef70754e8b9 (diff)
generate dungeon kinda works
-rw-r--r--frontend/DB.cpp37
-rw-r--r--frontend/DB.h55
-rw-r--r--frontend/GameData.cpp41
-rw-r--r--frontend/GameData.h5
-rw-r--r--frontend/generate_dungeon.cpp25
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<const char*>(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>(int index) {
return this->col<int>(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<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> 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<const char *>(0), row.col<const char *>(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<string> 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<string> names = {};
+ for (DBQueryRow & row : query.rows()) {
+ names.push_back(row.col<const char *>(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<std::string> 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<Dungeon> generate_dungeon() {
unique_ptr<Dungeon> dungeon = make_unique<Dungeon>();
-
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<string> 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;
}