- Fix a build failure from a missing header declaration;
[lsystem3d.git] / src / ruleset.cpp
CommitLineData
71fe8484 1// Copyright (C) 2006 Erik Dahlberg
2//
3// This file is part of LSystem3D.
4//
5// LSystem3D is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// LSystem3D is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with LSystem3D; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
fa21e8cd 21#include <cstdlib>
71fe8484 22#include <cmath>
23#include <ctime>
24
25#include <string>
26#include <utility>
27
28#include "rule.h"
29#include "ruleset.h"
30
31
32
33/**
34 * Constructor
35 */
36RuleSet::RuleSet()
37{
38 srand(time(NULL));
39}
40
41
42
43/**
44 * Destructor
45 */
46RuleSet::~RuleSet()
47{
48}
49
50
51
52/**
53 * Clear rule set
54 */
55void RuleSet::clear()
56{
57 _rules.clear();
58}
59
60
61
62/**
63 * Add one rule
64 * @param rule the rule
65 */
66void RuleSet::addRule(Rule rule)
67{
68 _rules.insert(make_pair(rule.getName(), rule));
69}
70
71
72
73/**
74 * Get one rule with repect of probability factor
75 * @param name the rule name
76 * @return the rule
77 */
78Rule RuleSet::findRule(string ruleName)
79{
80 // TODO: clean up...
81
82
83 int numRules = _rules.count(ruleName);
84 Rule selectedRule;
85
86 if (numRules == 0)
87 {
88 // no rule with this name
89 selectedRule.setProbability(0.0);
90 }
91 else if (numRules == 1)
92 {
93 // only one rule with this name
94 selectedRule = _rules.find(ruleName)->second;
95 }
96 else
97 {
98 // many rules with this name
99
100
101 // find ranges
102
103 // TODO: int ok?
104 int ranges[numRules + 1];
105
106 double lastRange = ranges[0] = 0;
107 int index = 1;
108
109 // TODO: move to addRule()
110 pair<rulemap::iterator, rulemap::iterator> interval = _rules.equal_range(ruleName);
111 for (rulemap::iterator it = interval.first; it != interval.second; it++)
112 {
113 // calculate and store ranges
114 lastRange += it->second.getProbability() * RAND_MAX;
115 ranges[index++] = (int)lastRange;
116 }
117
118 ranges[numRules] = RAND_MAX;
119
120
121 // choose random range
122
123 int selection = 0;
124 int random = rand();
125
126 for (int i = 0; i < numRules; i++)
127 {
128 if (random >= ranges[i] && random <= ranges[i + 1])
129 {
130 // in range
131 selection = i;
132
133 break;
134 }
135 }
136
137
138 // make selection
139
140 rulemap::iterator it = interval.first;
141 for (int i = 0; i < selection; i++)
142 {
143 it++;
144 }
145 selectedRule = it->second;
146 }
147
148
149 return selectedRule;
150}
151
152
153
154/**
155 * Get all rules
156 * @return the rules
157 */
158rulemap RuleSet::getRules()
159{
160 return _rules;
161}