From 01d39a192b198fd8a5daf6709cac0222da8d1bc8 Mon Sep 17 00:00:00 2001
From: Mikhail Andrenkov <mandrenkov@localhost.localdomain>
Date: Sat, 22 Oct 2016 13:24:15 -0400
Subject: [PATCH] Fixed Randomization Error

---
 src/armor.cpp         | 12 +++++++++---
 src/include/globals.h |  6 +++++-
 src/include/item.h    |  1 +
 src/include/random.h  | 19 ++++++++-----------
 src/item.cpp          | 10 ++--------
 src/level.cpp         |  2 +-
 src/potion.cpp        |  3 ++-
 src/random.cpp        | 17 ++++++++++-------
 src/ring.cpp          |  7 ++++---
 src/scroll.cpp        |  9 +++++----
 src/wand.cpp          |  5 +++--
 src/weapon.cpp        | 20 +++++++++++++++++---
 12 files changed, 67 insertions(+), 44 deletions(-)

diff --git a/src/armor.cpp b/src/armor.cpp
index 145b18b..ce04654 100644
--- a/src/armor.cpp
+++ b/src/armor.cpp
@@ -4,7 +4,7 @@
 #include "include/armor.h"
 #include "include/coord.h"
 #include "include/item.h"
-
+#include "include/random.h"
 
 std::vector<ARMOR_TUPLE_TYPE > Armor::typeVector = {
 	ARMOR_TUPLE_TYPE {"Leather Armor", 3},
@@ -17,13 +17,19 @@ std::vector<ARMOR_TUPLE_TYPE > Armor::typeVector = {
 };
 
 Armor::Armor(Coord location)
-	: Armor(location, Item::Context::FLOOR, rand() % Armor::typeVector.size()) {}
+	: Armor(location, Item::Context::FLOOR, Generator::intFromRange(0, Armor::typeVector.size() - 1)) {}
 
 Armor::Armor(Coord location, Item::Context context, int type)
 	: Item(']', location, context, "Armor", std::get<0>(Armor::typeVector[type]), type, false, false),
 	  rating(std::get<1>(Armor::typeVector[type])) {
+		int chance = Generator::intFromRange(1, 100);
 
-	  	this->enchantProtection = (rand() % 3) - 1;
+                if (chance <= 16) {
+			this->cursed = true;
+			this->enchantProtection -= Generator::intFromRange(0, 3);
+		} else if (chance <= 33) {
+			this->enchantProtection += Generator::intFromRange(0, 3);
+		}
 	}
 
 int Armor::getRating() {
diff --git a/src/include/globals.h b/src/include/globals.h
index 2d6f450..1194092 100644
--- a/src/include/globals.h
+++ b/src/include/globals.h
@@ -1,7 +1,11 @@
+#pragma once
+
 #include <string>
 
+#include "random.h"
+
 //please don't put mutable state here
 
-const int NUM_LEVELS = 30;
+const int NUM_LEVELS = 26;
 const int NAME_LENGTH = 10;
 const std::string VALID_NAME = "abcdefghijklmnopqrstuvwxyz _ABCDEFGHIJKLMNOPQRSTUVWXYZ";
diff --git a/src/include/item.h b/src/include/item.h
index 8df7343..3b27896 100644
--- a/src/include/item.h
+++ b/src/include/item.h
@@ -37,6 +37,7 @@ class Item : public Feature {
 		bool canThrow;
 		std::string className;
 		Context context;
+		bool cursed;
 		std::string name;
 		std::string pseudoName;
 		int type;
diff --git a/src/include/random.h b/src/include/random.h
index e4c542f..a5aaf81 100644
--- a/src/include/random.h
+++ b/src/include/random.h
@@ -1,21 +1,18 @@
+#pragma once
+
 #include <random>
 #include <string>
 #include <vector>
 
 #include "coord.h"
 
-#ifndef RANDOM_H
-#define RANDOM_H
-
 class Generator {
 	public:
-		Generator();
-		int intFromRange(int, int);
-		double operator()();
-		Coord randPosition(Coord, Coord);
-		void shuffle(std::vector<Coord>*);
+		static int intFromRange(int, int);
+		static double rand();
+		static bool randBool();
+		static Coord randPosition(Coord, Coord);
+		static void shuffle(std::vector<Coord>*);
 	private:
-		std::mt19937 gen;
+		static std::mt19937 gen;
 };
-
-#endif
diff --git a/src/item.cpp b/src/item.cpp
index a9d20a0..04ef455 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -4,6 +4,7 @@
 #include <vector>
 
 #include "include/item.h"
+#include "include/random.h"
 
 std::map<std::string, std::map<int, bool> > Item::identified;
 
@@ -23,14 +24,7 @@ Item::Item(char symbol, Coord location, Item::Context context, std::string class
 	  type(type) {}
 
 Item::Item(char symbol, Coord location, Item::Context context, std::string className, std::string name, int type, bool canStack, bool canThrow)
-	: Feature(symbol, location),
-	  canStack(canStack),
-	  canThrow(canThrow),
-	  className(className),
-	  context(context),
-	  name(name),
-	  pseudoName(name),
-	  type(type) {}
+	: Item(symbol, location, context, className, name, name, type, canStack, canThrow) {} 
 
 bool Item::operator==(const Item& other) const {
 	return this->name.compare(other.name) == 0;
diff --git a/src/level.cpp b/src/level.cpp
index 0383794..1a085f4 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -125,7 +125,7 @@ void Level::generate(PlayerChar player) {
 		bool dne = false;
 
 		//If room DNE, set its size to 1x1
-		if (gen() > ROOM_EXIST_CHANCE){
+		if (gen.rand() > ROOM_EXIST_CHANCE){
 			roomSize = Coord(1,1);
 			dne = true;
 		}
diff --git a/src/potion.cpp b/src/potion.cpp
index 550abc6..4aa9efc 100644
--- a/src/potion.cpp
+++ b/src/potion.cpp
@@ -5,6 +5,7 @@
 #include "include/coord.h"
 #include "include/item.h"
 #include "include/potion.h"
+#include "include/random.h"
 
 std::vector<std::string> Potion::nameVector = Item::shuffleNameVector({
 	"Blue Potion", "Red Potion", "Green Potion", "Grey Potion", "Brown Potion",
@@ -30,7 +31,7 @@ std::vector<POTION_TUPLE_TYPE > Potion::typeVector = {
 };
 
 Potion::Potion(Coord location)
-	: Potion(location, Item::Context::FLOOR, rand() % Potion::typeVector.size()) {}
+	: Potion(location, Item::Context::FLOOR, Generator::intFromRange(0, Potion::typeVector.size() - 1)) {}
 
 Potion::Potion(Coord location, Item::Context context, int type)
 	: Item('!', location, context, "Potion", std::get<0>(Potion::typeVector[type]), Potion::nameVector[type], type, true, true) {}
diff --git a/src/random.cpp b/src/random.cpp
index 86a4868..14861a0 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -1,25 +1,28 @@
-#include <random>
 #include <algorithm>
-#include "include/random.h"
+#include <random>
+
 #include "include/coord.h"
+#include "include/random.h"
 
-Generator::Generator() {
-	gen = std::mt19937(std::random_device()());
-}
+std::mt19937 Generator::gen = std::mt19937(std::random_device()());
 
 //inclusive
 int Generator::intFromRange(int lower, int upper) {
 	return std::uniform_int_distribution<>(lower, upper)(gen);
 }
 
-double Generator::operator()() {
+double Generator::rand() {
 	return std::uniform_real_distribution<>(0, 1)(gen);
 }
 
+bool Generator::randBool() {
+	return rand() < 0.5;
+}
+
 Coord Generator::randPosition(Coord a, Coord b) {
 	return Coord(intFromRange(a[0], b[0]), intFromRange(a[1], b[1]));
 }
 
 void Generator::shuffle(std::vector<Coord>* s) {
 	std::random_shuffle(s->begin(), s->end());
-}
\ No newline at end of file
+}
diff --git a/src/ring.cpp b/src/ring.cpp
index 2dd0e7b..1aeba69 100644
--- a/src/ring.cpp
+++ b/src/ring.cpp
@@ -4,6 +4,7 @@
 
 #include "include/coord.h"
 #include "include/item.h"
+#include "include/random.h"
 #include "include/ring.h"
 
 std::vector<std::string> Ring::nameVector = Item::shuffleNameVector({
@@ -27,11 +28,11 @@ std::vector<RING_TUPLE_TYPE > Ring::typeVector = {
 };
 
 Ring::Ring(Coord location)
-	: Ring(location, Item::Context::FLOOR, rand() % Ring::typeVector.size()) {}
+	: Ring(location, Item::Context::FLOOR, Generator::intFromRange(0, Ring::typeVector.size() - 1)) {}
 
 Ring::Ring(Coord location, Item::Context context, int type)
 	: Item('=', location, context, "Ring", std::get<0>(Ring::typeVector[type]), Ring::nameVector[type], type, true, true) {}
 
-bool Ring::activate(Level* level) {
+bool Ring::activate(Level* level) { 
 	return false;
-}
\ No newline at end of file
+}
diff --git a/src/scroll.cpp b/src/scroll.cpp
index 1c56004..9768306 100644
--- a/src/scroll.cpp
+++ b/src/scroll.cpp
@@ -4,6 +4,7 @@
 
 #include "include/coord.h"
 #include "include/item.h"
+#include "include/random.h"
 #include "include/scroll.h"
 
 
@@ -40,12 +41,12 @@ std::vector<std::string> Scroll::initializeScrollNames() {
 	std::vector<std::string> nameVector;
 	for (int type = 0 ; type < static_cast<int>(Scroll::typeVector.size()) ; type++) {
 		std::string scrollName = "Scroll titled '";
-		scrollName += Scroll::syllableVector[rand() % Scroll::syllableVector.size()];
+		scrollName += Scroll::syllableVector[Generator::intFromRange(0, Scroll::syllableVector.size() - 1)];
 
-		int syllables = 1 + (rand() % 3);
+		int syllables = Generator::intFromRange(1, 3);
 
 		for (int syll = 0 ; syll < syllables ; syll++) {
-			scrollName += " " + Scroll::syllableVector[rand() % Scroll::syllableVector.size()];
+			scrollName += " " + Scroll::syllableVector[Generator::intFromRange(0, Scroll::syllableVector.size() - 1)];
 		}
 
 		scrollName += "'";
@@ -56,7 +57,7 @@ std::vector<std::string> Scroll::initializeScrollNames() {
 }
 
 Scroll::Scroll(Coord location)
-	: Scroll(location, Item::Context::FLOOR, rand() % Scroll::typeVector.size()) {}
+	: Scroll(location, Item::Context::FLOOR, Generator::intFromRange(0, Scroll::typeVector.size() - 1)) {}
 
 Scroll::Scroll(Coord location, Item::Context context, int type)
 	: Item('?', location, context, "Scroll", std::get<0>(Scroll::typeVector[type]), Scroll::nameVector[type], type, true, true) {}
diff --git a/src/wand.cpp b/src/wand.cpp
index e3dd500..189e3b6 100644
--- a/src/wand.cpp
+++ b/src/wand.cpp
@@ -4,6 +4,7 @@
 
 #include "include/coord.h"
 #include "include/item.h"
+#include "include/random.h"
 #include "include/wand.h"
 
 std::vector<WAND_TUPLE_TYPE > Wand::typeVector = {
@@ -31,11 +32,11 @@ std::vector<std::string> Wand::nameVector = Item::shuffleNameVector({
 
 
 Wand::Wand(Coord location)
-	: Wand(location, Item::Context::FLOOR, rand() % Wand::typeVector.size()) {}
+	: Wand(location, Item::Context::FLOOR, Generator::intFromRange(0, Wand::typeVector.size() - 1)) {}
 
 Wand::Wand(Coord location, Item::Context context, int type)
 	: Item('/', location, context, "Wand", std::get<0>(Wand::typeVector[type]), Wand::nameVector[type], type, false, false),
-	  charges(3 + (rand() % 5)) {}
+	  charges(Generator::intFromRange(3, 7)) {}
 
 bool Wand::activate(Level* level) {
 	this->charges--;
diff --git a/src/weapon.cpp b/src/weapon.cpp
index 27c13d0..e922087 100644
--- a/src/weapon.cpp
+++ b/src/weapon.cpp
@@ -3,6 +3,7 @@
 
 #include "include/coord.h"
 #include "include/item.h"
+#include "include/random.h"
 #include "include/weapon.h"
 
 std::vector<WEAPON_TUPLE_TYPE > Weapon::typeVector = {
@@ -17,16 +18,29 @@ std::vector<WEAPON_TUPLE_TYPE > Weapon::typeVector = {
 };
 
 Weapon::Weapon(Coord location)
-	: Weapon(location, Item::Context::FLOOR, rand() % Weapon::typeVector.size()) {}
+	: Weapon(location, Item::Context::FLOOR, Generator::intFromRange(0, Weapon::typeVector.size() - 1)) {}
 
 Weapon::Weapon(Coord location, Item::Context context, int type)
 	: Item(')', location, context, "Weapon", std::get<0>(Weapon::typeVector[type]), type, std::get<3>(Weapon::typeVector[type]), true),
 	  damage(std::get<1>(Weapon::typeVector[type])),
 	  melee (std::get<2>(Weapon::typeVector[type])) {
 
-	  	this->enchantDamage = (rand() % 3) - 1;
-	  	this->enchantHit = (rand() % 3) - 1;
+	int chance = Generator::intFromRange(1, 96);
+	int iterations = Generator::intFromRange(1, 3);
+	int increment = 0;
+
+	if (chance <= 16) {
+		increment = -1;
+		this->cursed = true;
+	} else if (chance <= 32) {
+		increment = 1;
+	}
+
+	for (int i = 0 ; i < iterations ; i ++) {
+		if (Generator::randBool()) this->enchantDamage += increment;
+		else this->enchantHit += increment; 
 	}
+}
 
 int Weapon::getChance() {
 	return this->enchantHit;
-- 
GitLab