diff options
-rw-r--r-- | backend/ArmorObject.cpp | 6 | ||||
-rw-r--r-- | backend/ArmorObject.h | 1 | ||||
-rw-r--r-- | backend/Dungeon.cpp | 8 | ||||
-rw-r--r-- | backend/Enemy.cpp | 12 | ||||
-rw-r--r-- | backend/Enemy.h | 7 | ||||
-rw-r--r-- | backend/Exception.cpp | 8 | ||||
-rw-r--r-- | backend/List.h | 4 | ||||
-rw-r--r-- | backend/ObjectFactory.cpp | 3 | ||||
-rw-r--r-- | backend/Player.h | 4 | ||||
-rw-r--r-- | backend/PtrList.h | 4 | ||||
-rw-r--r-- | backend/RNG.cpp | 4 | ||||
-rw-r--r-- | backend/RNG.h | 5 | ||||
-rw-r--r-- | backend/Range.h | 8 | ||||
-rw-r--r-- | backend/String.cpp | 15 | ||||
-rw-r--r-- | backend/String.h | 2 | ||||
-rw-r--r-- | backend/WeaponObject.cpp | 12 | ||||
-rw-r--r-- | backend/WeaponObject.h | 7 | ||||
-rw-r--r-- | backend/print.h | 4 | ||||
-rw-r--r-- | frontend/DB.cpp | 4 | ||||
-rw-r--r-- | frontend/DB.h | 6 | ||||
-rw-r--r-- | frontend/GameData.cpp | 38 | ||||
-rw-r--r-- | frontend/GameData.h | 17 | ||||
-rw-r--r-- | frontend/cmd/hit.cpp | 2 | ||||
-rwxr-xr-x | todo | 1 |
24 files changed, 125 insertions, 57 deletions
diff --git a/backend/ArmorObject.cpp b/backend/ArmorObject.cpp index e6dc026..eb805e0 100644 --- a/backend/ArmorObject.cpp +++ b/backend/ArmorObject.cpp @@ -6,3 +6,9 @@ void ArmorObject::set_protection(int protection) { int ArmorObject::get_protection() const { return this->protection; } + +const String & ArmorObject::get_displayname() const { + static String display = String::fmt("%s (%d bescherming)", this->get_name().c_str(), this->protection); + return display; +} + diff --git a/backend/ArmorObject.h b/backend/ArmorObject.h index 458b0ba..8889ed7 100644 --- a/backend/ArmorObject.h +++ b/backend/ArmorObject.h @@ -8,6 +8,7 @@ class ArmorObject : public Object { public: void set_protection(int protection); int get_protection() const; + virtual const String & get_displayname() const; private: int protection = 0; diff --git a/backend/Dungeon.cpp b/backend/Dungeon.cpp index fed955b..e1fae39 100644 --- a/backend/Dungeon.cpp +++ b/backend/Dungeon.cpp @@ -17,15 +17,19 @@ void Dungeon::update() { } void Dungeon::update_attacks(ListRange<Enemy *> & enemies) { - lprtf(":: De vijand%s in je locatie vallen aan! ::\n", enemies.size() == 1 ? "" : "en"); + bool plural = enemies.size() != 1; RNG & rng = RNG::get(); + bool first = true; for (Enemy * enemy : enemies) { if (enemy->is_dead()) continue; if (rng.rand_double() < enemy->get_attack()) continue; + if (!first) + lprtf(":: De %s in je locatie %s aan! ::\n", plural ? "vijanden" : "vijand", plural ? "vallen" : "valt"); - unsigned damage = rng.rand_int(enemy->get_damage_min(), enemy->get_damage_max() + 1); + unsigned damage = rng.rand_int(enemy->get_damage()); lprtf("%s raakt en doet %d punt schade.\n", enemy->get_displayname().c_str(), damage); this->player.take_damage(damage); + first = false; } } diff --git a/backend/Enemy.cpp b/backend/Enemy.cpp index c4bfff2..a2bab30 100644 --- a/backend/Enemy.cpp +++ b/backend/Enemy.cpp @@ -12,11 +12,13 @@ const String & Enemy::get_description() const { return this->description; } void Enemy::set_attack(float attack_chance) { this->attack_chance = attack_chance; } float Enemy::get_attack() const { return this->attack_chance; } -void Enemy::set_damage_min(int damage_min) { this->damage_min = damage_min; } -int Enemy::get_damage_min() const { return this->damage_min; } - -void Enemy::set_damage_max(int damage_max) { this->damage_max = damage_max; } -int Enemy::get_damage_max() const { return this->damage_max; } +void Enemy::set_damage(const Range<int> & range) { + this->damage_min = range.min; + this->damage_max = range.max; +} +Range<int> Enemy::get_damage() const { + return { this->damage_min, this->damage_max }; +} void Enemy::set_health(unsigned health_points) { this->health_points = health_points; } unsigned Enemy::get_health() const { return this->health_points; } diff --git a/backend/Enemy.h b/backend/Enemy.h index 4db2ae8..f85172e 100644 --- a/backend/Enemy.h +++ b/backend/Enemy.h @@ -4,6 +4,7 @@ #include "PtrList.h" #include "ListIterator.h" #include "Object.h" +#include "Range.h" class Enemy { public: @@ -18,10 +19,8 @@ public: virtual const String & get_displayname() const; void set_attack(float attack_chance); float get_attack() const; - void set_damage_min(int damage_min); - int get_damage_min() const; - void set_damage_max(int damage_max); - int get_damage_max() const; + void set_damage(const Range<int> & range); + Range<int> get_damage() const; void add_hidden_object(Object *); void remove_hidden_object(Object *); diff --git a/backend/Exception.cpp b/backend/Exception.cpp index 4044d6a..bb7b7c4 100644 --- a/backend/Exception.cpp +++ b/backend/Exception.cpp @@ -1,7 +1,7 @@ -#include <cstdarg> -#include <cstdio> -#include <cstdlib> -#include <cstring> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "backend/String.h" diff --git a/backend/List.h b/backend/List.h index 3bdbb23..d991152 100644 --- a/backend/List.h +++ b/backend/List.h @@ -21,6 +21,10 @@ class List { public: List() = default; virtual ~List(); + List(const List &) = delete; + List(List &&) = delete; + List & operator = (const List &) = delete; + List & operator = (List &&) = delete; public: size_t size() const; diff --git a/backend/ObjectFactory.cpp b/backend/ObjectFactory.cpp index a3a6d83..1256f98 100644 --- a/backend/ObjectFactory.cpp +++ b/backend/ObjectFactory.cpp @@ -25,8 +25,7 @@ Object * ObjectFactory::create_object(const UniversalObject & data) { } case WEAPON: { WeaponObject * object = new WeaponObject(data.name, data.description); - object->set_damage_min(data.min_value); - object->set_damage_max(data.max_value); + object->set_damage({ data.min_value, data.max_value }); return object; } default: break; diff --git a/backend/Player.h b/backend/Player.h index 6fbd70d..061f13c 100644 --- a/backend/Player.h +++ b/backend/Player.h @@ -24,6 +24,10 @@ private: public: Player(Dungeon & dungeon); virtual ~Player(); + Player(const Player &) = delete; + Player(Player &&) = delete; + Player & operator = (const Player &) = delete; + Player & operator = (Player &&) = delete; public: void take_damage(unsigned int dmg); diff --git a/backend/PtrList.h b/backend/PtrList.h index 5442043..2947a15 100644 --- a/backend/PtrList.h +++ b/backend/PtrList.h @@ -7,6 +7,10 @@ class PtrList : public List<T *> { public: using List<T *>::List; virtual ~PtrList(); + PtrList(const PtrList &) = delete; + PtrList(PtrList &&) = delete; + PtrList & operator = (const PtrList &) = delete; + PtrList & operator = (PtrList &&) = delete; }; #include "PtrList.hpp" diff --git a/backend/RNG.cpp b/backend/RNG.cpp index 2d7895b..d804f7b 100644 --- a/backend/RNG.cpp +++ b/backend/RNG.cpp @@ -18,6 +18,10 @@ int RNG::rand_int(const int lower, const int upper) { uniform_int_distribution<int> random_dist(lower, upper - 1); return random_dist(rng); } +int RNG::rand_int(const Range<int> range) { + uniform_int_distribution<int> random_dist(range.min, range.max); + return random_dist(rng); +} double RNG::rand_double() { return this->rand_double(0.f, 1.f); diff --git a/backend/RNG.h b/backend/RNG.h index ded337c..3c168bd 100644 --- a/backend/RNG.h +++ b/backend/RNG.h @@ -1,5 +1,7 @@ #pragma once +#include "Range.h" + #include <random> class RNG { @@ -8,7 +10,10 @@ public: public: int rand_int(const int upper); + //! \note upper is non-inclusive int rand_int(const int lower, const int upper); + //! \note range is inclusive + int rand_int(const Range<int> range); double rand_double(); double rand_double(const double lower, const double upper); bool rand_bool(); diff --git a/backend/Range.h b/backend/Range.h new file mode 100644 index 0000000..d162eeb --- /dev/null +++ b/backend/Range.h @@ -0,0 +1,8 @@ +#pragma once + +template <typename T> +struct Range { + T min; + T max; +}; + diff --git a/backend/String.cpp b/backend/String.cpp index 381277e..c856d86 100644 --- a/backend/String.cpp +++ b/backend/String.cpp @@ -11,13 +11,24 @@ String::String() { } +String::String(const String & other) { + this->set(other.data(), other.size()); +} String & String::operator = (const String & other) { + if (this == &other) return *this; this->set(other.data(), other.size()); return *this; } -String::String(const String & other) { - this->set(other.data(), other.size()); +String::String(String && other) { + this->_data = other._data; + this->_data_len = other._data_len; +} +String & String::operator = (String && other) { + if (this == &other) return *this; + this->_data = other._data; + this->_data_len = other._data_len; + return *this; } String::String(const char * c_str) { diff --git a/backend/String.h b/backend/String.h index 0f20de6..bca8944 100644 --- a/backend/String.h +++ b/backend/String.h @@ -9,6 +9,7 @@ public: String(const char * c_str); String(const char * data, size_t size); String(const String &); + String(String &&); ~String(); public: static String va_fmt(va_list args, const char * fmt); @@ -22,6 +23,7 @@ public: public: String & operator = (const String &); + String & operator = (String &&); private: void set(const char * data); diff --git a/backend/WeaponObject.cpp b/backend/WeaponObject.cpp index 58db34d..a91b6bf 100644 --- a/backend/WeaponObject.cpp +++ b/backend/WeaponObject.cpp @@ -1,10 +1,12 @@ #include "WeaponObject.h" -void WeaponObject::set_damage_min(int damage_min) { this->damage_min = damage_min; } -int WeaponObject::get_damage_min() const { return this->damage_min; } - -void WeaponObject::set_damage_max(int damage_max) { this->damage_max = damage_max; } -int WeaponObject::get_damage_max() const { return this->damage_max; } +void WeaponObject::set_damage(const Range<int> & range) { + this->damage_min = range.min; + this->damage_max = range.max; +} +Range<int> WeaponObject::get_damage() const { + return { this->damage_min, this->damage_max }; +} const String & WeaponObject::get_displayname() const { static String display = String::fmt("%s (%d - %d schade)", this->get_name().c_str(), this->damage_min, this->damage_max); diff --git a/backend/WeaponObject.h b/backend/WeaponObject.h index 032ac15..b54ab59 100644 --- a/backend/WeaponObject.h +++ b/backend/WeaponObject.h @@ -1,15 +1,14 @@ #pragma once #include "Object.h" +#include "Range.h" class WeaponObject : public Object { using Object::Object; public: - void set_damage_min(int damage_min); - int get_damage_min() const; - void set_damage_max(int damage_max); - int get_damage_max() const; + void set_damage(const Range<int> & range); + Range<int> get_damage() const; virtual const String & get_displayname() const; private: diff --git a/backend/print.h b/backend/print.h index 8fa0501..48490de 100644 --- a/backend/print.h +++ b/backend/print.h @@ -13,6 +13,10 @@ public: private: SessionLog(); virtual ~SessionLog(); + SessionLog(const SessionLog &) = delete; + SessionLog(SessionLog &&) = delete; + SessionLog & operator = (const SessionLog &) = delete; + SessionLog & operator = (SessionLog &&) = delete; public: virtual void append(const String & str) const; diff --git a/frontend/DB.cpp b/frontend/DB.cpp index 28a1c3d..0f52433 100644 --- a/frontend/DB.cpp +++ b/frontend/DB.cpp @@ -17,11 +17,11 @@ DB::DB(const string & path) { throw Exception("sqlite3_open_v2: %d", ret); } -DBStatement DB::prepare(const string & query) { +DBStatement DB::prepare(const string & query) const { return DBStatement(*this, query); } -DBStatement::DBStatement(DB & parent, const string & query) : parent(parent) { +DBStatement::DBStatement(const DB & parent, const string & query) : parent(parent) { sqlite3_stmt * stmt = NULL; int ret = sqlite3_prepare_v2(this->parent.db.get(), query.c_str(), query.size(), &stmt, NULL); this->stmt = { diff --git a/frontend/DB.h b/frontend/DB.h index 2746e09..e3abfbf 100644 --- a/frontend/DB.h +++ b/frontend/DB.h @@ -54,7 +54,7 @@ class DBStatement { friend class DBQueryRowRange; public: - DBStatement(DB &, const std::string & query); + DBStatement(const DB &, const std::string & query); public: DBStatement & reset(); @@ -68,7 +68,7 @@ public: private: std::unique_ptr<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> stmt; int param_index = 1; - DB & parent; + const DB & parent; }; class DB { @@ -76,7 +76,7 @@ class DB { public: DB(const std::string & path); - DBStatement prepare(const std::string & query); + DBStatement prepare(const std::string & query) const; private: std::unique_ptr<sqlite3, std::function<void(sqlite3*)>> db = NULL; diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp index ee05d4b..a716a57 100644 --- a/frontend/GameData.cpp +++ b/frontend/GameData.cpp @@ -17,12 +17,8 @@ GameData & GameData::get_instance() { return instance; } -GameData::GameData() { - this->db = make_unique<DB>("kerkersendraken.db"); -} - Enemy * GameData::create_enemy(const string & name) const { - static DBStatement query = this->db->prepare(R"( + static DBStatement query = this->db.prepare(R"( select naam, omschrijving, @@ -46,8 +42,7 @@ Enemy * GameData::create_enemy(const string & name) const { // TODO: min/max objects(?) enemy->set_health(row.col<int>(4)); enemy->set_attack(static_cast<float>(row.col<int>(5)) / 100); - enemy->set_damage_min(row.col<int>(6)); - enemy->set_damage_max(row.col<int>(7)); + enemy->set_damage({ row.col<int>(6), row.col<int>(7) }); return enemy.release(); } catch (...) { return EnemyFactory::create_enemy(name.c_str()); @@ -64,7 +59,7 @@ static const unordered_map<string, ObjectType> type_map = { }; Object * GameData::create_object(const string & name) const { - static DBStatement query = this->db->prepare(R"( + static DBStatement query = this->db.prepare(R"( select type, omschrijving, @@ -97,7 +92,7 @@ Object * GameData::create_object(const string & name) const { } Location * GameData::create_location(const string & name) const{ - static DBStatement query = this->db->prepare(R"( + static DBStatement query = this->db.prepare(R"( select naam, beschrijving @@ -117,8 +112,8 @@ Location * GameData::create_location(const string & name) const{ } } -void GameData::leaderbord_add(const string & name, unsigned int gold) const { - static DBStatement stmt = this->db->prepare(R"( +void GameData::leaderbord_add(const string & name, unsigned int gold) { + static DBStatement stmt = this->db.prepare(R"( insert into Leaderboard (naam, goudstukken) values (?, ?) )"); @@ -130,7 +125,7 @@ void GameData::leaderbord_add(const string & name, unsigned int gold) const { } void GameData::leaderbord_print() const { - static DBStatement query = this->db->prepare(R"( + static DBStatement query = this->db.prepare(R"( select naam, goudstukken from Leaderboard order by goudstukken desc @@ -147,14 +142,15 @@ void GameData::leaderbord_print() const { } } -vector<string> GameData::random_locations(unsigned count) { - static DBStatement query = this->db->prepare(R"( +vector<string> GameData::random_names(const string & table, unsigned count) const { + static DBStatement query = this->db.prepare(R"( select naam - from Locaties + from ? order by random() limit ? )"); query.reset() + .bind(table.c_str()) .bind(count) ; @@ -165,3 +161,15 @@ vector<string> GameData::random_locations(unsigned count) { return names; } +vector<string> GameData::random_locations(unsigned count) const { + return this->random_names("Locaties", count); +} + +vector<string> GameData::random_objects(unsigned count) const { + return this->random_names("Objecten", count); +} + +vector<string> GameData::random_enemies(unsigned count) const { + return this->random_names("Vijanden", count); +} + diff --git a/frontend/GameData.h b/frontend/GameData.h index 0d7577d..b0c9415 100644 --- a/frontend/GameData.h +++ b/frontend/GameData.h @@ -1,7 +1,5 @@ #pragma once -#include <memory> - #include "DB.h" class Enemy; @@ -12,21 +10,24 @@ class GameData { public: static GameData & get_instance(); +private: + DB db { "kerkersendraken.db" }; + public: Enemy * create_enemy(const std::string & name) const; Object * create_object(const std::string & name) const; Location * create_location(const std::string & name) const; public: - void leaderbord_add(const std::string & name, unsigned int gold) const; + void leaderbord_add(const std::string & name, unsigned int gold); void leaderbord_print() const; - std::vector<std::string> random_locations(unsigned count = 1); -private: - GameData(); - virtual ~GameData() = default; +public: + std::vector<std::string> random_objects(unsigned count = 1) const; + std::vector<std::string> random_locations(unsigned count = 1) const; + std::vector<std::string> random_enemies(unsigned count = 1) const; private: - std::unique_ptr<DB> db = nullptr; + std::vector<std::string> random_names(const std::string & table, unsigned count) const; }; diff --git a/frontend/cmd/hit.cpp b/frontend/cmd/hit.cpp index 8866f60..94bde03 100644 --- a/frontend/cmd/hit.cpp +++ b/frontend/cmd/hit.cpp @@ -19,7 +19,7 @@ void GameController::cmd_hit(string & target_name) { if (rng.rand_double() > player.get_attack()) { lprtf("Je hebt gemist!\n"); } else { - unsigned damage = rng.rand_int(player.weapon->get_damage_min(), player.weapon->get_damage_max() + 1); + unsigned damage = rng.rand_int(player.weapon->get_damage()); enemy->take_damage(damage); lprtf("Je hebt %s geraakt en %d schade aangericht!\n", enemy->get_displayname().c_str(), damage); } @@ -1,2 +1,3 @@ #!/bin/sh git ls-files | xargs -d '\n' -- grep '\<TO''DO\>' -- +# TODO: use <algorithm> somewhere |