2d Cellular Automata Implementation

After drawing some glyphs with glBitMap I wanted to see something animated so I thought now would be a good time to learn bitwise operations and do something with cellular automata.

The basic breakdown is:

-Data region is a square with an integer number of bytes in size. (size of 2 bytes would be a 16x16 bit bitmap).

-Update looks at 4 orthogonal nearest neighbor bits (2^4 possible arrangements) and updates according to rule (2^16 rules being a permutation of the 2^4 possible neighbor arrangements)

-Caveat: nearest neighbor checks wrap on borders, eg the left neighbor of a bit on the left edge would be the bit on the right edge.

-Constructor starts map with all bytes to 0x00 except the first byte which is set to 0x01.

-Keyboard input is handled so that rule can be changed while program is running, and doing so resets all bytes to 0x00 except the 1st byte which is set to 0x01

Possible problem: I'm only seeing simple repeating scanlines, or solid or blank fields. There should be 2^16 or about 65k rules so maybe those with interesting behavior are too sparse, but i have flipped through hundreds and not seen more variation than 3 or 4 simple behaviors.

Well here's the module if anything jumps out as being an obvious problem.

Not shown are the drawing and update loops which is simply updateMap(); followed by drawMap(); every frame.

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef CELL_H
#define CELL_H

#include <cmath>

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

#include "system.h"

class Cell
{
	Uint32 mapsize;
	Uint32 w;
	Uint32 h;
	Uint32 bytesper_row;
	
	System* systemPointer;
public:
	Uint16 rule;
	Uint32 bits_total;
	Uint32 bytes_total;

	GLubyte* map;

	Cell(Uint32 rule_in, Uint32 mapsize_in, System& theSystem);

	bool getRuleBit(Uint16 i);
	bool getValue(Uint32 i);
	void setValue(GLubyte* the_map, Uint32 i, bool to);
	bool updateBit(Uint32 i);
	void updateMap();
	void drawMap(int pos_x, int pos_y);
};

#endif


#include "cell.h"

Cell::Cell(Uint32 rule_in, Uint32 mapsize_in, System& theSystem)
{
	systemPointer = &theSystem;
	rule = rule_in;
	w = mapsize_in * 8;
	h = w;
	bits_total = w*h;
	bytesper_row = mapsize_in;
	bytes_total = bytesper_row*h;
	map = new GLubyte[bytes_total];
	for (int i = 0; i < bytes_total; i++)	{
		map[i] = 0x00;
	}
	map[0] = 0x01;
}
bool Cell::getRuleBit(Uint16 i)
{
	GLubyte tester = pow(2.0f, int(i%16));
	return ((rule & tester) != 0);
}
bool Cell::getValue(Uint32 i)
{
	GLubyte tester = pow(2.0f, int(i%8));
	return ((map[int(i/w)] & tester) != 0);
}
void Cell::setValue(GLubyte* the_map, Uint32 i, bool to)
{
	GLubyte pos = pow(2.0f, int(i%8));
	GLubyte setter = 0x00;
	if (to == 1)	{
		setter = pos;
		the_map[int(i/8)] |= setter;
	}
	if (to == 0)	{
		setter = 0xff;
		setter -= pos;
		the_map[int(i/8)] &= setter;
	}
}
bool Cell::updateBit(Uint32 i)
{
	using namespace std;

	Uint32 neighb = 0x00;

	bool neighb0 = getValue(int(i-w) + bits_total*(int(i-w)<0));
	bool neighb1 = getValue(int(i/w)*w + (i+1)%w);
	bool neighb2 = getValue((i+w) - bits_total*((i+w)>=bits_total));
	bool neighb3 = getValue(int(i/w)*w + (i-1)%w);
	neighb |= neighb0*1;
	neighb |= neighb1*2;
	neighb |= neighb2*4;
	neighb |= neighb3*8;

	return getRuleBit(neighb);
}
void Cell::updateMap()
{
	GLubyte* temp_map = new GLubyte[bytes_total];
	for (Uint32 i = 0; i < bits_total; i++)	{
		setValue(temp_map, i, updateBit(i));
	}
	
	for (int i = 0; i < bytes_total; i++)	{
		map[i] = temp_map[i];
	}
	delete[] temp_map;
}
void Cell::drawMap(int pos_x, int pos_y)
{
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
		glLoadIdentity();

		glOrtho(0,systemPointer->SCREEN_WIDTH,-systemPointer->SCREEN_HEIGHT,0,-1,1);
		glMatrixMode(GL_MODELVIEW);

		glPushMatrix();
			glLoadIdentity();
			glDisable(GL_DEPTH_TEST);

			glColor3f(1.0, 0.0, 0.0);
			
			glRasterPos2i(pos_x, pos_y);

			glPixelStorei(GL_UNPACK_ALIGNMENT, bytesper_row);
			glBitmap(w, h, 0, 0, 0, 0, map);
	
			glEnable(GL_DEPTH_TEST);
		glPopMatrix();
	glPopMatrix();
}
I guess this is solved, I found the problem:
1
2
3
4
5
bool Cell::getValue(Uint32 i)
{
	GLubyte tester = pow(2.0f, int(i%8));
	return ((map[int(i/8)] & tester) != 0);
}
Topic archived. No new replies allowed.