X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8caa4ed10ec5a89c61dff9d19c3c28ea729b4272..c70d645d7f85d410fa8e25c3921f5f1c775c332c:/demos/life/game.h diff --git a/demos/life/game.h b/demos/life/game.h index dea8c45572..2b5b548f0e 100644 --- a/demos/life/game.h +++ b/demos/life/game.h @@ -12,118 +12,155 @@ #ifndef _LIFE_GAME_H_ #define _LIFE_GAME_H_ -#ifdef __GNUG__ - #pragma interface "game.h" -#endif - -// for compilers that support precompilation, includes "wx/wx.h" -#include "wx/wxprec.h" +// -------------------------------------------------------------------------- +// LifePattern +// -------------------------------------------------------------------------- -#ifdef __BORLANDC__ - #pragma hdrstop -#endif +// A class which holds a pattern +class LifePattern +{ +public: + // 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; + }; -// for all others, include the necessary headers -#ifndef WX_PRECOMP - #include "wx/wx.h" + // 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_description = description; + m_rules = wxEmptyString; + // TODO: add the positions later, since the formatting command + // causes a crash due to conversion objects not being available + // during initialisation. +#ifndef __WXMAC__ + m_shape.Add( wxString::Format(_T("%i %i"), -width/2, -height/2) ); #endif + for(int j = 0; j < height; j++) + { + wxString tmp; -// -------------------------------------------------------------------------- -// constants -// -------------------------------------------------------------------------- + for(int i = 0; i < width; i++) + { + tmp += wxChar(shape[j * width + i]); + } -// minimum and maximum table size, in each dimension -#define LIFE_MIN 20 -#define LIFE_MAX 200 + m_shape.Add( tmp ); + } + }; -// -------------------------------------------------------------------------- -// Cell and CellArray; -// -------------------------------------------------------------------------- + wxString m_name; + wxString m_description; + wxString m_rules; + wxArrayString m_shape; +}; -typedef long Cell; -typedef wxArrayLong CellArray; // -------------------------------------------------------------------------- -// LifeShape +// Life // -------------------------------------------------------------------------- -class LifeShape +// A struct used to pass cell coordinates around +struct LifeCell { -public: - LifeShape::LifeShape(wxString name, - wxString desc, - int width, int height, char *data, - int fieldWidth = 20, int fieldHeight = 20, - bool wrap = TRUE) - { - 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; + wxInt32 i; + wxInt32 j; }; -// -------------------------------------------------------------------------- -// Life -// -------------------------------------------------------------------------- +// 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_