From be0c301c628b42e15b157258576be6f4ead8c8d2 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Jan 19 2019 16:07:13 +0000 Subject: c gtk3: click --- diff --git a/c/gtk3/click/click.c b/c/gtk3/click/click.c new file mode 100644 index 0000000..b935bde --- /dev/null +++ b/c/gtk3/click/click.c @@ -0,0 +1,119 @@ +#include +#include +#include + +#define COLS 10 +#define ROWS 20 + +const int size = 30; +const int colors_count = 3; +const double colors[][3] = { + { 1, 1, 1 }, + { 1, 1, 0 }, + { 1, 0, 0 }, + { 0, 0, 1 }, + { 0.66, 0.66, 0.66 }, + { 0.33, 0.33, 0.33 } }; + +int board[COLS][ROWS]; + + +void new_game() { + srand(time(NULL)); + for(int x = 0; x < COLS; ++x) + for(int y = 0; y < ROWS; ++y) + board[x][y] = 1 + rand()%colors_count; +} + +int get_block(int x, int y) { + if (x < 0 || y < 0 || x >= COLS || y >= ROWS) + return -1; + return board[x][y]; +} + +void check(int x, int y) { + int color = get_block(x, y); + if (color > 0) { + if (get_block(x-1, y) == color) { + board[x][y] = 0; + check(x-1, y); + board[x-1][y] = 0; + } + if (get_block(x+1, y) == color) { + board[x][y] = 0; + check(x+1, y); + board[x+1][y] = 0; + } + if (get_block(x, y-1) == color) { + board[x][y] = 0; + check(x, y-1); + board[x][y-1] = 0; + } + if (get_block(x, y+1) == color) { + board[x][y] = 0; + check(x, y+1); + board[x][y+1] = 0; + } + } +} + +void fall() { + int dx = 0; + for(int x = 0; x < COLS; ++x) { + int dy = 0; + for(int y = 0; y < ROWS; ++y) { + if (board[x][y] != 0) { + if (dx > 0 || dy > 0) { + board[x-dx][y-dy] = board[x][y]; + board[x][y] = 0; + } + } else { + ++dy; + } + } + if (dy == ROWS) ++dx; + } +} + +gboolean button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) { + if (event->button == 1) { + check((int)(event->x)/size, ROWS - 1 - (int)(event->y)/size); + fall(); + } else + if (event->button == 3) { + new_game(); + } + gtk_widget_queue_draw(widget); + return TRUE; +} + +gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) { + for(int x = 0; x < COLS; ++x) { + for(int y = 0; y < ROWS; ++y) { + int c = board[x][ROWS - 1 - y]; + cairo_rectangle(cr, x*size, y*size, size, size); + cairo_set_source_rgb(cr, colors[c][0], colors[c][1], colors[c][2]); + cairo_fill(cr); + } + } + return TRUE; +} + +void activate(GtkApplication* app, gpointer data) { + GtkWidget *window = gtk_application_window_new (app); + g_signal_connect(window, "draw", G_CALLBACK(draw), NULL); + g_signal_connect(window, "button-press-event", G_CALLBACK(button_press), NULL); + gtk_window_set_default_size(GTK_WINDOW(window), size*COLS, size*ROWS); + gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK); + gtk_widget_show_all(window); + + new_game(); +} + +int main(int argc, char **argv) { + GtkApplication *application = gtk_application_new(NULL, 0); + g_signal_connect(application, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(application), argc, argv); + g_object_unref(application); + return status; +}