xref: /haiku/src/add-ons/screen_savers/glife/GLifeGrid.cpp (revision 579f1dbca962a2a03df54f69fdc6e9423f91f20e)
1 /*
2  * Copyright 2012, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  * 		Aaron Hill <serac@hillvisions.com>
7  */
8 
9 
10 #include "GLifeGrid.h"
11 
12 #include <math.h>
13 #include <stdlib.h>
14 #include <SupportDefs.h>
15 
16 
17 // ------------------------------------------------------
18 //  GLifeGrid Class Neighbors Definition
19 inline int32
20 GLifeGrid::Neighbors(int32 iRow, int32 iColumn)
21 {
22 	return (Occupied(iRow - 1, iColumn - 1) ? 1 : 0)
23 		   + (Occupied(iRow - 1, iColumn) ? 1 : 0)
24 		   + (Occupied(iRow - 1, iColumn + 1) ? 1 : 0)
25 		   + (Occupied(iRow, iColumn - 1) ? 1 : 0)
26 		   + (Occupied(iRow, iColumn + 1) ? 1 : 0)
27 		   + (Occupied(iRow + 1, iColumn - 1) ? 1 : 0)
28 		   + (Occupied(iRow + 1, iColumn) ? 1 : 0)
29 		   + (Occupied(iRow + 1, iColumn + 1) ? 1 : 0);
30 }
31 
32 
33 // ------------------------------------------------------
34 //  GLifeGrid Class Constructor Definition
35 GLifeGrid::GLifeGrid(int32 iWidth, int32 iHeight)
36 	:
37 	m_iWidth(iWidth),
38 	m_iHeight(iHeight)
39 {
40 	m_pbGrid = new bool[iWidth * iHeight];
41 
42 	// Randomize new grid
43 	for(int32 iRow = 0; iRow < iHeight; ++iRow) {
44 		for(int32 iColumn = 0; iColumn < iWidth; ++iColumn) {
45 			// TODO: Allow for customized randomization level
46 			m_pbGrid[ (iRow * iWidth) + iColumn] = ((rand() % 6 ) == 0);
47 		}
48 	}
49 }
50 
51 
52 // ------------------------------------------------------
53 //  GLifeGrid Class Destructor Definition
54 GLifeGrid::~GLifeGrid(void)
55 {
56 	delete m_pbGrid;
57 }
58 
59 
60 // ------------------------------------------------------
61 //  GLifeGrid Class Generation Definition
62 void
63 GLifeGrid::Generation(void)
64 {
65 	bool* pbTemp = new bool[m_iWidth * m_iHeight];
66 
67 	for(int32 iRow = 0; iRow < m_iHeight; ++iRow) {
68 		for(int32 iColumn = 0; iColumn < m_iWidth; ++iColumn) {
69 
70 			int32 iNum = Neighbors(iRow, iColumn);
71 			pbTemp[(iRow * m_iWidth) + iColumn]
72 				= ((iNum == 3) || (Occupied(iRow, iColumn)
73 				&& iNum >= 2 && iNum <= 3));
74 		}
75 	}
76 
77 	// Swap grids
78 	delete m_pbGrid;
79 	m_pbGrid = pbTemp;
80 }
81 
82 
83 // ------------------------------------------------------
84 //  GLifeGrid Class Occupied Definition
85 bool
86 GLifeGrid::Occupied(int32 iRow, int32 iColumn)
87 {
88 	int32 iNewRow = (iRow % m_iHeight), iNewColumn = (iColumn % m_iWidth);
89 	while(iNewRow < 0)
90 		iNewRow += m_iHeight;
91 	while(iNewColumn < 0)
92 		iNewColumn += m_iWidth;
93 	return m_pbGrid[(iNewRow * m_iWidth) + iNewColumn];
94 }
95