1 // ==============================================================
2 // This file is part of MegaGlest Shared Library (www.megaglest.org)
3 //
4 // Copyright (C) 2012 Mark Vejvoda, Titus Tscharntke
5 // 2001-2008 Martiño Figueroa
6 //
7 // You can redistribute this code and/or modify it under
8 // the terms of the GNU General Public License as published
9 // by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version
11 // ==============================================================
12
13 #include "randomgen.h"
14 #include <cassert>
15 #include "util.h"
16 #include <stdexcept>
17 #include "platform_util.h"
18 #include "math_util.h"
19 #include "leak_dumper.h"
20
21 using namespace std;
22 using namespace Shared::Graphics;
23
24 namespace Shared { namespace Util {
25
26 // =====================================================
27 // class RandomGen
28 // =====================================================
29
30 const int RandomGen::m= 714025;
31 const int RandomGen::a= 1366;
32 const int RandomGen::b= 150889;
33
RandomGen()34 RandomGen::RandomGen() {
35 lastNumber= 0;
36 disableLastCallerTracking = false;
37 }
38
init(int seed)39 void RandomGen::init(int seed){
40 lastNumber= seed % m;
41 }
42
rand(string lastCaller)43 int RandomGen::rand(string lastCaller) {
44 if(lastCaller != "") {
45 this->lastCaller.push_back(lastCaller);
46 }
47 this->lastNumber = (a*lastNumber + b) % m;
48 return lastNumber;
49 }
50
getLastCaller() const51 std::string RandomGen::getLastCaller() const {
52 std::string result = "";
53 if(lastCaller.empty() == false) {
54 for(unsigned int index = 0; index < lastCaller.size(); ++index) {
55 result += lastCaller[index] + "|";
56 }
57 }
58 return result;
59 }
60
clearLastCaller()61 void RandomGen::clearLastCaller() {
62 if(lastCaller.empty() == false) {
63 lastCaller.clear();
64 }
65 }
addLastCaller(std::string text)66 void RandomGen::addLastCaller(std::string text) {
67 if(disableLastCallerTracking == false) {
68 lastCaller.push_back(text);
69 }
70 }
71
randRange(int min,int max,string lastCaller)72 int RandomGen::randRange(int min, int max,string lastCaller) {
73 if(min > max) {
74 char szBuf[8096]="";
75 snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %d, max = %d",__FILE__,__FUNCTION__,__LINE__,min,max);
76 throw megaglest_runtime_error(szBuf);
77 }
78
79 int diff= max-min;
80 float numerator = static_cast<float>(diff + 1) * static_cast<float>(this->rand(lastCaller));
81 int res= min + static_cast<int>(truncateDecimal<float>(numerator / static_cast<float>(m),6));
82 if(res < min || res > max) {
83 char szBuf[8096]="";
84 snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %d, max = %d, res = %d",__FILE__,__FUNCTION__,__LINE__,min,max,res);
85 throw megaglest_runtime_error(szBuf);
86 }
87 return res;
88 }
89
randRange(float min,float max,string lastCaller)90 float RandomGen::randRange(float min, float max,string lastCaller) {
91 if(min > max) {
92 char szBuf[8096]="";
93 snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %f, max = %f",__FILE__,__FUNCTION__,__LINE__,min,max);
94 throw megaglest_runtime_error(szBuf);
95 }
96
97 float rand01 = static_cast<float>(this->rand(lastCaller)) / (m-1);
98 float res= min + (max - min) * rand01;
99 res = truncateDecimal<float>(res,6);
100
101 if(res < min || res > max) {
102 char szBuf[8096]="";
103 snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %f, max = %f, res = %f",__FILE__,__FUNCTION__,__LINE__,min,max,res);
104 throw megaglest_runtime_error(szBuf);
105 }
106 return res;
107 }
108
109 }}//end namespace
110