commit b7536e462acf6fc3309caf07d193c0ca6d8c7540 Author: hollorol Date: Mon Dec 2 21:45:40 2024 +0100 first implementation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe3d975 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +conway diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..88cd3cf --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +conway: main.c + gcc -o conway main.c -lncurses -lm diff --git a/main.c b/main.c new file mode 100644 index 0000000..a846207 --- /dev/null +++ b/main.c @@ -0,0 +1,466 @@ +#include +#include +#include +#include +#include + + +int conwayMatrix[50][120] = {0}; +int tempMatrix[50][120] = {0}; + +int base_percentage = 30; + +void generateRandomMatrix(int prob){ + for(int i = 0; i < 50; ++i){ + for(int j = 0; j < 120; ++j){ + conwayMatrix[i][j] = rand() % 100 < prob ? 1 : 0; + } + } +} + +int probdie(int prob){ + return rand() % 100 < prob ? 1 : 0; +} + +void clearConwayMatrix(){ + for(int i = 0; i < 50; ++i){ + for(int j = 0; j < 120; ++j){ + conwayMatrix[i][j] = 0; + } + } +} + +void displayConwayMatrix(){ + for(int i = 0; i < 50; ++i){ + for(int j = 0; j < 120; ++j){ + if(conwayMatrix[i][j] == 1){ + attrset(COLOR_PAIR(7)); + mvaddch(i, j, ' '); + } else { + attrset(COLOR_PAIR(0)); + mvaddch(i, j, ' '); + } + + } + } + refresh(); +} + +void drawcircle(){ + + char c; + MEVENT event; + int n = 0; + int points[2][2]; + while (1) { + c = getch(); + if (getmouse(&event) == OK) { + attrset(COLOR_PAIR(3)); + conwayMatrix[event.y][event.x] = 1; + mvaddch(event.y, event.x, ' '); + refresh(); + points[n][0] = event.x; + points[n][1] = event.y; + n++; + } + + if (n == 2){ + break; + } + + } + + int radius2 = (points[1][0] - points[0][0]) * (points[1][0] - points[0][0]) + + (points[1][1] - points[0][1]) * (points[1][1] - points[0][1]); + /* int radius = (int) sqrt(radius2); */ + int x,y; + + for (int i = 0; i*i <= radius2; i++){ + + y = points[0][1] + (int) sqrt(radius2 - i*i); + x = points[0][0] + i; + + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + y = points[0][1] + (int) sqrt(radius2 - i*i); + x = points[0][0] - i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + y = points[0][1] - (int)sqrt(radius2 - i*i); + x = points[0][0] + i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + + y = points[0][1] - (int) sqrt(radius2 - i*i); + x = points[0][0] - i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + x = points[0][0] + (int) sqrt(radius2 - i*i); + y = points[0][1] + i; + + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + x = points[0][0] + (int) sqrt(radius2 - i*i); + y = points[0][1] - i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + x = points[0][0] - (int)sqrt(radius2 - i*i); + y = points[0][1] + i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + + x = points[0][0] - (int) sqrt(radius2 - i*i); + y = points[0][1] - i; + if (x < 120 && y < 50 && x >= 0 && y >= 0){ + conwayMatrix[y][x] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(y, x, ' '); + } + + + } + +} + +void drawLine_from_points(int points[2][2]){ + float dx = (float)(points[1][0] - points[0][0]); + float dy = (float)(points[1][1] - points[0][1]); + + if( (dx == dy) && (dx == 0)){ + return; + } + + if(fabs(dx) >= fabs(dy)){ + for(int i = 0; i < (points[1][0] - points[0][0]); ++i){ + conwayMatrix[points[0][1] + (int)((dy/dx)*(float)i)][points[0][0] + i] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(points[0][1] + (int)((dy/dx)*(float)i), points[0][0] + i, ' '); + } + + refresh(); + return; + } + for(int i = 0; i < (points[1][1] - points[0][1]); ++i){ + conwayMatrix[points[0][1] + i][points[0][0] + (int)((dx/dy)*(float)i)] = 1; + attrset(COLOR_PAIR(3)); + mvaddch(points[0][1] + i,points[0][0] + (int)((dx/dy)*(float)i), ' '); + } + refresh(); +} + +void drawLine(){ + + char c; + MEVENT event; + int n = 0; + int points[2][2]; + while (1) { + c = getch(); + + if(c == 'q'){ + break; + } + + if (getmouse(&event) == OK) { + attrset(COLOR_PAIR(3)); + conwayMatrix[event.y][event.x] = 1; + mvaddch(event.y, event.x, ' '); + refresh(); + points[n][0] = event.x; + points[n][1] = event.y; + n++; + } + + if (n == 2){ + drawLine_from_points(points); + n = 0; + } + + } +} + +void geometry(){ + mvprintw(0, 0, "Geometry Mode: Press 'c' to draw a circle, 'q' to quit."); + refresh(); + while(1){ + char c = getch(); + switch(c){ + case 'q': + return; + case 'c': + drawcircle(); + return; + case 'l': + drawLine(); + return; + + } + + } +} + + +void simulate() { + + int left_neighbour = 0; + int right_neighbour = 0; + int top_neighbour = 0; + int bottom_neighbour = 0; + int topleft_neighbour = 0; + int topright_neighbour = 0; + int bottomleft_neighbour = 0; + int bottomright_neighbour = 0; + int num_neighbours = 0; + int conwayMode = 0; + int num = 0; + while(1){ + + if(getch() == 's'){ + break; + } + displayConwayMatrix(); + for(int i = 0; i < 50; ++i){ + for(int j = 0; j < 120; ++j){ + + if(j-1 <0){ + left_neighbour = 0; + } else { + left_neighbour = conwayMatrix[i][j-1]; + } + if(j+1 > 119){ + right_neighbour = 0; + } else { + right_neighbour = conwayMatrix[i][j+1]; + } + if(i-1 < 0){ + top_neighbour = 0; + } else { + top_neighbour = conwayMatrix[i-1][j]; + } + if(i+1 > 49){ + bottom_neighbour = 0; + } else { + bottom_neighbour = conwayMatrix[i+1][j]; + } + // topleft + if(i-1 < 0 || j-1 < 0){ + topleft_neighbour = 0; + } else { + topleft_neighbour = conwayMatrix[i-1][j-1]; + } + // topright + if(i-1 < 0 || j+1 > 119){ + topright_neighbour = 0; + } else { + topright_neighbour = conwayMatrix[i-1][j+1]; + } + // bottomleft + if(i+1 > 49 || j-1 < 0){ + bottomleft_neighbour = 0; + } else { + bottomleft_neighbour = conwayMatrix[i+1][j-1]; + } + // bottomright + + if(i+1 > 49 || j+1 > 119){ + bottomright_neighbour = 0; + } else { + bottomright_neighbour = conwayMatrix[i+1][j+1]; + } + + num_neighbours = left_neighbour + right_neighbour + top_neighbour + bottom_neighbour + topleft_neighbour + topright_neighbour + bottomleft_neighbour + bottomright_neighbour; + tempMatrix[i][j] = conwayMatrix[i][j]; + if((num_neighbours < 2) && (conwayMatrix[i][j] == 1)){ + /* tempMatrix[i][j] = probdie(10); */ + tempMatrix[i][j] = 0; + } else if(num_neighbours > 3){ + /* tempMatrix[i][j] = probdie(5); */ + tempMatrix[i][j] = 0; + } else if(num_neighbours == 3){ + tempMatrix[i][j] = 1; + } + + } + } + + for(int i = 0; i < 50; ++i){ + for(int j = 0; j < 120; ++j){ + conwayMatrix[i][j] = tempMatrix[i][j]; + } + } + + refresh(); + usleep(100000); + + } +} + + +static void finish(int sig); + +int +main(int argc, char *argv[]) +{ + int left_neighbour = 0; + int right_neighbour = 0; + int top_neighbour = 0; + int bottom_neighbour = 0; + int topleft_neighbour = 0; + int topright_neighbour = 0; + int bottomleft_neighbour = 0; + int bottomright_neighbour = 0; + int num_neighbours = 0; + int conwayMode = 0; + int num = 0; + printf("\033[?1003h\n"); + + /* initialize your non-curses data structures here */ + + (void) signal(SIGINT, finish); /* arrange interrupts to terminate */ + + (void) initscr(); /* initialize the curses library */ + keypad(stdscr, TRUE); /* enable keyboard mapping */ + (void) nonl(); /* tell curses not to do NL->CR/NL on output */ + (void) cbreak(); /* take input chars one at a time, no wait for \n */ + (void) echo(); /* echo input - in color */ + noecho(); // Prevent echoing of input + cbreak(); // Disable line buffering, get input immediately + nodelay(stdscr, TRUE); + if (mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL) == 0) { + endwin(); + printf("Mouse events not supported.\n"); + printf("\033[?1003l\n"); // Disable mouse reporting + return 1; + } + MEVENT event; + + curs_set(0); // Hide cursor + if (has_colors()) + { + start_color(); + + init_pair(0, COLOR_BLACK, COLOR_BLACK); + init_pair(1, COLOR_RED, COLOR_RED); + init_pair(2, COLOR_GREEN, COLOR_GREEN); + init_pair(3, COLOR_YELLOW, COLOR_YELLOW); + init_pair(4, COLOR_BLUE, COLOR_BLUE); + init_pair(5, COLOR_CYAN, COLOR_CYAN); + init_pair(6, COLOR_MAGENTA, COLOR_MAGENTA); + init_pair(7, COLOR_WHITE, COLOR_WHITE); + } + + srand(time(NULL)); + for (;;) + { + char c=getch(); + + if (getmouse(&event) == OK) { + // Display the mouse position + if (conwayMatrix[event.y][event.x] == 1){ + attrset(COLOR_PAIR(0)); + conwayMatrix[event.y][event.x] = 0; + mvaddch(event.y, event.x, ' '); + } else { + attrset(COLOR_PAIR(7)); + conwayMatrix[event.y][event.x] = 1; + mvaddch(event.y, event.x, ' '); + } + + refresh(); + } + + switch(c){ + case 'q': + finish(0); + break; + case 'r': + clear(); + clearConwayMatrix(); + generateRandomMatrix(base_percentage); + displayConwayMatrix(); + break; + case 'c': + clear(); + clearConwayMatrix(); + break; + case 's': + simulate(); + break; + case 'g': + geometry(); + break; + case '1': + base_percentage = 10; + break; + case '2': + base_percentage = 20; + break; + case '3': + base_percentage = 30; + break; + case '4': + base_percentage = 40; + break; + case '5': + base_percentage = 50; + break; + case '6': + base_percentage = 60; + break; + case '7': + base_percentage = 70; + break; + case '8': + base_percentage = 80; + break; + case '9': + base_percentage = 90; + break; + } + + refresh(); + + /* process the command keystroke */ + } + + finish(0); /* we are done */ +} + +static void finish(int sig) +{ + + printf("\033[?1003l\n"); + endwin(); + + /* do your non-curses wrapup here */ + + exit(0); +}