X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8caa4ed10ec5a89c61dff9d19c3c28ea729b4272..9eee81a4cf3aa063d4089074073c8a76fb56653b:/demos/life/game.h diff --git a/demos/life/game.h b/demos/life/game.h index dea8c45572..1366c18fec 100644 --- a/demos/life/game.h +++ b/demos/life/game.h @@ -29,101 +29,140 @@ #endif // -------------------------------------------------------------------------- -// constants +// LifePattern // -------------------------------------------------------------------------- -// minimum and maximum table size, in each dimension -#define LIFE_MIN 20 -#define LIFE_MAX 200 - -// -------------------------------------------------------------------------- -// Cell and CellArray; -// -------------------------------------------------------------------------- - -typedef long Cell; -typedef wxArrayLong CellArray; - -// -------------------------------------------------------------------------- -// LifeShape -// -------------------------------------------------------------------------- - -class LifeShape +// A class which holds a pattern +class LifePattern { public: - LifeShape::LifeShape(wxString name, - wxString desc, - int width, int height, char *data, - int fieldWidth = 20, int fieldHeight = 20, - bool wrap = TRUE) + // This ctor is used by the LifeReader class + LifePattern(wxString name, + wxString description, + wxString rules, + wxArrayString shape) + { + m_name = name; + m_description = description; + m_rules = rules; + m_shape = shape; + }; + + // A more convenient ctor for the built-in samples + LifePattern(wxString name, + wxString description, + int width, + int height, + const char *shape) { m_name = name; - m_desc = desc; - m_width = width; - m_height = height; - m_data = data; - m_fieldWidth = fieldWidth; - m_fieldHeight = fieldHeight; - m_wrap = wrap; - } - - wxString m_name; - wxString m_desc; - int m_width; - int m_height; - char *m_data; - int m_fieldWidth; - int m_fieldHeight; - bool m_wrap; + m_description = description; + m_rules = _(""); + m_shape.Add( wxString::Format("%i %i", -width/2, -height/2) ); + for(int j = 0; j < height; j++) + m_shape.Add( wxString(shape + (j * width), (size_t) width) ); + }; + + wxString m_name; + wxString m_description; + wxString m_rules; + wxArrayString m_shape; }; + // -------------------------------------------------------------------------- // Life // -------------------------------------------------------------------------- +// A struct used to pass cell coordinates around +struct LifeCell +{ + wxInt32 i; + wxInt32 j; +}; + +// A private class that contains data about a block of cells +class LifeCellBox; + +// A class that models a Life game instance class Life { public: // ctor and dtor - Life(int width, int height); + Life(); ~Life(); - void Create(int width, int height); - void Destroy(); - - // game field - inline int GetWidth() const { return m_width; }; - inline int GetHeight() const { return m_height; }; - inline void SetBorderWrap(bool on) { m_wrap = on; }; - - // cells - bool IsAlive(int i, int j) const; - bool IsAlive(Cell c) const; - int GetX(Cell c) const; - int GetY(Cell c) const; - const CellArray* GetCells() const { return &m_cells; }; - const CellArray* GetChangedCells() const { return &m_changed; }; - - // game logic + + // accessors + inline wxUint32 GetNumCells() const { return m_numcells; }; + inline wxString GetRules() const { return m_rules; }; + inline wxString GetDescription() const { return m_description; }; + bool IsAlive(wxInt32 x, wxInt32 y); + void SetCell(wxInt32 x, wxInt32 y, bool alive = TRUE); + void SetPattern(const LifePattern &pattern); + + // game control void Clear(); - Cell SetCell(int i, int j, bool alive = TRUE); - void SetShape(LifeShape &shape); bool NextTic(); -private: - int GetNeighbors(int i, int j) const; - inline Cell MakeCell(int i, int j, bool alive) const; - - enum CellFlags - { - CELL_DEAD = 0x0000, // is dead - CELL_ALIVE = 0x0001, // is alive - CELL_MARK = 0x0002, // will change / has changed - }; + // navigation + LifeCell FindNorth(); + LifeCell FindSouth(); + LifeCell FindWest(); + LifeCell FindEast(); + LifeCell FindCenter(); + + // The following functions find cells within a given viewport; either + // all alive cells, or only those cells which have changed since last + // generation. You first call BeginFind() to specify the viewport, + // then keep calling FindMore() until it returns TRUE. + // + // BeginFind: + // Specify the viewport and whether to look for alive cells or for + // cells which have changed since the last generation and thus need + // to be repainted. In this latter case, there is no distinction + // between newborn or just-dead cells. + // + // FindMore: + // Fills an array with cells that match the specification given with + // BeginFind(). The array itself belongs to the Life object and must + // not be modified or freed by the caller. If this function returns + // FALSE, then the operation is not complete: just process all cells + // and call FillMore() again. + // + void BeginFind(wxInt32 x0, wxInt32 y0, + wxInt32 x1, wxInt32 y1, + bool changed); + bool FindMore(LifeCell *cells[], size_t *ncells); - int m_width; - int m_height; - CellArray m_cells; - CellArray m_changed; - bool m_wrap; +private: + // cellbox-related + LifeCellBox *CreateBox(wxInt32 x, wxInt32 y, wxUint32 hv); + LifeCellBox *LinkBox(wxInt32 x, wxInt32 y, bool create = TRUE); + void KillBox(LifeCellBox *c); + + // helper for BeginFind & FindMore + void DoLine(wxInt32 x, wxInt32 y, wxUint32 alive, wxUint32 old = 0); + + + // pattern description + wxString m_name; // name (currently unused) + wxString m_rules; // rules (currently unused) + wxString m_description; // description + + // pattern data + LifeCellBox *m_head; // list of alive boxes + LifeCellBox *m_available; // list of reusable dead boxes + LifeCellBox **m_boxes; // hash table of alive boxes + wxUint32 m_numcells; // population (number of alive cells) + + // state vars for BeginFind & FindMore + LifeCell *m_cells; // array of cells + size_t m_ncells; // number of valid entries in m_cells + wxInt32 m_x, m_y, // counters and search mode + m_x0, m_y0, + m_x1, m_y1; + bool m_changed; + bool m_findmore; }; #endif // _LIFE_GAME_H_