MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Element_Bar.h
1 #ifndef ELEMENT_BAR_H /* -*- C++ -*- */
2 #define ELEMENT_BAR_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 #include "ColorMap.h"
13 
14 namespace MFM
15 {
16 
44  template <class CC>
45  class Element_Bar : public Element<CC>
46  {
47  // Extract short names for parameter types
48  typedef typename CC::ATOM_TYPE T;
49  typedef typename CC::PARAM_CONFIG P;
50  enum { R = P::EVENT_WINDOW_RADIUS };
51 
52  template <u32 TVBITS>
53  static u32 toSignMag(s32 value) {
54  const u32 SIGN_BIT = 1<<(TVBITS-1);
55  const u32 MAX = SIGN_BIT-1;
56  u32 sign = 0;
57  if (value < 0) {
58  sign = SIGN_BIT;
59  value = -value;
60  }
61  if (value > MAX)
62  value = MAX;
63  u32 val = (u32) value;
64  return sign|val;
65  }
66 
67  template <u32 TVBITS>
68  static u32 toMag(u32 value) {
69  const u32 MAX = (1<<TVBITS)-1;
70  if (value < 0) {
71  FAIL(ILLEGAL_ARGUMENT);
72  }
73  if (value > MAX)
74  value = MAX;
75  u32 val = value;
76  return val;
77  }
78 
79  template <u32 TVBITS>
80  static s32 fromSignMag(const u32 value) {
81  const u32 SIGN_BIT = 1<<(TVBITS-1);
82  const u32 MASK = SIGN_BIT-1;
83  FXP16 val = value&MASK;
84  if (value & SIGN_BIT)
85  val = -val;
86  return val;
87  }
88 
89  template <u32 TVBITS>
90  static u32 fromMag(const u32 value) {
91  const u32 MASK = (1<<TVBITS)-1;
92  u32 val = value&MASK;
93  return val;
94  }
95 
96  template <u32 TVBITS>
97  static u32 toSTiny(const SPoint & v) {
98  u32 x = toSignMag<TVBITS>(v.GetX());
99  u32 y = toSignMag<TVBITS>(v.GetY());
100  return (x<<TVBITS)|y;
101  }
102 
103 
104  template <u32 TVBITS>
105  static u32 toUTiny(const UPoint & v) {
106  u32 x = toMag<TVBITS>(v.GetX());
107  u32 y = toMag<TVBITS>(v.GetY());
108  return (x<<TVBITS)|y;
109  }
110 
111  template <u32 TVBITS>
112  static SPoint toSPoint(const u32 bits) {
113  const u32 MASK = (1<<TVBITS)-1;
114 
115  s32 x = fromSignMag<TVBITS>((bits>>TVBITS)&MASK);
116  s32 y = fromSignMag<TVBITS>(bits&MASK);
117  return SPoint(x,y);
118  }
119 
120  template <u32 TVBITS>
121  static UPoint toUPoint(const u32 bits) {
122  const u32 MASK = (1<<TVBITS)-1;
123 
124  u32 x = fromMag<TVBITS>((bits>>TVBITS)&MASK);
125  u32 y = fromMag<TVBITS>(bits&MASK);
126  return UPoint(x,y);
127  }
128 
129  public:
130  const char* GetName() const { return "Bar"; }
131 
132  static Element_Bar THE_INSTANCE;
133  static const u32 TYPE() {
134  return THE_INSTANCE.GetType();
135  }
136 
137  static const u32 TYPE_BITS = 8;
138  static const u32 TYPE_MASK = (1<<TYPE_BITS)-1;
139  static bool IsBarType(u32 type) {
140  return type==TYPE;
141  }
142 
143  static const u32 BITS_PER_DIM = 8;
144 
145  static const u32 STATE_SIZE_IDX = 0;
146  static const u32 STATE_SIZE_LEN = 2 * BITS_PER_DIM;
147  static const u32 STATE_POS_IDX = STATE_SIZE_IDX + STATE_SIZE_LEN;
148  static const u32 STATE_POS_LEN = 2 * BITS_PER_DIM;
149  static const u32 STATE_BITS = STATE_POS_IDX + STATE_POS_LEN;
150 
151  Element_Bar() { }
152 
153  SPoint GetMax(const T &atom) const {
154  if (!IsBarType(atom.GetType()))
155  FAIL(ILLEGAL_STATE);
156  return MakeSigned(toUPoint<BITS_PER_DIM>(atom.GetStateField(STATE_SIZE_IDX,STATE_SIZE_LEN)));
157  }
158 
159  SPoint GetPos(const T &atom) const {
160  if (!IsBarType(atom.GetType()))
161  FAIL(ILLEGAL_STATE);
162  return MakeSigned(toUPoint<BITS_PER_DIM>(atom.GetStateField(STATE_POS_IDX,STATE_POS_LEN)));
163  }
164 
165  bool FitsInRep(const SPoint & v) const {
166  return v.BoundedBy(SPoint(0,0),SPoint((1<<BITS_PER_DIM)-1,(1<<BITS_PER_DIM)-1));
167  }
168 
169  void SetSize(T &atom, const SPoint & v) const {
170  if (!IsBarType(atom.GetType()))
171  FAIL(ILLEGAL_STATE);
172  if (!FitsInRep(v))
173  FAIL(ILLEGAL_ARGUMENT);
174  atom.SetStateField(STATE_SIZE_IDX,STATE_SIZE_LEN,toUTiny<BITS_PER_DIM>(MakeUnsigned(v)));
175  }
176 
177  void SetPos(T &atom, const SPoint v) const {
178  if (!IsBarType(atom.GetType()))
179  FAIL(ILLEGAL_STATE);
180  if (!FitsInRep(v))
181  FAIL(ILLEGAL_ARGUMENT);
182  atom.SetStateField(STATE_POS_IDX,STATE_POS_LEN,toUTiny<BITS_PER_DIM>(MakeUnsigned(v)));
183  }
184 
185  virtual const T & GetDefaultAtom() const
186  {
187  static T defaultAtom(TYPE,0,0,STATE_BITS);
188  return defaultAtom;
189  }
190 
191  T GetAtom(const SPoint & size, const SPoint & pos) const
192  {
193  T atom = GetDefaultAtom();
194  SetSize(atom,size);
195  SetPos(atom,pos);
196 
197  return atom;
198  }
199 
200  virtual u32 DefaultPhysicsColor() const
201  {
202  return 0xfff00505;
203  }
204 
205  virtual u32 DefaultLowlightColor() const
206  {
207  return 0xff700202;
208  }
209 
210  virtual u32 LocalPhysicsColor(const T & atom, u32 selector) const
211  {
212  switch (selector) {
213  case 1: {
214  SPoint barMax = GetMax(atom);
215  SPoint myPos = GetPos(atom);
216  return ColorMap_SEQ6_PuRd::THE_INSTANCE.
217  GetInterpolatedColor(myPos.GetEuclideanLength(),
218  0,barMax.GetEuclideanLength(),
219  0xffff0000);
220  }
221  default:
222  return Element<CC>::PhysicsColor();
223  }
224  }
225 
226  virtual void Behavior(EventWindow<CC>& window) const
227  {
228  Random & random = window.GetRandom();
229 
230  T self = window.GetCenterAtom();
231  const u32 selfType = self.GetType();
232 
233  if (!IsBarType(selfType))
234  FAIL(ILLEGAL_STATE);
235 
236  SPoint barMax = GetMax(self);
237 
238  SPoint myPos = GetPos(self);
239  // myPos.Print(stderr);
240 
241  const MDist<R> md = MDist<R>::get();
242 
243  SPoint anInconsistent;
244  u32 inconsistentCount = 0;
245  T unmakeGuy;
246 
247  u32 consistentCount = 0;
248 
249  SPoint toMake;
250  T makeGuy;
251  u32 makeCount = 0;
252 
253  SPoint toEat;
254  u32 eatCount = 0;
255 
256  // Scan event window outside self
257  for (u32 idx = md.GetFirstIndex(1); idx <= md.GetLastIndex(R); ++idx) {
258  const SPoint sp = md.GetPoint(idx);
259 
260  // First question: A 'bar grid' site?
261  bool onGrid = (sp.GetX()&1)==0 && (sp.GetY()&1)==0;
262 
263  if (onGrid) {
264  // Next question: Site within the bounds of the bar?
265 
266  const SPoint theirBarPos = sp+myPos;
267  bool inBar = theirBarPos.BoundedBy(SPoint(0,0),barMax);
268 
269  if (inBar) {
270  // Next question: Site empty?
271 
272  const T other = window.GetRelativeAtom(sp);
273  const u32 otherType = other.GetType();
274 
275  bool isEmpty = otherType == Element_Empty<CC>::TYPE;
276 
277  if (isEmpty) {
278 
279  if (random.OneIn(++makeCount)) {
280  toMake = sp;
281  makeGuy = self; // Start with us
282  SetPos(makeGuy,theirBarPos); // Update position
283  //window.SetRelativeAtom(sp,them); // Store
284  }
285 
286  } else {
287 
288  // Next question: Are they also a bar?
289  if (IsBarType(otherType)) {
290 
291  // Next question: Are they consistent with us?
292 
293  SPoint otherBarMax = GetMax(other);
294  SPoint otherPos = GetPos(other);
295 
296  SPoint otherPosMapped = otherPos-sp;
297  if (otherBarMax==barMax && otherPosMapped == myPos) {
298  ++consistentCount;
299  } else if (random.OneIn(++inconsistentCount)) {
300  anInconsistent = sp;
301  // Inconsistent Bars decay to Res
303  }
304  }
305 
306  }
307  }
308  } else {
309  // This is a non-grid site. We'd kind of like it to be Res,
310  // and if not that, empty, but we'd really like it not to
311  // have Bar's in it
312 
313  const T other = window.GetRelativeAtom(sp);
314  const u32 otherType = other.GetType();
315 
316  bool isRes = otherType == Element_Res<CC>::TYPE;
317  if (isRes) {
318  ++consistentCount;
319  if (random.OneIn(++eatCount)) {
320  toEat = sp;
321  }
322  }
323  else {
324 
325  bool isEmpty = otherType == Element_Empty<CC>::TYPE;
326 
327  if (isEmpty) ++consistentCount;
328  else {
329  bool isBar = otherType == Element_Bar<CC>::TYPE;
330  if (isBar) {
331  if (random.OneIn(++inconsistentCount)) {
332  anInconsistent = sp;
334  }
335  }
336  }
337  }
338  }
339  }
340 
341  // Scan finished. Let's decide what to do.
342 
343  // First question: Are we inconsistent with anybody?
344  if (inconsistentCount > 0) {
345  // Next question: Are we much more consistent than inconsistent?
346  if (consistentCount > 3*inconsistentCount) {
347  // Yes. Punish selected loser
348  window.SetRelativeAtom(anInconsistent, unmakeGuy);
349  } else if (inconsistentCount > 3*consistentCount) {
350  // If we're way inconsistent, let's res out and let them have us
352  }
353  } else {
354  // No inconsistencies. Do we have something to make, and eat?
355  if (makeCount > 0 && eatCount > 0) {
356  window.SetRelativeAtom(toMake, makeGuy);
358  }
359  }
360 
361  }
362 
363  };
364 
365  template <class CC>
366  Element_Bar<CC> Element_Bar<CC>::THE_INSTANCE;
367 
368 }
369 
370 #endif /* ELEMENT_BAR_H */
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
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 const T & GetDefaultAtom() const
Definition: Element_Bar.h:185
void SetCenterAtom(const T &atom)
Definition: EventWindow.h:220
bool BoundedBy(const Point< T > &lowerBound, const Point< T > &upperBound) const
Definition: Point.tcc:223
virtual u32 DefaultPhysicsColor() const
Definition: Element_Bar.h:200
bool OneIn(u32 odds)
Definition: Random.h:96
T GetY() const
Definition: Point.tcc:40
Random & GetRandom()
Definition: EventWindow.h:122
const T & GetRelativeAtom(const SPoint &offset) const
Definition: EventWindow.tcc:26
const T & GetCenterAtom() const
Definition: EventWindow.h:209
virtual const T & GetDefaultAtom() const
Definition: Element.h:382
Definition: MDist.h:69
static MDist< R > & get()
Definition: MDist.tcc:193
Definition: Element_Res.h:48
Definition: Element_Bar.h:45
Definition: ElementTable.h:43
virtual u32 LocalPhysicsColor(const T &atom, u32 selector) const
Definition: Element_Bar.h:210
virtual u32 PhysicsColor() const
Definition: Element.h:398
double GetEuclideanLength() const
Definition: Point.tcc:58
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
virtual u32 DefaultLowlightColor() const
Definition: Element_Bar.h:205
Definition: Atom.h:43
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_Bar.h:226
T GetX() const
Definition: Point.tcc:34