Langton's ant
About the code
The rules
First program
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BLACK Color(0, 0, 0)
#define WHITE Color(255, 255, 255)
int main(int argc, char* argv[])
{
// init the window
gfx.init("Langton's ant", SCREEN_WIDTH, SCREEN_HEIGHT);
gfx.init2D();
gfx.clearScreen(BLACK);
Then for the ant, we will need its x and y position and its direction.
int x = SCREEN_WIDTH / 2;
int y = SCREEN_HEIGHT / 2;
int dir = 0; // direction 0=up, 1=right, 2=down, 3=left
Then in our main loop we check if the ant is inside the screen
// wait till the end
while (sys.isQuitRequested() == false)
{
// if we are on the screen
if (x >= 0 && x < SCREEN_WIDTH &&
y >= 0 && y < SCREEN_HEIGHT)
{
We get the color of the pixel where the ant is
// get current color
Color c = gfx.getPixel(x, y);
We check this value to turn the ant and change the color of the pixel.
// turn and change color
if (c.argb == BLACK.argb)
{
dir = (dir - 1 + 4) % 4; // turn left
gfx.setPixel(x, y, WHITE);
}
else
{
dir = (dir + 1) % 4; // turn right
gfx.setPixel(x, y, BLACK);
}
Notice that for the turnings we take the modulo with 4, because we want a value between 0 and 3.
// move forward
if (dir == 0)
{
y--; // up
}
else if (dir == 1)
{
x++; // right
}
else if (dir == 2)
{
y++; // down
}
else
{
x--; // left
}
}
And we end the main loop
sys.processEvents();
gfx.render();
sys.wait(2);
}
gfx.quit();
return EXIT_SUCCESS;
}
Download source code
Download executable for Windows
Let's see what happens when we run this program.
Adding more players
int x[10];
int y[10];
int dir[10];
Color col[10];
We initialize these values randomly.
srand(time(NULL));
for (int i = 0; i < 10; ++i)
{
x[i] = rand() % SCREEN_WIDTH;
y[i] = rand() % SCREEN_HEIGHT;
dir[i] = rand() % 4;
col[i] = Color(rand() & 0xff, rand() & 0xff, rand() & 0xff);
}
And process them in the main loop.
while (sys.isQuitRequested() == false)
{
for (int i = 0; i < 10; ++i)
lang(x[i], y[i], dir[i], col[i]);
sys.processEvents();
gfx.render();
sys.wait(2);
}
The lang() function contains the same code we saw before with only a small modification for the color.
void lang(int &x, int &y, int &dir, Color& col)
{
// if we are on the screen
if (x >= 0 && x < SCREEN_WIDTH &&
y >= 0 && y < SCREEN_HEIGHT)
{
// get current color
Color c = gfx.getPixel(x, y);
// turn and change color
if (c.argb == BLACK.argb)
{
dir = (dir - 1 + 4) % 4; // turn left
gfx.setPixel(x, y, col);
}
else
{
dir = (dir + 1) % 4; // turn right
gfx.setPixel(x, y, BLACK);
}
// move forward
if (dir == 0)
{
y--; // up
}
else if (dir == 1)
{
x++; // right
}
else if (dir == 2)
{
y++; // down
}
else
{
x--; // left
}
}
}
Download source code
Download executable for Windows
If you run this program several times you will see some interesting behaviors.
Adding colors
char rule[] = "RLR";
int nbColors = strlen(rule);
We will use a palette for these colors. It is initialized with random colors except the color 0 which is black.
Color* palette;
// init palette
srand(time(NULL));
palette = new Color[nbColors];
palette[0] = Color(0, 0, 0);
for (int i = 1; i < nbColors; i++)
{
palette[i] = Color(rand() % 256,
rand() % 256,
rand() % 256);
}
As it will not be easy to retrieve the color number from its RGB value as we did with black and white, we will
int world[SCREEN_WIDTH][SCREEN_HEIGHT];
// init world
for (int yy = 0; yy < SCREEN_HEIGHT; yy++)
for (int xx = 0; xx < SCREEN_WIDTH; xx++)
world[xx][yy] = 0;
Now, in the main loop, we first get the color where the ant is
// wait till the end
while (sys.isQuitRequested() == false)
{
// if we are on the screen
if (x >= 0 && x < SCREEN_WIDTH &&
y >= 0 && y < SCREEN_HEIGHT)
{
// get current color
int c = world[x][y];
We decide to turn left or right according to the letter in the rule that corresponds to this color:
// turn
if (rule[c] == 'R')
{
dir = (dir + 1) % 4; // turn right
}
else
{
dir = (dir - 1 + 4) % 4; // turn left
}
To change the color of the cell, in the 2 colors world we turned a black cell to white and vice versa.
// change color
c = (c + 1) % nbColors;
world[x][y] = c;
gfx.setPixel(x, y, palette[c]);
And we move forward...
// move forward
if (dir == 0)
{
y--; // up
}
else if (dir == 1)
{
x++; // right
}
else if (dir == 2)
{
y++; // down
}
else
{
x--; // left
}
}
Download source code
Download executable for Windows
As the ants are more complex now, we will get different results depending on the rule we set in this program.