00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #ifndef CA_H
00027 #define CA_H
00028
00029 #ifndef BUILDING_DOX
00030 # include <bitset>
00031 # include <string>
00032 #endif
00033
00034 #include <boost/dynamic_bitset.hpp>
00035
00039 typedef signed long TCoord;
00040
00045 typedef unsigned long TBus;
00046
00050 #define RULE_WIDTH (1 << 5)
00051
00055 typedef std::bitset<RULE_WIDTH> TRule5N;
00056
00061 enum EDirection {
00062 D_NULL = 0,
00063 D_TOP,
00064 D_RIGHT,
00065 D_BOTTOM,
00066 D_LEFT,
00067 D_ONE_AFTER_LAST
00068 };
00069
00073 struct Pos {
00074 TCoord row;
00075 TCoord col;
00076
00077 Pos(): row(0), col(0) { }
00078 Pos(TCoord row_, TCoord col_):
00079 row(row_),
00080 col(col_)
00081 {
00082 }
00083 };
00084
00090 void writeRule(std::ostream &str, const TRule5N &rule);
00091
00098 inline Pos neighbor(Pos pos, EDirection dir) {
00099 switch (dir) {
00100 case D_TOP: return Pos(pos.row - 1, pos.col);
00101 case D_RIGHT: return Pos(pos.row, pos.col + 1);
00102 case D_BOTTOM: return Pos(pos.row + 1, pos.col);
00103 case D_LEFT: return Pos(pos.row, pos.col - 1);
00104 default: return pos;
00105 }
00106 }
00107
00114 class CaState {
00115 public:
00120 CaState(size_t size);
00121
00125 size_t size() const;
00126
00132 bool getCellAtPos(Pos pos) const;
00133
00140 void setCellAtPos(Pos pos, bool val);
00141
00142 bool operator== (const CaState &other) const;
00143 bool operator!= (const CaState &other) const {
00144 return !operator== (other);
00145 }
00146
00147 private:
00148 size_t size_;
00149 boost::dynamic_bitset <> bitset_;
00150 };
00151
00157 std::ostream& operator<< (std::ostream &str, const CaState &state);
00158
00166 bool applyRule(const CaState &ca, Pos pos, const TRule5N &rule);
00167
00174 class IGate {
00175 public:
00176 virtual ~IGate() { }
00177
00184 virtual IGate* clone() const = 0;
00185
00189 virtual size_t nInputs() const = 0;
00190
00194 virtual size_t nOutputs() const = 0;
00195
00202 virtual TBus operator[] (TBus in) const = 0;
00203 };
00204
00208 class IGateBinding {
00209 public:
00210 virtual ~IGateBinding() { }
00211
00218 virtual IGateBinding* clone() const = 0;
00219
00225 virtual void setInput(CaState &state, TBus in) const = 0;
00226
00233 virtual void setOutput(CaState &state, TBus out) const = 0;
00234
00240 virtual TBus getOutput(const CaState &state) const = 0;
00241 };
00242
00246 class ICaRules {
00247 public:
00248 virtual ~ICaRules() { }
00249 virtual ICaRules* clone() const = 0;
00250
00256 virtual void getRuleAtPos(Pos pos, TRule5N &rule) const = 0;
00257 };
00258
00265 bool applyRules(CaState &state, const ICaRules *rules);
00266
00272 struct CaEvalParams {
00273 size_t caSize;
00274 size_t nSteps;
00275 };
00276
00282 class CaEvaluator {
00283 public:
00289 CaEvaluator(
00290 const IGate &gate,
00291 const IGateBinding &binding,
00292 const CaEvalParams ¶ms);
00293 ~CaEvaluator();
00294
00298 size_t caSize() const;
00299
00306 float eval(const ICaRules *ca);
00307
00316 bool cntSteps(const ICaRules *ca, unsigned &min, unsigned &max);
00317
00325 void simulate(const ICaRules *ca, std::ostream &str, TBus in);
00326
00333 void simulate(const ICaRules *ca, std::ostream &str);
00334
00335 private:
00336 struct Private;
00337 Private *d;
00338 };
00339
00340 #endif // CA_H