MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Element_Collector.h
1 #ifndef ELEMENT_COLLECTOR_H /* -*- C++ -*- */
2 #define ELEMENT_COLLECTOR_H
3 
4 #include "Element.h"
5 #include "EventWindow.h"
6 #include "ElementTable.h"
7 #include "Element_Empty.h"
8 #include "Element_Res.h"
9 #include "itype.h"
10 #include "FXP.h"
11 #include "P1Atom.h"
12 
13 namespace MFM
14 {
15 
22  template <class CC>
23  class Element_Collector : public Element<CC>
24  {
25  // Extract short names for parameter types
26  typedef typename CC::ATOM_TYPE T;
27  typedef typename CC::PARAM_CONFIG P;
28  enum { R = P::EVENT_WINDOW_RADIUS };
29 
30  public:
31  enum {
32  COLLECTOR_VERSION = 1
33  };
34 
35  static Element_Collector THE_INSTANCE;
36  static const u32 TYPE() {
37  return THE_INSTANCE.GetType();
38  }
39 
40  static bool IsMyType(u32 type) {
41  return type==TYPE();
42  }
43 
44  Element_Collector() : Element<CC>(MFM_UUID_FOR("PileMaker", COLLECTOR_VERSION))
45  {
47  Element<CC>::SetName("Collector (PileMaker)");
48  }
49 
50  virtual const T & GetDefaultAtom() const
51  {
52  static T defaultAtom(TYPE(),0,0,0);
53  return defaultAtom;
54  }
55 
56  virtual u32 DefaultPhysicsColor() const
57  {
58  return 0xff00c8c8;
59  }
60 
61  virtual u32 DefaultLowlightColor() const
62  {
63  return 0xff007070;
64  }
65 
66  virtual u32 PercentMovable(const T& you, const T& me, const SPoint& offset) const
67  {
68  return 100;
69  }
70 
71  virtual void Behavior(EventWindow<CC>& window) const
72  {
73  Random & random = window.GetRandom();
74 
75  T self = window.GetCenterAtom();
76  const u32 selfType = self.GetType();
77 
78  if (!IsMyType(selfType))
79  FAIL(ILLEGAL_STATE);
80 
81  SPoint occup;
82  u32 occupCount = 0;
83  u32 occupType = 0;
84 
85  u32 meCount = 0;
86  SPoint resLoc;
87  u32 resCount = 0;
88 
89  SPoint empty;
90  u32 emptyCount = 0;
91 
92  const MDist<R> & md = MDist<R>::get();
93 
94  // Scan near me for mytypes, res, or other object
95  for (u32 idx = md.GetFirstIndex(1); idx <= md.GetLastIndex(2); ++idx) {
96  const SPoint sp = md.GetPoint(idx);
97 
98  if (!window.IsLiveSite(sp))
99  continue;
100 
101  // Empty or occupied?
102  const T other = window.GetRelativeAtom(sp);
103  const u32 otherType = other.GetType();
104  bool isEmpty = Element_Empty<CC>::THE_INSTANCE.IsType(otherType);
105 
106  if (isEmpty) {
107  if (random.OneIn(++emptyCount)) {
108  empty = sp;
109  }
110  } else {
111  if (otherType == selfType)
112  ++meCount;
113  else if (otherType == Element_Res<CC>::THE_INSTANCE.GetType()) {
114  if (random.OneIn(++resCount)) {
115  resLoc = sp;
116  }
117  } else if (random.OneIn(++occupCount)) {
118  occup = sp;
119  occupType = otherType;
120  }
121  }
122  }
123 
124  if (occupCount > 0 && emptyCount > 0) {
125 
126  u32 otherCount = 0;
127 
128  // Scan near them for other theirtypes
129  for (u32 idx = md.GetFirstIndex(1); idx <= md.GetLastIndex(2); ++idx) {
130  const SPoint sp = md.GetPoint(idx) + occup;
131 
132  if (!window.IsLiveSite(sp))
133  continue;
134 
135  const T other = window.GetRelativeAtom(sp);
136  const u32 otherType = other.GetType();
137 
138  // One of them? One of them?
139  if (otherType == occupType) {
140  ++otherCount;
141  }
142  }
143 
144  if ((otherCount == 0 || random.OneIn(100*otherCount)) && emptyCount > 0) {
145  // They are alone (or unlucky) and we have an empty nearish us. Pull them in
146  window.SwapAtoms(occup,empty);
147  } else {
148 
149  // Nothing to do. Clonebomb?
150  if (resCount > 1 && meCount == 0) {
151  window.SetRelativeAtom(resLoc,self); // Be Like Me!
152  }
153  }
154  }
155 
156  this->Diffuse(window);
157  }
158 
159  };
160 
161  template <class CC>
162  Element_Collector<CC> Element_Collector<CC>::THE_INSTANCE;
163 
164 }
165 
166 #endif /* ELEMENT_COLLECTOR_H */
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
void Diffuse(EventWindow< CC > &window) const
Definition: Element.tcc:73
virtual u32 PercentMovable(const T &you, const T &me, const SPoint &offset) const
Definition: Element_Collector.h:66
u32 GetType() const
Definition: Element.h:290
Definition: Element_Empty.h:41
Definition: Random.h:45
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_Collector.h:71
virtual u32 DefaultPhysicsColor() const
Definition: Element_Collector.h:56
void SetName(const char *name)
Definition: Element.h:209
void SetAtomicSymbol(const char *symbol)
Definition: Element.h:193
bool IsLiveSite(const SPoint &location) const
Definition: EventWindow.h:148
bool OneIn(u32 odds)
Definition: Random.h:96
Random & GetRandom()
Definition: EventWindow.h:122
const T & GetRelativeAtom(const SPoint &offset) const
Definition: EventWindow.tcc:26
Definition: Element_Collector.h:23
const T & GetCenterAtom() const
Definition: EventWindow.h:209
virtual const T & GetDefaultAtom() const
Definition: Element_Collector.h:50
Definition: MDist.h:69
bool IsType(u32 type) const
Definition: Element.h:345
static MDist< R > & get()
Definition: MDist.tcc:193
Definition: Element_Res.h:48
Definition: ElementTable.h:43
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
virtual u32 DefaultLowlightColor() const
Definition: Element_Collector.h:61
Definition: Atom.h:43
void SwapAtoms(const SPoint &locA, const SPoint &locB)
Definition: EventWindow.tcc:40