Fixed crash in Life demo on Mac
[wxWidgets.git] / demos / life / game.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: game.h
3 // Purpose: Life! game logic
4 // Author: Guillermo Rodriguez Garcia, <guille@iies.es>
5 // Modified by:
6 // Created: Jan/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000, Guillermo Rodriguez Garcia
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _LIFE_GAME_H_
13 #define _LIFE_GAME_H_
14
15 // for compilers that support precompilation, includes "wx/wx.h"
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 // for all others, include the necessary headers
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 // --------------------------------------------------------------------------
28 // LifePattern
29 // --------------------------------------------------------------------------
30
31 // A class which holds a pattern
32 class LifePattern
33 {
34 public:
35 // This ctor is used by the LifeReader class
36 LifePattern(wxString name,
37 wxString description,
38 wxString rules,
39 wxArrayString shape)
40 {
41 m_name = name;
42 m_description = description;
43 m_rules = rules;
44 m_shape = shape;
45 };
46
47 // A more convenient ctor for the built-in samples
48 LifePattern(wxString name,
49 wxString description,
50 int width,
51 int height,
52 const char *shape)
53 {
54 m_name = name;
55 m_description = description;
56 m_rules = wxEmptyString;
57 // TODO: add the positions later, since the formatting command
58 // causes a crash due to conversion objects not being available
59 // during initialisation.
60 #ifndef __WXMAC__
61 m_shape.Add( wxString::Format(_T("%i %i"), -width/2, -height/2) );
62 #endif
63 for(int j = 0; j < height; j++)
64 {
65 wxString tmp;
66
67 for(int i = 0; i < width; i++)
68 {
69 tmp += wxChar(shape[j * width + i]);
70 }
71
72 m_shape.Add( tmp );
73 }
74 };
75
76 wxString m_name;
77 wxString m_description;
78 wxString m_rules;
79 wxArrayString m_shape;
80 };
81
82
83 // --------------------------------------------------------------------------
84 // Life
85 // --------------------------------------------------------------------------
86
87 // A struct used to pass cell coordinates around
88 struct LifeCell
89 {
90 wxInt32 i;
91 wxInt32 j;
92 };
93
94 // A private class that contains data about a block of cells
95 class LifeCellBox;
96
97 // A class that models a Life game instance
98 class Life
99 {
100 public:
101 // ctor and dtor
102 Life();
103 ~Life();
104
105 // accessors
106 inline wxUint32 GetNumCells() const { return m_numcells; };
107 inline wxString GetRules() const { return m_rules; };
108 inline wxString GetDescription() const { return m_description; };
109 bool IsAlive(wxInt32 x, wxInt32 y);
110 void SetCell(wxInt32 x, wxInt32 y, bool alive = true);
111 void SetPattern(const LifePattern &pattern);
112
113 // game control
114 void Clear();
115 bool NextTic();
116
117 // navigation
118 LifeCell FindNorth();
119 LifeCell FindSouth();
120 LifeCell FindWest();
121 LifeCell FindEast();
122 LifeCell FindCenter();
123
124 // The following functions find cells within a given viewport; either
125 // all alive cells, or only those cells which have changed since last
126 // generation. You first call BeginFind() to specify the viewport,
127 // then keep calling FindMore() until it returns true.
128 //
129 // BeginFind:
130 // Specify the viewport and whether to look for alive cells or for
131 // cells which have changed since the last generation and thus need
132 // to be repainted. In this latter case, there is no distinction
133 // between newborn or just-dead cells.
134 //
135 // FindMore:
136 // Fills an array with cells that match the specification given with
137 // BeginFind(). The array itself belongs to the Life object and must
138 // not be modified or freed by the caller. If this function returns
139 // false, then the operation is not complete: just process all cells
140 // and call FillMore() again.
141 //
142 void BeginFind(wxInt32 x0, wxInt32 y0,
143 wxInt32 x1, wxInt32 y1,
144 bool changed);
145 bool FindMore(LifeCell *cells[], size_t *ncells);
146
147 private:
148 // cellbox-related
149 LifeCellBox *CreateBox(wxInt32 x, wxInt32 y, wxUint32 hv);
150 LifeCellBox *LinkBox(wxInt32 x, wxInt32 y, bool create = true);
151 void KillBox(LifeCellBox *c);
152
153 // helper for BeginFind & FindMore
154 void DoLine(wxInt32 x, wxInt32 y, wxUint32 alive, wxUint32 old = 0);
155
156
157 // pattern description
158 wxString m_name; // name (currently unused)
159 wxString m_rules; // rules (currently unused)
160 wxString m_description; // description
161
162 // pattern data
163 LifeCellBox *m_head; // list of alive boxes
164 LifeCellBox *m_available; // list of reusable dead boxes
165 LifeCellBox **m_boxes; // hash table of alive boxes
166 wxUint32 m_numcells; // population (number of alive cells)
167
168 // state vars for BeginFind & FindMore
169 LifeCell *m_cells; // array of cells
170 size_t m_ncells; // number of valid entries in m_cells
171 wxInt32 m_x, m_y, // counters and search mode
172 m_x0, m_y0,
173 m_x1, m_y1;
174 bool m_changed;
175 bool m_findmore;
176 };
177
178 #endif // _LIFE_GAME_H_