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