You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
3.4 KiB
161 lines
3.4 KiB
# include <iostream>
|
|
# include <cmath>
|
|
# include <cstdlib>
|
|
# include <cstring>
|
|
# include <unistd.h>
|
|
# include<ctime>
|
|
|
|
using namespace std;
|
|
|
|
const int DIM = 35;
|
|
const int HALF = DIM / 2;
|
|
|
|
// Get the number of bits needed to store an int
|
|
int get_bits (int x) {
|
|
return floor(log(x)/log(2)) + 1;
|
|
}
|
|
|
|
// Convert an int to a string representation of a binary number
|
|
string to_bin(int x) {
|
|
if(x == 0) {
|
|
return "0";
|
|
} else {
|
|
int bits = get_bits(x);
|
|
char buffer[bits];
|
|
char* p = buffer + bits;
|
|
do {
|
|
*--p = '0' + (x & 1);
|
|
} while (x >>= 1);
|
|
|
|
return string(p, buffer + bits);
|
|
}
|
|
}
|
|
|
|
// Convert a string representation of a binary number to an integer
|
|
long to_int(string str) {
|
|
|
|
char * ptr;
|
|
return strtol(str.c_str(), & ptr, 2);
|
|
}
|
|
|
|
// Get the string representation of a rule
|
|
string get_rule(int rule, int bits = 9) {
|
|
if(bits < get_bits(rule) ) {
|
|
bits = get_bits(rule);
|
|
}
|
|
int length = pow(2, bits);
|
|
string str = to_bin(rule);
|
|
int strl = strlen(str.c_str());
|
|
string padding = "";
|
|
if (strl < length) {
|
|
for (int i = 0; i < (length - strl); i++) {
|
|
padding += "0";
|
|
}
|
|
}
|
|
return string ( str.rbegin(), str.rend() ) + padding;
|
|
}
|
|
|
|
// Get the bit that correspons to the int pos of the rule
|
|
int get_val_at_pos(int pos, int rule) {
|
|
// Minus the ascii value of 0
|
|
return get_rule(rule).c_str()[pos] - 48;
|
|
}
|
|
|
|
// Pretty pint a matrix of bits (represented by ints)
|
|
void print_arr(int arr[DIM][DIM]) {
|
|
for(int i = 0; i < DIM; i++) {
|
|
for( int j = 0; j < DIM; j++) {
|
|
int value = arr[i][j];
|
|
char c;
|
|
if(value == 1) {
|
|
c = '#';
|
|
} else {
|
|
c = ' ';
|
|
}
|
|
cout << c << " ";
|
|
}
|
|
cout << endl;
|
|
}
|
|
cout << endl;
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[] ) {
|
|
// Assume rule 30 and 200 generations if nothing else is stated
|
|
int rule = 30;
|
|
int gens = 200;
|
|
if (argc > 1) {
|
|
gens = atoi(argv[1]);
|
|
}
|
|
if (argc > 2) {
|
|
rule = atoi(argv[2]);
|
|
}
|
|
// Seed the random number generator
|
|
srand (time(0));
|
|
|
|
// Set up the initial condition
|
|
int initial[DIM][DIM];
|
|
int row = rand() % DIM;
|
|
int column = rand() % DIM;
|
|
for(int i = 0; i < DIM; i++) {
|
|
for(int j = 0; j < DIM; j++) {
|
|
if(i == DIM -1 && j == HALF ) {
|
|
initial[i][j] = 1;
|
|
} else {
|
|
initial[i][j] = 0;
|
|
}
|
|
|
|
//initial[i][j] = rand() % 2;
|
|
|
|
/*if(i == column && j == row ) {
|
|
initial[i][j] = 1;
|
|
} else {
|
|
initial[i][j] = 0;
|
|
}*/
|
|
|
|
}
|
|
}
|
|
|
|
// Loop all generations
|
|
for(int i = 0; i < gens; i++) {
|
|
// Clear the screen
|
|
cout << "\033[2J";
|
|
cout << "\033[0;0H";
|
|
cout << "Rule: " << rule << " generation: " << i << endl;
|
|
// Print the current state
|
|
print_arr(initial);
|
|
// Sleep 0.05 seconds
|
|
usleep(50000);
|
|
|
|
// The next state
|
|
int next[DIM][DIM];
|
|
// Loop the columns
|
|
for(int j = 0; j < DIM; j++) {
|
|
char state[10];
|
|
// Loop the row
|
|
for(int k = 0; k < DIM; k++) {
|
|
state[9] = '\0';
|
|
state[8] = initial[ (j -1) % DIM ][ (k-1) % DIM ] + 48;
|
|
state[7] = initial[ (j -1) % DIM ][k] + 48;
|
|
state[6] = initial[ (j -1) % DIM ][ (k+1) % DIM ] + 48;
|
|
state[5] = initial[j][ (k-1) % DIM ] + 48;
|
|
state[4] = initial[j][k] + 48 ;
|
|
state[3] = initial[j][ (k+1) % DIM ] + 48;
|
|
state[2] = initial[ (j +1) % DIM ][ (k-1) % DIM ] + 48;
|
|
state[1] = initial[ (j +1) % DIM ][k] + 48;
|
|
state[0] = initial[ (j +1) % DIM ][ (k+1) % DIM ] + 48;
|
|
|
|
next[j][k] = get_val_at_pos(to_int(state), rule);
|
|
}
|
|
}
|
|
// Copy the matrix
|
|
for(int j = 0; j < DIM; j++) {
|
|
for(int k = 0; k < DIM; k++) {
|
|
initial[j][k] = next[j][k];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|