#include <string.h> // for memset
-#define ARRAYSIZE 1024 // size of the static array for BeginFind & co.
+
+#define ARRAYSIZE 1024 // static array for BeginFind & co.
#define ALLOCBOXES 16 // number of cellboxes to alloc at once
+#define MAXDEAD 8 // tics before removing cellbox from list
// ==========================================================================
#define HASH(x, y) (((x >> 3) & 0x7f) << 7) + ((y >> 3) & 0x7f)
-#define HASHSIZE 32768
-#define MAXDEAD 8
+#define HASHSIZE 32768 // hash table size (do not change!)
+#define CELLBOX 8 // cells in a cellbox (do not change!)
+
class CellBox
{
}
// --------------------------------------------------------------------------
-// FindMore & co.
+// Navigation
// --------------------------------------------------------------------------
-// Post eight cells to the cell arrays (changed cells only)
-void Life::DoLine(wxInt32 i, wxInt32 j, wxUint32 live, wxUint32 old)
+Cell Life::FindCenter()
{
- wxUint32 diff = (live ^ old) & 0x000000ff;
+ double i, j;
+ int n;
+ i = 0.0;
+ j = 0.0;
+ n = 0;
- if (!diff) return;
+ CellBox *c;
+ for (c = m_head; c; c = c->m_next)
+ if (!c->m_dead)
+ {
+ i += c->m_x;
+ j += c->m_y;
+ n++;
+ }
- for (wxInt32 k = 8; k; k--, i++)
+ if (n > 0)
{
- if (diff & 0x01)
+ i = (i / n) + CELLBOX / 2;
+ j = (j / n) + CELLBOX / 2;
+ }
+
+ Cell cell;
+ cell.i = (wxInt32) i;
+ cell.j = (wxInt32) j;
+ return cell;
+}
+
+Cell Life::FindNorth()
+{
+ wxInt32 i = 0, j = 0;
+ bool first = TRUE;
+
+ CellBox *c;
+ for (c = m_head; c; c = c->m_next)
+ if (!c->m_dead && ((first) || (c->m_y < j)))
{
- m_cells[m_ncells].i = i;
- m_cells[m_ncells].j = j;
- m_ncells++;
+ i = c->m_x;
+ j = c->m_y;
+ first = FALSE;
}
- diff >>= 1;
- live >>= 1;
- }
+
+ Cell cell;
+ cell.i = first? 0 : i + CELLBOX / 2;
+ cell.j = first? 0 : j + CELLBOX / 2;
+ return cell;
}
-// Post eight cells to the cell arrays (alive cells only)
-void Life::DoLine(wxInt32 i, wxInt32 j, wxUint32 live)
+Cell Life::FindSouth()
{
- if (! (live & 0x000000ff)) return;
+ wxInt32 i = 0, j = 0;
+ bool first = TRUE;
+
+ CellBox *c;
+ for (c = m_head; c; c = c->m_next)
+ if (!c->m_dead && ((first) || (c->m_y > j)))
+ {
+ i = c->m_x;
+ j = c->m_y;
+ first = FALSE;
+ }
+
+ Cell cell;
+ cell.i = first? 0 : i + CELLBOX / 2;
+ cell.j = first? 0 : j + CELLBOX / 2;
+ return cell;
+}
+
+Cell Life::FindWest()
+{
+ wxInt32 i = 0, j = 0;
+ bool first = TRUE;
+
+ CellBox *c;
+ for (c = m_head; c; c = c->m_next)
+ if (!c->m_dead && ((first) || (c->m_x < i)))
+ {
+ i = c->m_x;
+ j = c->m_y;
+ first = FALSE;
+ }
+
+ Cell cell;
+ cell.i = first? 0 : i + CELLBOX / 2;
+ cell.j = first? 0 : j + CELLBOX / 2;
+ return cell;
+}
+
+Cell Life::FindEast()
+{
+ wxInt32 i = 0, j = 0;
+ bool first = TRUE;
+
+ CellBox *c;
+ for (c = m_head; c; c = c->m_next)
+ if (!c->m_dead && ((first) || (c->m_x > i)))
+ {
+ i = c->m_x;
+ j = c->m_y;
+ first = FALSE;
+ }
+
+ Cell cell;
+ cell.i = first? 0 : i + CELLBOX / 2;
+ cell.j = first? 0 : j + CELLBOX / 2;
+ return cell;
+}
+
+// --------------------------------------------------------------------------
+// FindMore & co.
+// --------------------------------------------------------------------------
+
+// DoLine:
+// Post eight cells to the cell arrays - leave out the fourth
+// argument (or pass 0, the default value) to post alive cells
+// only, else it will post cells which have changed.
+//
+void Life::DoLine(wxInt32 i, wxInt32 j, wxUint32 live, wxUint32 old)
+{
+ wxUint32 diff = (live ^ old) & 0xff;
+
+ if (!diff) return;
for (wxInt32 k = 8; k; k--, i++)
{
- if (live & 0x01)
+ if (diff & 0x01)
{
m_cells[m_ncells].i = i;
m_cells[m_ncells].j = j;
m_ncells++;
}
- live >>= 1;
+ diff >>= 1;
}
}