MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Element_AntiForkBomb.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  Element_AntiForkBomb.h Inflammation-based forkbomb suppression
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
27 #ifndef ELEMENT_ANTIFORKBOMB_H
28 #define ELEMENT_ANTIFORKBOMB_H
29 
30 #include "Element.h"
31 #include "P3Atom.h"
32 #include "EventWindow.h"
33 #include "ElementTable.h"
35 #include "itype.h"
36 
37 namespace MFM
38 {
39 
40 #define ANTIFORKBOMB_VERSION 1
41 
42  template <class CC>
43  class Element_AntiForkBomb : public Element<CC>
44  {
45  // Extract short names for parameter types
46  typedef typename CC::ATOM_TYPE T;
47  typedef typename CC::PARAM_CONFIG P;
48  enum {
49  R = P::EVENT_WINDOW_RADIUS,
50  BITS = P::BITS_PER_ATOM,
51 
53  // Element state fields
54 
55  INFLAMMATION_POS = T::ATOM_FIRST_STATE_BIT,
56  INFLAMMATION_LEN = 2
57 
58  };
59 
60  private:
65  u32 m_minDensity;
66 
71  u32 m_maxDensity;
72 
73  public:
74 
75  typedef BitField<BitVector<BITS>,VD::U32,INFLAMMATION_LEN,INFLAMMATION_POS> AFInflammationLevel;
76 
77  static Element_AntiForkBomb THE_INSTANCE;
78 
79  Element_AntiForkBomb() : Element<CC>(MFM_UUID_FOR("AntiFork", ANTIFORKBOMB_VERSION))
80  {
81  m_minDensity = 1;
82  m_maxDensity = 3;
84  Element<CC>::SetName("Anti-Fork Bomb");
85  }
86 
87  virtual u32 LocalPhysicsColor(const T& atom, u32 selector) const
88  {
89  u32 level = AFInflammationLevel::Read(atom); // 0..3
90  if (level == 0)
91  {
92  return 0xff333333; // Grey20
93  }
94 
95  const u32 LEVEL_INCREMENT = 50;
96  return ((level*LEVEL_INCREMENT + (255-3*LEVEL_INCREMENT))<<8) | 0xff000000;
97  }
98 
99  virtual void Behavior(EventWindow<CC>& window) const
100  {
101  Random & random = window.GetRandom();
102  const u32 ourType = THE_INSTANCE.GetType();
103  const MDist<R> & md = MDist<R>::get();
104 
105  T self = window.GetCenterAtom();
106  u32 myInflammationLevel = AFInflammationLevel::Read(self);
107 
108  const u32 loIdx = md.GetFirstIndex(1);
109  const u32 hiIdx = md.GetLastIndex(R);
110 
111  u32 usCount = 0;
112  u32 maxInflammation = 0;
113  u32 emptyCount = 0;
114  SPoint randomEmpty;
115  SPoint randomSelf;
116 
117  for (u32 i = loIdx; i <= hiIdx; ++i)
118  {
119  const SPoint rel = md.GetPoint(i);
120  if (!window.IsLiveSite(rel))
121  {
122  continue;
123  }
124  const T & atom = window.GetRelativeAtom(rel);
125  const u32 type = atom.GetType();
126  const Element<CC> * elt = window.GetTile().GetElement(type);
128  {
129  if (random.OneIn(++emptyCount))
130  {
131  randomEmpty = rel;
132  }
133  } else if (type == ourType)
134  {
135  u32 level = AFInflammationLevel::Read(atom);
136  if (level > maxInflammation)
137  {
138  maxInflammation = level;
139  }
140  if (random.OneIn(++usCount))
141  {
142  randomSelf = rel;
143  }
144  } else if (dynamic_cast<const AbstractElement_ForkBomb<CC>*>(elt))
145  {
146  // We see a pathogen! Danger danger! Red alert!
147  maxInflammation = 4;
148  break;
149  }
150  }
151 
152  if (maxInflammation >= 3)
153  {
154  u32 inflammationLevel = maxInflammation - 1;
155 
156  T inflamedUs = window.GetCenterAtom();
157  AFInflammationLevel::Write(inflamedUs, inflammationLevel);
158  window.SetCenterAtom(inflamedUs);
159 
160  //DEFEND AT ALL COSTS!
161  for (u32 i = loIdx; i <= hiIdx; ++i)
162  {
163  const SPoint rel = md.GetPoint(i);
164  const T & atom = window.GetRelativeAtom(rel);
165  const u32 type = atom.GetType();
166  if (type != ourType || AFInflammationLevel::Read(atom) < inflammationLevel)
167  {
168  window.SetRelativeAtom(rel, inflamedUs);
169  }
170  }
171  }
172  else if (myInflammationLevel > 0)
173  {
174  AFInflammationLevel::Write(self, myInflammationLevel - 1);
175  window.SetCenterAtom(self);
176  }
177  else if (usCount < m_minDensity)
178  {
179  //It's calm around here, but need more of us on patrol
180  if (emptyCount > 0)
181  {
182  window.SetRelativeAtom(randomEmpty, THE_INSTANCE.GetDefaultAtom());
183  }
184  } else if (usCount > m_maxDensity)
185  {
186  //It's calm and there's too many of us. I sacrifice myself for the team.
188  } else
189  {
190  //It's calm and we have reasonable density. I will patrol.
191  this->Diffuse(window);
192  }
193  }
194 
195  virtual u32 PercentMovable(const T& you,
196  const T& me, const SPoint& offset) const
197  {
198  return 100;
199  }
200 
201  virtual u32 DefaultPhysicsColor() const
202  {
203  T temp;
204  return LocalPhysicsColor(temp, 0);
205  }
206 
207  };
208 
209  template <class CC>
210  Element_AntiForkBomb<CC> Element_AntiForkBomb<CC>::THE_INSTANCE;
211 
212 }
213 
214 #endif /* ELEMENT_ANTIFORKBOMB_H */
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
static void Write(BV &bv, u32 val)
Definition: BitField.h:84
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_AntiForkBomb.h:195
u32 GetType() const
Definition: Element.h:290
Definition: Element_Empty.h:41
static u32 Read(const BV &bv)
Definition: BitField.h:73
Definition: AbstractElement_ForkBomb.h:41
Definition: Element_AntiForkBomb.h:43
Definition: Random.h:45
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_AntiForkBomb.h:99
virtual u32 DefaultPhysicsColor() const
Definition: Element_AntiForkBomb.h:201
void SetCenterAtom(const T &atom)
Definition: EventWindow.h:220
Tile< CC > & GetTile()
Definition: EventWindow.h:132
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: Atom.h:45
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: ElementTable.h:43
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
virtual u32 LocalPhysicsColor(const T &atom, u32 selector) const
Definition: Element_AntiForkBomb.h:87
Definition: Atom.h:43