Flat random generator:
...only one [random] structure with a comma-separated list in 'value', instead of nested structures. There is still some nesting when a [results] structure is needed. This new scheme should reduce the size of the replay and avoid hitting the nesting limit. It is supposed to be backward-compatible, hence a bit of complexity.
This commit is contained in:
parent
40bfc4bece
commit
0453a7b4cc
3 changed files with 55 additions and 35 deletions
|
@ -625,6 +625,7 @@ void attack(display& gui, const gamemap& map,
|
|||
LOG_NG << "start of attack loop...\n";
|
||||
|
||||
if(stats.nattacks > 0 && stats.defender_strikes_first == false) {
|
||||
add_random_separator();
|
||||
const int ran_num = get_random();
|
||||
bool hits = (ran_num%100) < stats.chance_to_hit_defender;
|
||||
|
||||
|
@ -794,6 +795,7 @@ void attack(display& gui, const gamemap& map,
|
|||
|
||||
if(stats.ndefends > 0) {
|
||||
LOG_NG << "doing defender attack...\n";
|
||||
add_random_separator();
|
||||
|
||||
const int ran_num = get_random();
|
||||
bool hits = (ran_num%100) < stats.chance_to_hit_attacker;
|
||||
|
|
|
@ -14,49 +14,66 @@
|
|||
#include "config.hpp"
|
||||
#include "random.hpp"
|
||||
#include "wassert.hpp"
|
||||
#include <sstream>
|
||||
|
||||
rng::rng() : random_(NULL), separator_(false)
|
||||
rng::rng() : random_(NULL)
|
||||
{}
|
||||
|
||||
int rng::get_random(int value)
|
||||
int rng::get_random()
|
||||
{
|
||||
separator_ = false;
|
||||
if (!random_)
|
||||
return rand();
|
||||
|
||||
if(random_ == NULL) {
|
||||
return value >= 0 ? value : rand();
|
||||
}
|
||||
|
||||
//random numbers are in a 'list' meaning that each random
|
||||
//number contains another random numbers unless it's at
|
||||
//the end of the list. Generating a new random number means
|
||||
//nesting a new node inside the current node, and making
|
||||
//the current node the new node
|
||||
config* const random = random_->child("random");
|
||||
if(random == NULL) {
|
||||
int res = value;
|
||||
if(value < 0)
|
||||
res = rand() & 0x7FFFFFFF;
|
||||
random_ = &random_->add_child("random");
|
||||
|
||||
char buf[100];
|
||||
sprintf(buf,"%d",res);
|
||||
(*random_)["value"] = buf;
|
||||
|
||||
return res;
|
||||
} else {
|
||||
const int res = atoi((*random)["value"].c_str());
|
||||
config *random;
|
||||
if (!started_ || separator_) {
|
||||
// setup the first [random] or find a nested [random]
|
||||
started_ = true;
|
||||
separator_ = false;
|
||||
random = random_->child("random");
|
||||
if (random == NULL) {
|
||||
random_ = &random_->add_child("random");
|
||||
remaining_values_ = "";
|
||||
goto new_value;
|
||||
}
|
||||
random_ = random;
|
||||
return res;
|
||||
remaining_values_ = (*random_)["value"];
|
||||
}
|
||||
|
||||
// find some remaining value
|
||||
while (remaining_values_.empty()) {
|
||||
random = random_->child("random");
|
||||
if (random == NULL) {
|
||||
// no remaining value nor child
|
||||
// create a new value and store it, then return it
|
||||
new_value:
|
||||
int res = rand() & 0x7FFFFFFF;
|
||||
std::ostringstream tmp;
|
||||
if (!(*random_)["value"].empty())
|
||||
tmp << ',';
|
||||
tmp << res;
|
||||
(*random_)["value"] += tmp.str();
|
||||
return res;
|
||||
}
|
||||
random_ = random;
|
||||
remaining_values_ = (*random_)["value"];
|
||||
}
|
||||
|
||||
// read the first remaining value and erase it
|
||||
int res = atoi(remaining_values_.c_str()); // atoi stops at the comma
|
||||
std::string::size_type pos = remaining_values_.find(',');
|
||||
if (pos != std::string::npos)
|
||||
remaining_values_.erase(0, pos + 1);
|
||||
else
|
||||
remaining_values_ = "";
|
||||
return res;
|
||||
}
|
||||
|
||||
const config* rng::get_random_results()
|
||||
{
|
||||
wassert(random_ != NULL);
|
||||
|
||||
if(separator_) {
|
||||
get_random(0);
|
||||
}
|
||||
if (separator_)
|
||||
get_random();
|
||||
return random_->child("results");
|
||||
}
|
||||
|
||||
|
@ -64,9 +81,8 @@ void rng::set_random_results(const config& cfg)
|
|||
{
|
||||
wassert(random_ != NULL);
|
||||
|
||||
if(separator_) {
|
||||
get_random(0);
|
||||
}
|
||||
if (separator_)
|
||||
get_random();
|
||||
random_->clear_children("results");
|
||||
random_->add_child("results",cfg);
|
||||
}
|
||||
|
@ -85,6 +101,7 @@ config* rng::set_random(config* random)
|
|||
{
|
||||
config* old = random_;
|
||||
random_ = random;
|
||||
started_ = false;
|
||||
separator_ = false;
|
||||
return old;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class rng
|
|||
{
|
||||
public:
|
||||
rng();
|
||||
int get_random(int value=-1);
|
||||
int get_random();
|
||||
|
||||
const config* get_random_results();
|
||||
void set_random_results(const config& cfg);
|
||||
|
@ -41,7 +41,8 @@ protected:
|
|||
|
||||
private:
|
||||
config* random_;
|
||||
bool separator_;
|
||||
bool separator_, started_;
|
||||
std::string remaining_values_;
|
||||
};
|
||||
|
||||
struct set_random_generator {
|
||||
|
|
Loading…
Add table
Reference in a new issue