22 template <
class CC>
class Element_DBar ;
56 typedef typename CC::ATOM_TYPE T;
57 typedef typename CC::PARAM_CONFIG P;
58 enum { R = P::EVENT_WINDOW_RADIUS };
61 static u32 toSignMag(s32 value) {
62 const u32 SIGN_BIT = 1<<(TVBITS-1);
63 const u32 MAX = SIGN_BIT-1;
71 u32 val = (u32) value;
76 static u32 toMag(u32 value) {
77 const u32 MAX = (1<<TVBITS)-1;
79 FAIL(ILLEGAL_ARGUMENT);
88 static s32 fromSignMag(
const u32 value) {
89 const u32 SIGN_BIT = 1<<(TVBITS-1);
90 const u32 MASK = SIGN_BIT-1;
91 FXP16 val = value&MASK;
98 static u32 fromMag(
const u32 value) {
99 const u32 MASK = (1<<TVBITS)-1;
100 u32 val = value&MASK;
104 template <u32 TXBITS, u32 TYBITS>
105 static u32 toUTiny(
const UPoint & v) {
106 u32 x = toMag<TXBITS>(v.
GetX());
107 u32 y = toMag<TYBITS>(v.
GetY());
108 return (x<<TYBITS)|y;
111 template <u32 TXBITS, u32 TYBITS>
112 static UPoint toUPoint(
const u32 bits) {
114 u32 x = fromMag<TXBITS>(bits>>TYBITS);
115 u32 y = fromMag<TYBITS>(bits);
122 static const u32 TYPE() {
126 static bool IsOurType(u32 type) {
130 static const u32 BITS_WIDE = 5;
131 static const u32 BITS_HIGH = 7;
132 static const u32 BITS_SYMI = 2;
133 static const u32 BITS_TIMER = 3;
135 static const u32 MAX_TIMER_VALUE = (1<<BITS_TIMER)-1;
137 static const u32 BITS_BAR_COORD_LEN = BITS_WIDE + BITS_HIGH;
139 static const u32 STATE_SIZE_IDX = 0;
140 static const u32 STATE_SIZE_LEN = BITS_BAR_COORD_LEN;
141 static const u32 STATE_POS_IDX = STATE_SIZE_IDX + STATE_SIZE_LEN;
142 static const u32 STATE_POS_LEN = BITS_BAR_COORD_LEN;
143 static const u32 STATE_SYMI_IDX = STATE_POS_IDX + STATE_POS_LEN;
144 static const u32 STATE_SYMI_LEN = BITS_SYMI;
145 static const u32 STATE_TIMER_IDX = STATE_SYMI_IDX + STATE_SYMI_LEN;
146 static const u32 STATE_TIMER_LEN = BITS_TIMER;
147 static const u32 STATE_BITS = STATE_TIMER_IDX + STATE_TIMER_LEN;
151 u32 GetSymI(
const T &atom)
const {
152 if (!IsOurType(atom.GetType()))
154 return atom.GetStateField(STATE_SYMI_IDX,STATE_SYMI_LEN);
157 SPoint GetMax(
const T &atom)
const {
158 if (!IsOurType(atom.GetType()))
160 return MakeSigned(toUPoint<BITS_WIDE,BITS_HIGH>(atom.GetStateField(STATE_SIZE_IDX,STATE_SIZE_LEN)));
163 SPoint GetPos(
const T &atom)
const {
164 if (!IsOurType(atom.GetType()))
166 return MakeSigned(toUPoint<BITS_WIDE,BITS_HIGH>(atom.GetStateField(STATE_POS_IDX,STATE_POS_LEN)));
169 u32 GetTimer(
const T &atom)
const {
170 if (!IsOurType(atom.GetType()))
172 return atom.GetStateField(STATE_TIMER_IDX,STATE_TIMER_LEN);
175 bool FitsInRep(
const SPoint & v)
const {
179 void SetSize(T &atom,
const SPoint & v)
const {
180 if (!IsOurType(atom.GetType()))
183 FAIL(ILLEGAL_ARGUMENT);
184 atom.SetStateField(STATE_SIZE_IDX,STATE_SIZE_LEN,toUTiny<BITS_WIDE,BITS_HIGH>(MakeUnsigned(v)));
187 void SetPos(T &atom,
const SPoint v)
const {
188 if (!IsOurType(atom.GetType()))
191 FAIL(ILLEGAL_ARGUMENT);
192 atom.SetStateField(STATE_POS_IDX,STATE_POS_LEN,toUTiny<BITS_WIDE,BITS_HIGH>(MakeUnsigned(v)));
195 void SetSymI(T &atom,
const u32 sym)
const {
196 if (!IsOurType(atom.GetType()))
198 if (sym >= PSYM_SYMMETRY_COUNT)
199 FAIL(ILLEGAL_ARGUMENT);
200 atom.SetStateField(STATE_SYMI_IDX,STATE_SYMI_LEN, sym);
203 void SetTimer(T &atom,
const u32 tmr)
const {
204 if (!IsOurType(atom.GetType()))
206 if (tmr > MAX_TIMER_VALUE)
207 FAIL(ILLEGAL_ARGUMENT);
208 atom.SetStateField(STATE_TIMER_IDX,STATE_TIMER_LEN, tmr);
213 static T defaultAtom(TYPE(), 0, 0, STATE_BITS);
214 const SPoint QBAR_SIZE(27, 3 * 27);
215 SetSize(defaultAtom, QBAR_SIZE);
216 SetPos(defaultAtom, QBAR_SIZE / 4);
217 SetSymI(defaultAtom, 0);
221 T GetAtom(
const SPoint & size,
const SPoint & pos)
const
243 SPoint barMax = GetMax(atom);
244 SPoint myPos = GetPos(atom);
245 return ColorMap_SEQ6_PuRd::THE_INSTANCE.
252 u32 timer = GetTimer(atom);
253 return ColorMap_SEQ6_GnBu::THE_INSTANCE.
271 const u32 selfType =
self.GetType();
272 if (!IsOurType(selfType)) FAIL(ILLEGAL_STATE);
275 u32 symi = GetSymI(
self);
280 SPoint barMax = GetMax(
self);
281 SPoint myPos = GetPos(
self);
286 u32 inconsistentCount = 0;
289 u32 consistentCount = 0;
298 bool neighborTimer =
false;
304 const SPoint sp = md.GetPoint(idx);
307 bool onGrid = (sp.
GetX()&1)==0 && (sp.
GetY()&1)==0;
310 const SPoint theirBarPos = sp+myPos;
320 const u32 otherType = other.GetType();
326 if (random.
OneIn(++makeCount)) {
329 SetPos(makeGuy,theirBarPos);
336 if (IsOurType(otherType)) {
340 SPoint otherBarMax = GetMax(other);
341 SPoint otherPos = GetPos(other);
343 SPoint otherPosMapped = otherPos-sp;
344 if (otherBarMax==barMax && otherPosMapped == myPos) {
348 u32 otherTimer = GetTimer(other);
349 if (!neighborTimer || otherTimer < minTimer)
350 minTimer = otherTimer;
351 if (!neighborTimer || otherTimer > maxTimer)
352 maxTimer = otherTimer;
353 neighborTimer =
true;
355 }
else if (random.
OneIn(++inconsistentCount)) {
371 const u32 otherType = other.GetType();
376 if (random.
OneIn(++eatCount)) {
384 if (isEmpty) ++consistentCount;
386 bool iQBar = IsOurType(otherType);
388 if (random.
OneIn(++inconsistentCount)) {
402 if (inconsistentCount > 0) {
404 if (consistentCount > 3*inconsistentCount) {
407 }
else if (inconsistentCount > 3*consistentCount) {
413 u32 ourTimer = GetTimer(
self);
415 if (neighborTimer && minTimer < ourTimer)
419 SetTimer(
self,ourTimer);
425 if (makeCount > 0 && eatCount > 0) {
431 if (myPos == barMax-
SPoint(1,1)) {
435 const u32 offType = offEnd.GetType();
438 u32 symi = GetSymI(
self);
440 if (symi > PSYM_DEG270L)
442 SetSymI(corner,symi);
443 SetPos(corner,
SPoint(0,0));
450 u32 ourTimer = GetTimer(
self);
451 if (ourTimer < MAX_TIMER_VALUE && (ourTimer==0 || (neighborTimer && minTimer+1 >= ourTimer))) {
452 if (random.
OneIn(ourTimer+1)) {
454 SetTimer(
self,ourTimer);
467 Element_QBar<CC> Element_QBar<CC>::THE_INSTANCE;
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
Definition: Element_QBar.h:53
u32 GetType() const
Definition: Element.h:290
Definition: Element_Empty.h:41
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
void SetSymmetry(const PointSymmetry psym)
Definition: EventWindow.h:110
void SetCenterAtom(const T &atom)
Definition: EventWindow.h:220
u32 NoDiffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: Element.h:508
bool BoundedBy(const Point< T > &lowerBound, const Point< T > &upperBound) const
Definition: Point.tcc:223
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
bool IsType(u32 type) const
Definition: Element.h:345
static MDist< R > & get()
Definition: MDist.tcc:193
virtual u32 LocalPhysicsColor(const T &atom, u32 selector) const
Definition: Element_QBar.h:239
Definition: Element_Res.h:48
virtual const T & GetDefaultAtom() const
Definition: Element_QBar.h:211
Definition: ElementTable.h:43
double GetEuclideanLength() const
Definition: Point.tcc:58
void Message(const char *format,...)
Definition: Logger.h:287
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_QBar.h:267
virtual u32 DefaultPhysicsColor() const
Definition: Element_QBar.h:228
virtual u32 PercentMovable(const T &you, const T &me, const SPoint &offset) const
Definition: Element_QBar.h:233
virtual u32 Diffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: Element_QBar.h:263
T GetX() const
Definition: Point.tcc:34