Задача: создать игру Пазл; Игра пазл: Основная задача - убедиться, что пазл соберется. Для этого необходимо проверить на четность количество инверсий в перестановках. Если оно четное - пазл соберется верно, иначе мы перемешиваем части пазла еще раз. /* Подключаемые модули */ #pragma comment(lib,"gthread-2.0.lib") #pragma comment(lib,"gtk-win32-2.0.lib") #pragma comment(lib,"glib-2.0.lib") #pragma comment(lib,"gobject-2.0.lib") #pragma comment(lib,"gdk-win32-2.0.lib") #pragma comment(lib,"gdk_pixbuf-2.0.lib") #pragma comment(lib,"pango-1.0.lib") #pragma comment(lib,"pangowin32-1.0.lib") #pragma comment(lib,"intl.lib") /* Подключаемые библиотеки; WIDTH - ширина создаваемого окна; HEIGHT - высота создаваемого окна; N - разрядность матрицы ||NxN||; R - длина стороны квадратика; shadow - сдвиг, чтобы из квадрата, радиуса R, получить квадрат радиуса чуть меньше; */ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <stdlib.h> #include <time.h> #define WIDTH N*R #define HEIGHT N*R #define N 4 #define R 100 #define shadow 5 int X1,Y1,Y2,X2,x1,x2,y1,y2,I,J,vector; int a[N][N],lent; GdkGC *gc,*gc1;//графические контексты GtkWidget *window,*window1;//окна GdkDrawable *w,*w1;//области рисования double x_mouse, y_mouse;//координаты мышки GtkWidget *mstart,*mst1,*mst2,*mst3,*mst4,*mst5,*mst6,*mst7,*mst8,*mst9,*mst10,*mst11,*mst12,*mst13,*mst14,*mst15,*mst16,*ms; GdkPixbuf *start,*st1,*st2,*st3,*st4,*st5,*st6,*st7,*st8,*st9,*st10,*st11,*st12,*st13,*st14,*st15,*st16,*t,*s; gboolean boolstart(GtkWidget *widget); // функция перерисовки состояния. gboolean mousemove(GtkWidget *w, GdkEvent *e,gpointer data); // отслеживание перемещение мышки gboolean on_click(GtkWidget *Window, GdkEventButton *event, gpointer data); // функция, обрабатывающая, событие: click gboolean on_draw(GtkWidget *widget, GdkEventExpose *event, gpointer data); // задает исходное состояние. gboolean apis(GtkWidget *widget, GdkEventExpose *event, gpointer data); // задает полную картинку. gboolean destroy(GtkWidget *widget); // разрушение. gboolean keypress(GtkWidget *widget, GdkEventKey *e,gpointer data); // обработка нажатия клавиш на клавиатуре. gint delete_event(GtkWidget *widget); // удаление события. gboolean time_wind(GtkWidget *widget); // перемещение кусочка пазла. gboolean gdk_draw_picture(GdkPixbuf *picture,gint x,gint y); // прорисовка изображения. /* отслеживание перемещений мышки */ gboolean mousemove(GtkWidget *w, GdkEvent *e,gpointer data) { double a,b; gdk_event_get_coords(e,&a,&b); x_mouse=a; y_mouse=b; return FALSE; } gboolean gdk_draw_picture(GdkPixbuf *picture,gint x,gint y) // прорисовка изображения. { gdk_draw_pixbuf(w,gc,picture,0,0,x,y,R,R,GDK_RGB_DITHER_NONE,0,0); return TRUE; } /* обработка нажатия клавиш на клавиатуре */ gboolean keypress(GtkWidget *widget, GdkEventKey *e,gpointer data) { int st[N*N - 1],i,k,j,s,zero,t1,rdt,t2,tt1,tt2; switch(e->keyval) { case (GDK_r): // если нажали английскую 'r', проверяем состояние; { do { rdt = rand()%100 + 20; for(i=0; i<rdt; i++) { t1 = rand()%N; t2 = rand()%N; tt1 = rand()%(N/2); tt2 = rand()%(N/2) + N/2; j = a[tt1][t1]; a[tt1][t1] = a[tt2][t2]; a[tt2][t2] = j; } for(i=0,k=0; i<N; i++) // переписываем элементы в строчку, исключая 0 { for(j=0; j<N; j++) { if(a[i][j] != 0) {st[k] = a[i][j]; k++; } else { zero = i + 1;} } } s = 1; k = 0; while(s) // подсчет инверсий { i = 0; s = 0; while(i < N*N - 2) { if(st[i] > st[i+1]) { k++; // +1 инверсия s = 1; j = st[i]; st[i] = st[i+1]; st[i+1] = j; } i++; } } if((k+zero)%2 == 0) break; }while(k); boolstart(window); break; } } return TRUE; } int main(int arge, char **argv) { int i,j,k; gtk_init(&arge,&argv); srand(time(0)); k = 0; for(i=0;i<N;i++) // создание начальной матрицы { for(j=0;j<N;j++) { k++; if(i == N-1 && j == N-1) a[i][j] = 0; else a[i][j] = k; } } mst1 = gtk_image_new_from_file("img//st1.jpg");//загружаем картинки st1 = gtk_image_get_pixbuf(GTK_IMAGE(mst1)); mst2 = gtk_image_new_from_file("img//st2.jpg"); st2 = gtk_image_get_pixbuf(GTK_IMAGE(mst2)); mst3 = gtk_image_new_from_file("img//st3.jpg"); st3 = gtk_image_get_pixbuf(GTK_IMAGE(mst3)); mst4 = gtk_image_new_from_file("img//st4.jpg"); st4 = gtk_image_get_pixbuf(GTK_IMAGE(mst4)); mst5 = gtk_image_new_from_file("img//st5.jpg"); st5 = gtk_image_get_pixbuf(GTK_IMAGE(mst5)); mst6 = gtk_image_new_from_file("img//st6.jpg"); st6 = gtk_image_get_pixbuf(GTK_IMAGE(mst6)); mst7 = gtk_image_new_from_file("img//st7.jpg"); st7 = gtk_image_get_pixbuf(GTK_IMAGE(mst7)); mst8 = gtk_image_new_from_file("img//st8.jpg"); st8 = gtk_image_get_pixbuf(GTK_IMAGE(mst8)); mst9 = gtk_image_new_from_file("img//st9.jpg"); st9 = gtk_image_get_pixbuf(GTK_IMAGE(mst9)); mst10 = gtk_image_new_from_file("img//st10.jpg"); st10 = gtk_image_get_pixbuf(GTK_IMAGE(mst10)); mst11 = gtk_image_new_from_file("img//st11.jpg"); st11 = gtk_image_get_pixbuf(GTK_IMAGE(mst11)); mst12 = gtk_image_new_from_file("img//st12.jpg"); st12 = gtk_image_get_pixbuf(GTK_IMAGE(mst12)); mst13 = gtk_image_new_from_file("img//st13.jpg"); st13 = gtk_image_get_pixbuf(GTK_IMAGE(mst13)); mst14 = gtk_image_new_from_file("img//st14.jpg"); st14 = gtk_image_get_pixbuf(GTK_IMAGE(mst14)); mst15 = gtk_image_new_from_file("img//st15.jpg"); st15 = gtk_image_get_pixbuf(GTK_IMAGE(mst15)); mst16 = gtk_image_new_from_file("img//st16.jpg"); st16 = gtk_image_get_pixbuf(GTK_IMAGE(mst16)); ms = gtk_image_new_from_file("img//start.jpg"); s = gtk_image_get_pixbuf(GTK_IMAGE(ms)); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window,WIDTH,HEIGHT); gtk_widget_set_size_request(window1,WIDTH,HEIGHT); gtk_widget_add_events(window,GDK_POINTER_MOTION_MASK); gtk_widget_add_events(window,GDK_BUTTON_PRESS_MASK); gtk_widget_add_events(window,GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(window),"motion-notify-event",G_CALLBACK(mousemove),NULL); g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(destroy),NULL); g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL); g_signal_connect(G_OBJECT(window),"button-press-event",G_CALLBACK(on_click),NULL); g_signal_connect(G_OBJECT(window),"key-press-event",G_CALLBACK(keypress),NULL); g_signal_connect(G_OBJECT(window),"expose_event",G_CALLBACK(on_draw),NULL); g_signal_connect(G_OBJECT(window1),"expose_event",G_CALLBACK(apis),NULL); gtk_widget_show_all(window); gtk_widget_show_all(window1); gtk_main(); return 0; } gboolean destroy(GtkWidget *widget) { return FALSE; } gint delete_event(GtkWidget *widget) { gtk_main_quit(); return 1; } /* при нажатии на левую кнопку мыши, проверяем, можем ли мы сдвинуться в каком-либо направлении (т.е. есть ли в окрестности 0) vector: 1 - влево 2 - вверх 3 - вправо 4 - вниз */ gboolean on_click(GtkWidget *Window, GdkEventButton *event, gpointer data) { int i,j; for(i=0; i<N; i++) { for(j=0; j<N; j++) { if(x_mouse > j*R && x_mouse < (j+1)*R && y_mouse > i*R && y_mouse < (i+1)*R) { x1 = j*R; y1 = i*R; I = i; J = j; } } } vector = 0; if(I == 0 || J == 0 || I == N-1 || J == N-1)//если часть пазла находится у границы окна(слева, сверху,справа,снизу) { if(I == 0 && J == 0)//левый верхний { if(a[I][J+1] == 0) vector = 3;//если правый пустой двигаемся вправо if(a[I+1][J] == 0) vector = 4;//если нижний пустой двигаемся вниз } else if(I == 0 && J == N-1) { if(a[I][J-1] == 0) vector = 1; if(a[I+1][J] == 0) vector = 4; } else if(I == N-1 && J == 0) { if(a[I-1][J] == 0) vector = 2; if(a[I][J+1] == 0) vector = 3; } else if(I == N-1 && J == N-1) { if(a[I-1][J] == 0) vector = 2; if(a[I][J-1] == 0) vector = 1; } else if(I == 0) { if(a[I][J-1] == 0) vector = 1; if(a[I+1][J] == 0) vector = 4; if(a[I][J+1] == 0) vector = 3; } else if(I == N-1) { if(a[I-1][J] == 0) vector = 2; if(a[I][J-1] == 0) vector = 1; if(a[I][J+1] == 0) vector = 3; } else if(J == 0) { if(a[I+1][J] == 0) vector = 4; if(a[I-1][J] == 0) vector = 2; if(a[I][J+1] == 0) vector = 3; } else if(J == N-1) { if(a[I-1][J] == 0) vector = 2; if(a[I+1][J] == 0) vector = 4; if(a[I][J-1] == 0) vector = 1; } } else { if(a[I][J-1] == 0) vector = 1; if(a[I-1][J] == 0) vector = 2; if(a[I][J+1] == 0) vector = 3; if(a[I+1][J] == 0) vector = 4; } g_timeout_add(20,(GSourceFunc)time_wind,(gpointer)window); return TRUE; } /* После того, как мы сделали случайную перестановку элементов (при нажатии клавишы 'r', нам нужно вывести на экран результат) */ gboolean boolstart(GtkWidget *widget) { int i,j; for(i=0; i<N; i++) { for(j=0; j<N; j++) { if(a[i][j] == 1) gdk_draw_picture(st1,j*R,i*R); else if(a[i][j] == 2) gdk_draw_picture(st2,j*R,i*R); else if(a[i][j] == 3) gdk_draw_picture(st3,j*R,i*R); else if(a[i][j] == 4) gdk_draw_picture(st4,j*R,i*R); else if(a[i][j] == 5) gdk_draw_picture(st5,j*R,i*R); else if(a[i][j] == 6) gdk_draw_picture(st6,j*R,i*R); else if(a[i][j] == 7) gdk_draw_picture(st7,j*R,i*R); else if(a[i][j] == 8) gdk_draw_picture(st8,j*R,i*R); else if(a[i][j] == 9) gdk_draw_picture(st9,j*R,i*R); else if(a[i][j] == 10) gdk_draw_picture(st10,j*R,i*R); else if(a[i][j] == 11) gdk_draw_picture(st11,j*R,i*R); else if(a[i][j] == 12) gdk_draw_picture(st12,j*R,i*R); else if(a[i][j] == 13) gdk_draw_picture(st13,j*R,i*R); else if(a[i][j] == 14) gdk_draw_picture(st14,j*R,i*R); else if(a[i][j] == 15) gdk_draw_picture(st15,j*R,i*R); else if(a[i][j] == 0) gdk_draw_picture(st16,j*R,i*R); } } return TRUE; } gboolean apis(GtkWidget *widget, GdkEventExpose *event, gpointer data)//прорисовка полной картинки на втором окне { gc1 = widget->style->fg_gc[GTK_WIDGET_STATE(widget)]; w1 = widget->window; gdk_draw_pixbuf(w1,gc1,s,0,0,0,0,WIDTH,HEIGHT,GDK_RGB_DITHER_NONE,0,0); return TRUE; } /* Создаем изображение начального состояния и задаем начальные элементы (цвета, надписи и т.п.) */ gboolean on_draw(GtkWidget *widget,GdkEventExpose *event, gpointer data) { int i, j, XX1, YY1, XX2, YY2,k; XX1 = YY1 = 0; XX2 = WIDTH; YY2 = HEIGHT; gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)]; w = widget->window; for(i=0,k=1; i<N; i++) { for(j=0; j<N; j++) { if(k == 1) gdk_draw_picture(st1,j*R,i*R); else if(k == 2) gdk_draw_picture(st2,j*R,i*R); else if(k == 3) gdk_draw_picture(st3,j*R,i*R); else if(k == 4) gdk_draw_picture(st4,j*R,i*R); else if(k == 5) gdk_draw_picture(st5,j*R,i*R); else if(k == 6) gdk_draw_picture(st6,j*R,i*R); else if(k == 7) gdk_draw_picture(st7,j*R,i*R); else if(k == 8) gdk_draw_picture(st8,j*R,i*R); else if(k == 9) gdk_draw_picture(st9,j*R,i*R); else if(k == 10) gdk_draw_picture(st10,j*R,i*R); else if(k == 11) gdk_draw_picture(st11,j*R,i*R); else if(k == 12) gdk_draw_picture(st12,j*R,i*R); else if(k == 13) gdk_draw_picture(st13,j*R,i*R); else if(k == 14) gdk_draw_picture(st14,j*R,i*R); else if(k == 15) gdk_draw_picture(st15,j*R,i*R); else if(k == 0) gdk_draw_picture(st16,j*R,i*R); k++; } } return TRUE; } /* Перемещение квадратика в направлении найденного вектора (после обработки события: click) */ gboolean time_wind(GtkWidget *widget) { int xx1,yy1; if(vector == 1)//влево { xx1 = x1 - R; yy1 = y1; if(a[I][J] == 1) t = st1; else if(a[I][J] == 2) t = st2; else if(a[I][J] == 3) t = st3; else if(a[I][J] == 4) t = st4; else if(a[I][J] == 5) t = st5; else if(a[I][J] == 6) t = st6; else if(a[I][J] == 7) t = st7; else if(a[I][J] == 8) t = st8; else if(a[I][J] == 9) t = st9; else if(a[I][J] == 10) t = st10; else if(a[I][J] == 11) t = st11; else if(a[I][J] == 12) t = st12; else if(a[I][J] == 13) t = st13; else if(a[I][J] == 14) t = st14; else if(a[I][J] == 15) t = st15; gdk_draw_picture(st16,x1,y1); gdk_draw_picture(t,xx1,yy1); a[I][J-1] = a[I][J]; a[I][J] = 0; } else if(vector == 2)//вверх { xx1 = x1; yy1 = y1 - R; if(a[I][J] == 1) t = st1; else if(a[I][J] == 2) t = st2; else if(a[I][J] == 3) t = st3; else if(a[I][J] == 4) t = st4; else if(a[I][J] == 5) t = st5; else if(a[I][J] == 6) t = st6; else if(a[I][J] == 7) t = st7; else if(a[I][J] == 8) t = st8; else if(a[I][J] == 9) t = st9; else if(a[I][J] == 10) t = st10; else if(a[I][J] == 11) t = st11; else if(a[I][J] == 12) t = st12; else if(a[I][J] == 13) t = st13; else if(a[I][J] == 14) t = st14; else if(a[I][J] == 15) t = st15; gdk_draw_picture(st16,x1,y1); gdk_draw_picture(t,xx1,yy1); a[I-1][J] = a[I][J]; a[I][J] = 0; } else if(vector == 3)//вправо { xx1 = x1 + R; yy1 = y1; if(a[I][J] == 1) t = st1; else if(a[I][J] == 2) t = st2; else if(a[I][J] == 3) t = st3; else if(a[I][J] == 4) t = st4; else if(a[I][J] == 5) t = st5; else if(a[I][J] == 6) t = st6; else if(a[I][J] == 7) t = st7; else if(a[I][J] == 8) t = st8; else if(a[I][J] == 9) t = st9; else if(a[I][J] == 10) t = st10; else if(a[I][J] == 11) t = st11; else if(a[I][J] == 12) t = st12; else if(a[I][J] == 13) t = st13; else if(a[I][J] == 14) t = st14; else if(a[I][J] == 15) t = st15; gdk_draw_picture(t,xx1,yy1); gdk_draw_picture(st16,x1,y1); a[I][J+1] = a[I][J]; a[I][J] = 0; } else if(vector == 4)//вниз { xx1 = x1; yy1 = y1 + R; if(a[I][J] == 1) t = st1; else if(a[I][J] == 2) t = st2; else if(a[I][J] == 3) t = st3; else if(a[I][J] == 4) t = st4; else if(a[I][J] == 5) t = st5; else if(a[I][J] == 6) t = st6; else if(a[I][J] == 7) t = st7; else if(a[I][J] == 8) t = st8; else if(a[I][J] == 9) t = st9; else if(a[I][J] == 10) t = st10; else if(a[I][J] == 11) t = st11; else if(a[I][J] == 12) t = st12; else if(a[I][J] == 13) t = st13; else if(a[I][J] == 14) t = st14; else if(a[I][J] == 15) t = st15; gdk_draw_picture(t,xx1,yy1); gdk_draw_picture(st16,x1,y1); a[I+1][J] = a[I][J]; a[I][J] = 0; } return FALSE; }
Ключевые слова:
игра, пазл
|
|||||||