|
|
be0c30 |
#include <stdlib.h></stdlib.h>
|
|
|
be0c30 |
#include <time.h></time.h>
|
|
|
be0c30 |
#include <gtk gtk.h=""></gtk>
|
|
|
be0c30 |
|
|
|
be0c30 |
#define COLS 10
|
|
|
be0c30 |
#define ROWS 20
|
|
|
be0c30 |
|
|
|
be0c30 |
const int size = 30;
|
|
|
be0c30 |
const int colors_count = 3;
|
|
|
be0c30 |
const double colors[][3] = {
|
|
|
be0c30 |
{ 1, 1, 1 },
|
|
|
be0c30 |
{ 1, 1, 0 },
|
|
|
be0c30 |
{ 1, 0, 0 },
|
|
|
be0c30 |
{ 0, 0, 1 },
|
|
|
be0c30 |
{ 0.66, 0.66, 0.66 },
|
|
|
be0c30 |
{ 0.33, 0.33, 0.33 } };
|
|
|
be0c30 |
|
|
|
be0c30 |
int board[COLS][ROWS];
|
|
|
be0c30 |
|
|
|
be0c30 |
|
|
|
be0c30 |
void new_game() {
|
|
|
be0c30 |
srand(time(NULL));
|
|
|
be0c30 |
for(int x = 0; x < COLS; ++x)
|
|
|
be0c30 |
for(int y = 0; y < ROWS; ++y)
|
|
|
be0c30 |
board[x][y] = 1 + rand()%colors_count;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
int get_block(int x, int y) {
|
|
|
be0c30 |
if (x < 0 || y < 0 || x >= COLS || y >= ROWS)
|
|
|
be0c30 |
return -1;
|
|
|
be0c30 |
return board[x][y];
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
void check(int x, int y) {
|
|
|
be0c30 |
int color = get_block(x, y);
|
|
|
be0c30 |
if (color > 0) {
|
|
|
be0c30 |
if (get_block(x-1, y) == color) {
|
|
|
be0c30 |
board[x][y] = 0;
|
|
|
be0c30 |
check(x-1, y);
|
|
|
be0c30 |
board[x-1][y] = 0;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
if (get_block(x+1, y) == color) {
|
|
|
be0c30 |
board[x][y] = 0;
|
|
|
be0c30 |
check(x+1, y);
|
|
|
be0c30 |
board[x+1][y] = 0;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
if (get_block(x, y-1) == color) {
|
|
|
be0c30 |
board[x][y] = 0;
|
|
|
be0c30 |
check(x, y-1);
|
|
|
be0c30 |
board[x][y-1] = 0;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
if (get_block(x, y+1) == color) {
|
|
|
be0c30 |
board[x][y] = 0;
|
|
|
be0c30 |
check(x, y+1);
|
|
|
be0c30 |
board[x][y+1] = 0;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
}
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
void fall() {
|
|
|
be0c30 |
int dx = 0;
|
|
|
be0c30 |
for(int x = 0; x < COLS; ++x) {
|
|
|
be0c30 |
int dy = 0;
|
|
|
be0c30 |
for(int y = 0; y < ROWS; ++y) {
|
|
|
be0c30 |
if (board[x][y] != 0) {
|
|
|
be0c30 |
if (dx > 0 || dy > 0) {
|
|
|
be0c30 |
board[x-dx][y-dy] = board[x][y];
|
|
|
be0c30 |
board[x][y] = 0;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
} else {
|
|
|
be0c30 |
++dy;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
}
|
|
|
be0c30 |
if (dy == ROWS) ++dx;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
gboolean button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
|
|
|
be0c30 |
if (event->button == 1) {
|
|
|
be0c30 |
check((int)(event->x)/size, ROWS - 1 - (int)(event->y)/size);
|
|
|
be0c30 |
fall();
|
|
|
be0c30 |
} else
|
|
|
be0c30 |
if (event->button == 3) {
|
|
|
be0c30 |
new_game();
|
|
|
be0c30 |
}
|
|
|
be0c30 |
gtk_widget_queue_draw(widget);
|
|
|
be0c30 |
return TRUE;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
|
|
|
be0c30 |
for(int x = 0; x < COLS; ++x) {
|
|
|
be0c30 |
for(int y = 0; y < ROWS; ++y) {
|
|
|
be0c30 |
int c = board[x][ROWS - 1 - y];
|
|
|
be0c30 |
cairo_rectangle(cr, x*size, y*size, size, size);
|
|
|
be0c30 |
cairo_set_source_rgb(cr, colors[c][0], colors[c][1], colors[c][2]);
|
|
|
be0c30 |
cairo_fill(cr);
|
|
|
be0c30 |
}
|
|
|
be0c30 |
}
|
|
|
be0c30 |
return TRUE;
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
void activate(GtkApplication* app, gpointer data) {
|
|
|
be0c30 |
GtkWidget *window = gtk_application_window_new (app);
|
|
|
be0c30 |
g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
|
|
|
be0c30 |
g_signal_connect(window, "button-press-event", G_CALLBACK(button_press), NULL);
|
|
|
be0c30 |
gtk_window_set_default_size(GTK_WINDOW(window), size*COLS, size*ROWS);
|
|
|
be0c30 |
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
|
|
|
be0c30 |
gtk_widget_show_all(window);
|
|
|
be0c30 |
|
|
|
be0c30 |
new_game();
|
|
|
be0c30 |
}
|
|
|
be0c30 |
|
|
|
be0c30 |
int main(int argc, char **argv) {
|
|
|
be0c30 |
GtkApplication *application = gtk_application_new(NULL, 0);
|
|
|
be0c30 |
g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
|
|
|
be0c30 |
int status = g_application_run(G_APPLICATION(application), argc, argv);
|
|
|
be0c30 |
g_object_unref(application);
|
|
|
be0c30 |
return status;
|
|
|
be0c30 |
}
|