Why does my Neural Cellular automaton not draw grphics properly

57 Views Asked by At

I am attempting to recreate the neural cellular automaton shown in this video using openGL and c. I am using a simple Game of Life demo shown in minute 7:08 of the video to check if my code works (the filter and and the activation function are also shown in minute 7:08), the problem is that my code is not acting the way it should even though I did everything, we can see this in Frame1 and 2,in Frame1 we can see the glider but once the filter and activation is appled it acts completely differently, the glider should act like in conways game of life but its behaviour follows a seemingly random ruleset.

Frame1: Frame2:

code:

#include <stdio.h>
#include <windows.h>
#include <GL/glut.h>

#define sleep(x) Sleep(1000 * (x))

#define sizeX 10
#define sizeY 10
#define wallSize 40

int frame = 0;

double grid[sizeY][sizeX];
double filter[3][3] = {{1, 1, 1},
                       {1, 9, 1},
                       {1, 1, 1}};
                       

int width = 1000;
int height = 500;

double activation(double x){
    if(x == 3 || x == 11 || x == 12){
        return 1;
    }
    else{
        return 0;
    }
}

void CVFilter(){
    int x,y;
    double cv; //covolved value
    for(y=1;y<sizeY-1;y++){
  for(x=1;x<sizeX-1;x++){
    cv = (grid[y+1][x-1]*filter[0][0]) + (grid[y+1][x]*filter[0][1]) + (grid[y+1][x+1]*filter[2][2])+
         (grid[y][x-1]*filter[1][0]) + (grid[y][x]*filter[1][1]) + (grid[y][x+1]*filter[1][2])+
         (grid[y-1][x-1]*filter[2][0]) + (grid[y-1][x]*filter[2][1]) + (grid[y-1][x+1]*filter[2][2]);
            grid[y][x] = activation(cv);
  }
 }
}

void drawGrid(){
 int x,y;
 double rgb;
 glPointSize(wallSize);
 glBegin(GL_POINTS);
 for(y=0;y<sizeY;y++){
  for(x=0;x<sizeX;x++){
    rgb = grid[y][x];
    glColor3f(rgb,rgb,rgb);
    glVertex2i((x*wallSize),(y*wallSize));
  }
 }
 glEnd();
}

void display(){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 if(frame == 1){
  CVFilter();
 }
 if(frame == 2){
    sleep(1000);
 }
 //-----------------------Draw----------------------
 drawGrid();
 //-------------------------------------------------
 glutSwapBuffers();
 glutPostRedisplay();
 sleep(3);
 frame++;
}


void init(){
 glClearColor(0.3,0.3,0.3,0);
 gluOrtho2D(0,width,height,0);
}

void main(int argc, char** argv){ 
 grid[5][5] = 1; //Draws the glider
 grid[4][5] = 1; //Draws the glider
 grid[3][5] = 1; //Draws the glider
    grid[5][4] = 1; //Draws the glider
    grid[4][3] = 1; //Draws the glider
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(width,height);
 glutCreateWindow("OpenGL");
 init();
 glutDisplayFunc(display);
 glutMainLoop();
}
1

There are 1 best solutions below

0
Saw On

So using @Nelfeal 's advice, I made a copy of the grid where I made the changes and once that was done I coloned the values back to the main grid. This fixed the problem.

#include <stdio.h>
#include <windows.h>
#include <GL/glut.h>

#define sleep(x) Sleep(1000 * (x))

#define sizeX 10
#define sizeY 10
#define wallSize 40

int frame = 0;

double grid[sizeY][sizeX];
double newGrid[sizeY][sizeX];
double filter[3][3] = {{1, 1, 1},
                       {1, 9, 1},
                       {1, 1, 1}};
                       

int width = 1000;
int height = 500;

double activation(double x){
    if(x == 3 || x == 11 || x == 12){
        return 1;
    }
    else{
        return 0;
    }
}

void CVFilter(){
    int x,y;
    double cv; //covolved value
    for(y=1;y<sizeY-1;y++){
  for(x=1;x<sizeX-1;x++){
    cv = (grid[y+1][x-1]*filter[0][0]) + (grid[y+1][x]*filter[0][1]) + (grid[y+1][x+1]*filter[2][2])+
         (grid[y][x-1]*filter[1][0]) + (grid[y][x]*filter[1][1]) + (grid[y][x+1]*filter[1][2])+
         (grid[y-1][x-1]*filter[2][0]) + (grid[y-1][x]*filter[2][1]) + (grid[y-1][x+1]*filter[2][2]);
            newGrid[y][x] = activation(cv);
  }
 }
}

void drawGrid(){
 int x,y;
 double rgb;
 glPointSize(wallSize);
 glBegin(GL_POINTS);
 for(y=0;y<sizeY;y++){
  for(x=0;x<sizeX;x++){
    rgb = grid[y][x];
    glColor3f(rgb,rgb,rgb);
    glVertex2i((x*wallSize),(y*wallSize));
  }
 }
 glEnd();
}

void cloneGrids(){
    int x,y;
    for(y=0;y<sizeY;y++){
  for(x=0;x<sizeX;x++){
    grid[y][x] = newGrid[y][x];
  }
 }
}

void display(){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 if(frame == 1){
  CVFilter();
  cloneGrids();
 }
 if(frame == 2){
    sleep(1000);
 }
 //-----------------------Draw----------------------
 drawGrid();
 //-------------------------------------------------
 glutSwapBuffers();
 glutPostRedisplay();
 sleep(3);
 frame++;
}


void init(){
 glClearColor(0.3,0.3,0.3,0);
 gluOrtho2D(0,width,height,0);
}

void main(int argc, char** argv){ 
 grid[5][5] = 1; //Draws the glider
 grid[4][5] = 1; //Draws the glider
 grid[3][5] = 1; //Draws the glider
    grid[5][4] = 1; //Draws the glider
    grid[4][3] = 1; //Draws the glider
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(width,height);
 glutCreateWindow("OpenGL");
 init();
 glutDisplayFunc(display);
 glutMainLoop();
}