Blame c/gtk3/click/click.c

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