Anch'io ho un progetto di fine corso per programmazione 1; devo implementare il famigerato giochino Ruzzle... Per l'interfaccia userò le librerie grafiche Gtk+.
codice:
//ruzzle.c
typedef char * Str;
typedef struct { int x; int y; } Pos;
typedef struct
{
Str car;
Pos pos; //posizione nel quadrante
int ord; //ordine di lettura
}
Character
;
/*
* funzioni di utilità generale
*
*/
Str str_new( int nchar )
{
return (Str) calloc( nchar, sizeof(char))
;
}
/*
* genera un caratere casuale tra a e z esluse le
* lettere straniere.
*
*/
char *rand_character()
{
char * c = calloc( 2, sizeof(char));
c[0] = 'a' + rand() % ('z'-'a');
if(c[0] == ('w'||'k'||'j'||'y'||'x'))
c = rand_character()
;
c[1] = '\0';
return c;
}
codice:
//grafica.c
#include <gtk/gtk.h>
#include<stdlib.h>
#include<time.h>
#include"ruzzle.c"
/*
* record per il passaggio di parametri alle funzioni sincronizzate ad'eventi
*
*/
typedef struct
{
GtkWidget * widget;
Character data;
}
Parametri
;
/*
* I toggle button sono dei pulsanti che rimangono premuti a meno di nuovo clik
* emmetono due segnali, quello di active quando sono premuti, altrimenti... bla bla bla
*
*/
void func( Parametri * pp ){
if (GTK_TOGGLE_BUTTON (pp->widget)->active)
{
printf("%s",(pp->data).car);
} else {
/* If control reaches here, the toggle button is up */
}
}
int main (int argc, char *argv[])
{
GtkWidget *window, *table, *button;
int rows, cols;
gtk_init (&argc, &argv);
/*
* main window
*
*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Ruzzle");
gtk_container_set_border_width (GTK_CONTAINER (window), 9);
/*
* tabl è la tabella che conterrà tutti i toggle button del quadrante
*
*/
table = gtk_table_new (4, 4, TRUE);
/*
* poniamo la tabella nella finestra principale
*
*/
gtk_container_add (GTK_CONTAINER (window), table);
Parametri pp;
Character qdt[4][4]; //quadrante
srand(time(NULL));
/*
* inizializiamo il quadrante con valori aleatori
*
*/
for ( rows = 0; rows < 4; rows++ )
for ( cols = 0; cols < 4; cols++ )
qdt[rows][cols].car = rand_character()
;
for ( rows = 0; rows < 4; rows++ ) {
for ( cols = 0; cols < 4; cols++ )
{
/*
* creazione dei button con etichete il quadrante
* dopodiche li aggiungiamo alla tabella precreata.
*
*/
button = gtk_toggle_button_new_with_label(qdt[rows][cols].car);
gtk_table_attach (GTK_TABLE (table), button, cols, cols + 1,
rows, rows + 1, GTK_FILL | GTK_EXPAND,
GTK_FILL | GTK_EXPAND, 0, 0);
/*
* parametri per func
*
*/
pp.widget=button;
pp.data.car = str_new();
pp.data = qdt[rows][cols];
/*
* connessione della funzione ai pulsanti
*
*/
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (func), &pp);
}
}
gtk_widget_show_all (window);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
gtk_main ();
return 0;
}
Compilo con
codice:
cc grafica.c -o ruzzle `pkg-config --cflags --libs gtk+-2.0`
Alla pressione di un pulsante, il programma dovrebbe stampare sul terminale il carattere corrispondente, ma in realtà mi stampa quest'errore,
codice:
(grafica:3540): GLib-GObject-WARNING **: invalid uninstantiatable type `guchar' in cast to `GtkToggleButton'
Qualche dritta?