nthconwayscurses/main.c
2024-12-03 09:36:48 +01:00

438 lines
12 KiB
C

#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <time.h>
#include <math.h>
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){
left_neighbour = conwayMatrix[i][((j-1) +120) % 120];
right_neighbour = conwayMatrix[i][(j+1) % 120];
top_neighbour = conwayMatrix[((i-1) + 50) % 50][j];
bottom_neighbour = conwayMatrix[(i+1) % 50][j];
topleft_neighbour = conwayMatrix[((i-1) + 50) % 50][((j-1) + 120) % 120];
topright_neighbour = conwayMatrix[((i-1) + 50) % 50][(j+1) % 120];
bottomleft_neighbour = conwayMatrix[(i+1) % 50][((j-1) + 120) % 120];
bottomright_neighbour = conwayMatrix[(i+1)%50][(j+1)%50];
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);
}