#include <stdio.h> #include <stdlib.h> #define N 25 void printBlocks(int blocks[][N], int n); void printPos(int pos[], int n); void push(int blocks[][N], int a, int p); void moveOnto(int blocks[][N], int pos[], int a, int b); void moveOver(int blocks[][N], int pos[], int a, int b); void pileOnto(int blocks[][N], int pos[], int a, int b); void pileOver(int blocks[][N], int pos[], int a, int b); int main () { int blocks[N][N]; int pos[N]; int n = 10; char com1[10]; char com2[10]; int a, b; int i, j, result; for (i=0; i<N; i++) { for (j=0; j<N; j++) { if (j==0) blocks[i][j] = i; else blocks[i][j] = -1; } pos[i] = i; } scanf("%d", &n); result = 1; while(result) { scanf("%s", com1); if(com1[0] == 'q') break; else { scanf("%d %s %d", &a, com2, &b); if (com1[0] == 'm' && com2[1] == 'n') /*printf("move %d onto %d\n", a, b);*/ moveOnto(blocks, pos, a, b); else if (com1[0] == 'm' && com2[1] == 'v') /*printf("move %d over %d\n", a, b);*/ moveOver(blocks, pos, a, b); else if (com1[0] == 'p' && com2[1] == 'n') /*printf("pile %d onto %d\n", a, b);*/ pileOnto(blocks, pos, a, b); else if (com1[0] == 'p' && com2[1] == 'v') /*printf("pile %d over %d\n", a, b);*/ pileOver(blocks, pos, a, b); else ; } } printBlocks(blocks, n); /* moveOnto(blocks, pos, 9, 1); printBlocks(blocks, n); moveOver(blocks, pos, 8, 1); printBlocks(blocks, n); moveOver(blocks, pos, 7, 1); printBlocks(blocks, n); moveOver(blocks, pos, 6, 1); printBlocks(blocks, n); pileOver(blocks, pos, 8, 6); printBlocks(blocks, n); pileOver(blocks, pos, 8, 5); printBlocks(blocks, n); moveOver(blocks, pos, 2, 1); printBlocks(blocks, n); moveOver(blocks, pos, 4, 9); printBlocks(blocks, n); */ return 0; } void printBlocks(int blocks[][N], int n) { int i, j; for (i=0; i<n; i++) { printf("%d:", i); for (j=0; j<n; j++) { if (blocks[i][j] < 0) { printf("\n"); break; } else printf(" %d", blocks[i][j]); } } } void printPos(int pos[], int n) { int i; printf("Positions: "); for (i=0; i<n; i++) printf("%d ", pos[i]); printf("\n"); } void push(int blocks[][N], int a, int p) { int i=0; while(blocks[p][i] >= 0) i++; blocks[p][i] = a; } void moveOnto(int blocks[][N], int pos[], int a, int b) { /*printf("Move block %d onto block %d\n", a, b);*/ if (a == b || pos[a] == pos[b]) ; else { /*first move blocks from on top of block "a"*/ int i=0, bl; while ( blocks[pos[a]][i] != a) i++; blocks[pos[a]][i] = -1; i++; bl = blocks[pos[a]][i]; while ( bl >= 0) { /*move these blocks back to original positions*/ push(blocks, bl, bl); blocks[pos[a]][i] = -1; /*update positions*/ pos[bl] = bl; i++; bl = blocks[pos[a]][i]; } /*now move the blocks on top of block "b"*/ i=0; while ( blocks[pos[b]][i] != b) i++; /*leave b where it is*/ i++; bl = blocks[pos[b]][i]; while ( bl >= 0) { /*move to original position*/ push(blocks, bl, bl); /*remove from current*/ blocks[pos[b]][i] = -1; pos[bl] = bl; i++; bl = blocks[pos[b]][i]; } /*now push a on to b*/ push(blocks, a, pos[b]); pos[a] = pos[b]; } } void moveOver(int blocks[][N], int pos[], int a, int b) { /*printf("Move block %d over block %d\n", a, b);*/ /*first move blocks from on top of block "a"*/ if (a == b || pos[a] == pos[b]) ; else { int i=0, bl; while ( blocks[pos[a]][i] != a) i++; blocks[pos[a]][i] = -1; i++; bl = blocks[pos[a]][i]; while ( bl >= 0) { /*move these blocks back to original positions*/ push(blocks, bl, bl); blocks[pos[a]][i] = -1; /*update positions*/ pos[bl] = bl; i++; bl = blocks[pos[a]][i]; } /*now push a on to b*/ push(blocks, a, pos[b]); pos[a] = pos[b]; } } void pileOnto(int blocks[][N], int pos[], int a, int b) { /*printf("Pile block %d onto block %d\n", a, b);*/ if (a == b || pos[a] == pos[b]) ; else { /*move the blocks on top of block "b"*/ int i=0, bl; while ( blocks[pos[b]][i] != b) i++; /*leave b where it is*/ i++; bl = blocks[pos[b]][i]; while (bl >= 0) { /*move to original position*/ push(blocks, bl, bl); /*remove from current*/ blocks[pos[b]][i] = -1; pos[bl] = bl; i++; bl = blocks[pos[b]][i]; } /*now move pile of a over*/ int start_pos_a = pos[a]; i=0; while ( blocks[start_pos_a][i] != a) i++; bl = blocks[start_pos_a][i]; while (bl >= 0) { /*move these blocks back to b*/ push(blocks, bl, pos[b]); blocks[start_pos_a][i] = -1; /*update positions*/ pos[bl] = pos[b]; i++; bl = blocks[start_pos_a][i]; } } } void pileOver(int blocks[][N], int pos[], int a, int b) { /*printf("Pile block %d over block %d\n", a, b);*/ int i=0, bl; if (a == b || pos[a] == pos[b]) ; else { /*move pile of a over*/ int start_pos_a = pos[a]; while ( blocks[start_pos_a][i] != a) i++; bl = blocks[start_pos_a][i]; while (bl >= 0) { /*move these blocks back to b*/ push(blocks, bl, pos[b]); blocks[start_pos_a][i] = -1; /*update positions*/ pos[bl] = pos[b]; i++; bl = blocks[start_pos_a][i]; } } }
Sunday, December 4, 2011
101 - The Blocks Problem - in C
Problem 101 - The Blocks Problem, from the UVa Online Judge. Not the most elegant but it works...
Sunday, September 25, 2011
Drawing a pixbuf with cairo
I wanted to be able to add an image to a drawing area and draw onto it with cairo. The standard way to draw an image with cairo is to use a surface, created for example with
cairo_image_surface_create_from_png
. This seems to limit you to various image formats, in my case the images I want to use are in a non-trivial format (BAS image plate scans) which I can get into pixbuf format. I'm not sure if this is the best solution, but I usedpixbuf = gdk_pixbuf_scale_simple (pixbuf, GDK_INTERP_BILINEAR); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr);where width and height are for the drawing area.
Tuesday, September 13, 2011
Gtk with Anjuta, first steps.
I've recently been trying out Gnome 3 after installing Fedora 15. I worked through the developer tutorials (Image viewer and the guitar tuner) for developing using Anjuta with Gtk. I remember from looking at a glade tutorial a few years ago, that a useful technique is to create a struct as a central store for widgets and other data, which can then be passed to every callback as user_data. So I thought I'd have a go...
After creating a project in Anjuta (using the simple Gtk option), I used the designer to add a button box and a few controls. I added a button, two range widgets and a label. The idea was just to test if I could set some values with the range widgets, then update the label when the button is clicked.
I then added a typedef struct called xy_t at the top of main.c which stores two values x and y, as well as a label widget.
After creating a project in Anjuta (using the simple Gtk option), I used the designer to add a button box and a few controls. I added a button, two range widgets and a label. The idea was just to test if I could set some values with the range widgets, then update the label when the button is clicked.
I then added a typedef struct called xy_t at the top of main.c which stores two values x and y, as well as a label widget.
#include <config.h> #include <gtk/gtk.h> typedef struct { int x, y; GtkWidget *label; } xy_t;At the top of the create_window function, create a struct of type xy_t called data:
xy_t *data; data = g_slice_new (xy_t); data->x = 0; data->y = 0;After loading the UI, we need to connect the label in the data struct with the label from the builder.
data->label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));Then pass the data structure to all the callback functions:
gtk_builder_connect_signals (builder, data);Then add a few callbacks (above the destroy callback). The range widgets update the values of x and y. When the button is clicked, it updates the label with the values of x and y.
void print_xy (GtkButton *button, gpointer user_data) { xy_t *point = user_data; int x = point->x; int y = point->y; printf("%d %d\n", x, y); char l[10]; sprintf(l, "%d %d", point->x, point->y); gtk_label_set_text (point->label, l); } void update_x (GtkRange *range, gpointer user_data) { xy_t *point = user_data; int val = gtk_range_get_value (range); point->x = val; printf("label %d\n", val); }Pretty pointless, but I just wanted to demonstrate to myself how to create a struct which can then be passed to all the callback functions. The struct can contain widgets which must be linked to the widgets created by the builder. It may not be the best way to do it, but it seems to work, and maybe useful for other novices like me for whom it isn't obvious.
Monday, September 12, 2011
Subscribe to:
Posts (Atom)