MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Element_Mover.h
1 #ifndef ELEMENT_MOVER_H /* -*- C++ -*- */
2 #define ELEMENT_MOVER_H
3 
4 #include "Element.h"
5 #include "EventWindow.h"
6 #include "ElementTable.h"
7 #include "Element_Empty.h"
8 #include "Element_Dreg.h"
9 #include "Element_Res.h"
10 #include "itype.h"
11 #include "FXP.h"
12 #include "P1Atom.h"
13 
14 namespace MFM
15 {
16 #define MOVER_VERSION 1
17 
28  template <class CC>
29  class Element_Mover : public Element<CC>
30  {
31  // Extract short names for parameter types
32  typedef typename CC::ATOM_TYPE T;
33  typedef typename CC::PARAM_CONFIG P;
34  enum { R = P::EVENT_WINDOW_RADIUS };
35 
36  public:
37 
38  static Element_Mover THE_INSTANCE;
39  static const u32 TYPE() {
40  return THE_INSTANCE.GetType();
41  }
42 
43  static const u32 TYPE_BITS = 12;
44  static const u32 TYPE_MASK = (1<<TYPE_BITS)-1;
45 
46  static const u32 STATE_BITS = 0;
47 
48  static bool IsMoverType(u32 type)
49  {
50  return type==TYPE();
51  }
52 
53  Element_Mover() : Element<CC>(MFM_UUID_FOR("Mover", MOVER_VERSION))
54  {
56  Element<CC>::SetName("Mover");
57  }
58 
59  virtual const T & GetDefaultAtom() const
60  {
61  static T defaultAtom(TYPE(),0,0,STATE_BITS);
62  return defaultAtom;
63  }
64 
65  virtual u32 DefaultPhysicsColor() const
66  {
67  return 0xff0030e0;
68  }
69 
70  virtual u32 DefaultLowlightColor() const
71  {
72  return 0xff001870;
73  }
74 
75  virtual u32 PercentMovable(const T& you, const T& me, const SPoint& offset) const
76  {
77  return 100;
78  }
79 
80  virtual void Behavior(EventWindow<CC>& window) const
81  {
82  Random & random = window.GetRandom();
83 
84  T self = window.GetCenterAtom();
85  const u32 selfType = self.GetType();
86 
87  if (!IsMoverType(selfType))
88  FAIL(ILLEGAL_STATE);
89 
90  SPoint occup;
91  u32 occupCount = 0;
92 
93  u32 moverCount = 0;
94  u32 dregCount = 0;
95  u32 resCount = 0;
96 
97  SPoint empty;
98  u32 emptyCount = 0;
99 
100  const MDist<R> & md = MDist<R>::get();
101 
102  // Scan event window outside self
103  for (u32 idx = md.GetFirstIndex(1); idx <= md.GetLastIndex(1); ++idx) {
104  const SPoint sp = md.GetPoint(idx);
105 
106  if (!window.IsLiveSite(sp))
107  continue;
108 
109  // Empty or occupied?
110  const T other = window.GetRelativeAtom(sp);
111  const u32 otherType = other.GetType();
112  bool isEmpty = Element_Empty<CC>::THE_INSTANCE.IsType(otherType);
113 
114  if (isEmpty) {
115  if (random.OneIn(++emptyCount)) {
116  empty = sp;
117  }
118  } else {
119  if (otherType == Element_Mover<CC>::THE_INSTANCE.GetType())
120  ++moverCount;
121  else if (otherType == Element_Dreg<CC>::THE_INSTANCE.GetType())
122  ++dregCount;
123  else if (otherType == Element_Res<CC>::THE_INSTANCE.GetType())
124  ++resCount;
125 
126  if (random.OneIn(++occupCount)) {
127  occup = sp;
128  }
129  }
130  }
131 
132  if (occupCount > 0) {
133 
134  const T other = window.GetRelativeAtom(occup);
135  const u32 otherType = other.GetType();
136  bool isRes = otherType == Element_Res<CC>::TYPE();
137 
138  // Is it Res, and no other Movers, and we're inclined to convert?
139 
140  if (isRes && moverCount==0 && resCount > 1) {
141  window.SetRelativeAtom(occup,self); // Be Like Me!
142  } else if (emptyCount > 0) {
143  // If have empty and occup, swap
144  window.SwapAtoms(occup,empty);
145  }
146  }
147 
148  this->Diffuse(window);
149  }
150 
151  };
152 
153  template <class CC>
154  Element_Mover<CC> Element_Mover<CC>::THE_INSTANCE;
155 
156 }
157 
158 #endif /* ELEMENT_MOVER_H */
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
void Diffuse(EventWindow< CC > &window) const
Definition: Element.tcc:73
u32 GetType() const
Definition: Element.h:290
virtual u32 DefaultPhysicsColor() const
Definition: Element_Mover.h:65
Definition: Element_Empty.h:41
Definition: Random.h:45
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
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_Dreg.h:47
virtual u32 PercentMovable(const T &you, const T &me, const SPoint &offset) const
Definition: Element_Mover.h:75
const T & GetCenterAtom() const
Definition: EventWindow.h:209
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_Mover.h:80
virtual u32 DefaultLowlightColor() const
Definition: Element_Mover.h:70
Definition: MDist.h:69
bool IsType(u32 type) const
Definition: Element.h:345
Element(const UUID &uuid)
Definition: Element.h:246
Definition: Element_Mover.h:28
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 const T & GetDefaultAtom() const
Definition: Element_Mover.h:59
void SwapAtoms(const SPoint &locA, const SPoint &locB)
Definition: EventWindow.tcc:40