438 lines
12 KiB
C
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);
|
|
}
|