|
|
b51884 |
#include <stdlib.h></stdlib.h>
|
|
|
b51884 |
#include <time.h></time.h>
|
|
|
b51884 |
#include <gtk gtk.h=""></gtk>
|
|
|
b51884 |
|
|
|
b51884 |
#define ROWS 20
|
|
|
b51884 |
#define COLS 30
|
|
|
b51884 |
|
|
|
b51884 |
const double pi = 3.141592653589793;
|
|
|
b51884 |
|
|
|
b51884 |
const int size = 20;
|
|
|
b51884 |
|
|
|
b51884 |
int field1[COLS][ROWS];
|
|
|
b51884 |
int field2[COLS][ROWS];
|
|
|
b51884 |
GtkWidget *drawing_area;
|
|
|
b51884 |
GtkWidget *toggle_button;
|
|
|
b51884 |
|
|
|
b51884 |
|
|
|
b51884 |
int get_cell(int x, int y) {
|
|
|
b51884 |
x = (x + COLS)%COLS;
|
|
|
b51884 |
y = (y + ROWS)%ROWS;
|
|
|
b51884 |
return field1[x][y];
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
gboolean timeout(gpointer data) {
|
|
|
b51884 |
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))) {
|
|
|
b51884 |
for(int i = 0; i < COLS; ++i) {
|
|
|
b51884 |
for(int j = 0; j < ROWS; ++j) {
|
|
|
b51884 |
int count = 0;
|
|
|
b51884 |
count += get_cell(i-1, j-1);
|
|
|
b51884 |
count += get_cell(i-1, j);
|
|
|
b51884 |
count += get_cell(i-1, j+1);
|
|
|
b51884 |
count += get_cell(i, j-1);
|
|
|
b51884 |
count += get_cell(i, j+1);
|
|
|
b51884 |
count += get_cell(i+1, j-1);
|
|
|
b51884 |
count += get_cell(i+1, j);
|
|
|
b51884 |
count += get_cell(i+1, j+1);
|
|
|
b51884 |
if (field1[i][j]) {
|
|
|
b51884 |
field2[i][j] = (count == 2 || count == 3);
|
|
|
b51884 |
} else {
|
|
|
b51884 |
field2[i][j] = (count == 3);
|
|
|
b51884 |
}
|
|
|
b51884 |
}
|
|
|
b51884 |
}
|
|
|
b51884 |
for(int i = 0; i < COLS; ++i)
|
|
|
b51884 |
for(int j = 0; j < ROWS; ++j)
|
|
|
b51884 |
field1[i][j] = field2[i][j];
|
|
|
b51884 |
gtk_widget_queue_draw(drawing_area);
|
|
|
b51884 |
}
|
|
|
b51884 |
return TRUE;
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
|
|
|
b51884 |
cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1);
|
|
|
b51884 |
cairo_paint(cr);
|
|
|
b51884 |
|
|
|
b51884 |
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1);
|
|
|
b51884 |
for(int i = 0; i <= COLS; ++i) {
|
|
|
b51884 |
cairo_move_to(cr, i*size, 0.0);
|
|
|
b51884 |
cairo_line_to(cr, i*size, ROWS*size);
|
|
|
b51884 |
}
|
|
|
b51884 |
for(int j = 0; j < ROWS; ++j) {
|
|
|
b51884 |
cairo_move_to(cr, 0.0, j*size);
|
|
|
b51884 |
cairo_line_to(cr, COLS*size, j*size);
|
|
|
b51884 |
}
|
|
|
b51884 |
cairo_stroke(cr);
|
|
|
b51884 |
|
|
|
b51884 |
for(int i = 0; i < COLS; ++i) {
|
|
|
b51884 |
for(int j = 0; j < ROWS; ++j) {
|
|
|
b51884 |
if (field1[i][j]) {
|
|
|
b51884 |
cairo_arc(cr, (i + 0.5)*size, (j + 0.5)*size, 0.5*size, 0.0, 2.0*pi);
|
|
|
b51884 |
cairo_fill(cr);
|
|
|
b51884 |
}
|
|
|
b51884 |
}
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
return TRUE;
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
gboolean button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
|
|
|
b51884 |
int x = (int)(event->x)/size;
|
|
|
b51884 |
int y = (int)(event->y)/size;
|
|
|
b51884 |
if (x >= 0 && y >= 0 && x < COLS && y < ROWS) {
|
|
|
b51884 |
field1[x][y] = !field1[x][y];
|
|
|
b51884 |
gtk_widget_queue_draw(drawing_area);
|
|
|
b51884 |
}
|
|
|
b51884 |
return TRUE;
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
void activate(GtkApplication* app, gpointer data) {
|
|
|
b51884 |
srand(time(NULL));
|
|
|
b51884 |
|
|
|
b51884 |
GtkWidget *window = gtk_application_window_new (app);
|
|
|
b51884 |
|
|
|
b51884 |
GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
|
|
|
b51884 |
gtk_container_add(GTK_CONTAINER(window), hbox);
|
|
|
b51884 |
|
|
|
b51884 |
drawing_area = gtk_drawing_area_new();
|
|
|
b51884 |
gtk_widget_set_size_request(GTK_WIDGET(drawing_area), COLS*size, ROWS*size);
|
|
|
b51884 |
gtk_widget_set_hexpand(drawing_area, TRUE);
|
|
|
b51884 |
gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK);
|
|
|
b51884 |
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw), NULL);
|
|
|
b51884 |
g_signal_connect(drawing_area, "button-press-event", G_CALLBACK(button_press), NULL);
|
|
|
b51884 |
gtk_container_add(GTK_CONTAINER(hbox), drawing_area);
|
|
|
b51884 |
|
|
|
b51884 |
toggle_button = gtk_toggle_button_new_with_label("Start/Stop");
|
|
|
b51884 |
gtk_widget_set_valign(toggle_button, GTK_ALIGN_START);
|
|
|
b51884 |
gtk_container_add(GTK_CONTAINER(hbox), toggle_button);
|
|
|
b51884 |
|
|
|
b51884 |
gtk_widget_show_all(window);
|
|
|
b51884 |
|
|
|
b51884 |
g_timeout_add(100, timeout, NULL);
|
|
|
b51884 |
}
|
|
|
b51884 |
|
|
|
b51884 |
int main(int argc, char **argv) {
|
|
|
b51884 |
GtkApplication *application = gtk_application_new(NULL, 0);
|
|
|
b51884 |
g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
|
|
|
b51884 |
int status = g_application_run(G_APPLICATION(application), argc, argv);
|
|
|
b51884 |
g_object_unref(application);
|
|
|
b51884 |
return status;
|
|
|
b51884 |
}
|