/* Tile 20000117 by Joe Wingbermuehle */ #include #include #include /* Functions */ void ButtonClicked(GtkWidget*,gpointer); int CheckButton(int,int); void CheckGameOver(void); void StartGame(int); void SetButton(int,int); int GetButton(int); void NewGame(GtkWidget*,gpointer); void SetSize3(GtkWidget*,gpointer); void SetSize4(GtkWidget*,gpointer); void SetSize5(GtkWidget*,gpointer); void CreateButtons(void); void About(void); void GameOver(void); int IsPossible(void); void DestroyMessage(GtkWidget*,gpointer); void RemoveMessageGrab(GtkWidget*,gpointer); /* The menus */ static GtkItemFactoryEntry menuItems[]= { { "/ゲーム(_G)", NULL, NULL, 0, "" }, { "/ゲーム(_G)/新ゲーム(_N)", "N", NewGame, 0, NULL }, { "/終了(_x)", "X", gtk_main_quit, 0, NULL }, { "/サイズ(_S)", NULL, NULL, 0, "" }, { "/サイズ(_S)/ _3 ", NULL, SetSize3, 0, NULL }, { "/サイズ(_S)/ _4 ", NULL, SetSize4, 0, NULL }, { "/サイズ(_S)/ _5 ", NULL, SetSize5, 0, NULL }, { "/ヘルプ(_H)", NULL, NULL, 0, "" }, { "/ヘルプ(_H)/バージョン情報(_A)", NULL, About, 0, NULL }}; gint menuSize=sizeof(menuItems)/sizeof(menuItems[0]); /* Gobal variables */ GtkWidget *barray[5*5],*table,*box,*window; int boardsize; const int TIMES_TO_SCRAMBLE=100; /* main */ int main(int argc, char *argv[]) { GtkWidget *menubar; GtkItemFactory *menu; GtkAccelGroup *accelGroup; gtk_init(&argc, &argv); /* Create window */ window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Tile タイルゲーム"); box=gtk_vbox_new(FALSE,1); gtk_container_border_width(GTK_CONTAINER(box),1); gtk_container_add(GTK_CONTAINER(window),box); gtk_widget_show(box); accelGroup=gtk_accel_group_new(); menu=gtk_item_factory_new(GTK_TYPE_MENU_BAR,"
",accelGroup); gtk_item_factory_create_items(menu,menuSize,menuItems,NULL); gtk_window_add_accel_group(GTK_WINDOW(window),accelGroup); menubar=gtk_item_factory_get_widget(menu,"
"); gtk_box_pack_start(GTK_BOX(box),menubar,FALSE,TRUE,0); gtk_widget_show(menubar); gtk_signal_connect_object(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(gtk_main_quit), NULL); gtk_container_set_border_width(GTK_CONTAINER(window), 1); StartGame(0); gtk_widget_show(window); gtk_main(); return(0); } /* main */ /* Check if the puzzle is possible */ int IsPossible(void) { int x,y; int inversions=0; int values[boardsize*boardsize]; for(y=x=0;xaction_area),button,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),message,TRUE,TRUE,0); gtk_widget_show(message); gtk_widget_show(button); gtk_widget_show(dialog); gtk_grab_add(dialog); } void DestroyMessage(GtkWidget *widget,gpointer data) { GtkWidget *dialog=(GtkWidget*)(data); RemoveMessageGrab(dialog,0); gtk_widget_destroy(dialog); } void RemoveMessageGrab(GtkWidget *dialog,gpointer data) { gtk_grab_remove(dialog); } /* Display the about box */ void About(void) { DisplayMessage("Tile 20000915\nby Joe Wingbermuehle"); } /* About */ /* Display game over message */ void GameOver(void) { DisplayMessage(" あなたの勝ち! "); } /* GameOver */ /* Draw the buttons */ void CreateButtons(void) { int x,y; char name[]=" "; if(boardsize) { gtk_widget_destroy(table); } else { boardsize=3; } table=gtk_table_new(boardsize,boardsize,TRUE); gtk_container_add(GTK_CONTAINER(box),table); for(x=0;xchild),&old); for(index=0;;index++) { gtk_label_get((GtkLabel*)(GTK_BIN(barray[index])->child),¤t); if(old[2]==current[2] && old[3]==current[3]) break; } /* If not on left, check left */ if(index%boardsize) { if(CheckButton(index,index-1)) return; } /* If not on right, check right */ if(index%boardsize < boardsize-1) { if(CheckButton(index,index+1)) return; } /* If not on the top, check top */ if(index/boardsize) { if(CheckButton(index,index-boardsize)) return; } /* If not on the bottom, check bottom */ if(index/boardsize < boardsize-1) { if(CheckButton(index,index+boardsize)) return; } } /* ButtonClicked */ /* Check if a button is near an empty button, swap if so */ int CheckButton(int a, int b) { /* IN: a=selected button, b=button to check */ /* OUT: returns 1 if empty button found and swaps the buttons */ int first, second; first=GetButton(a); second=GetButton(b); if(!second) { SetButton(a,second); SetButton(b,first); CheckGameOver(); return(1); } return(0); } /* CheckButton */ /* Check if game over */ void CheckGameOver(void) { int index; for(index=1;index9) { text[2]=value/10+'0'; text[3]=value%10+'0'; } else { if(value) text[3]=value+'0'; } gtk_label_set_text((GtkLabel*)(GTK_BIN(barray[index])->child),text); } /* SetButton */ /* Get button text */ int GetButton(int index) { char *text,value; gtk_label_get((GtkLabel*)(GTK_BIN(barray[index])->child),&text); if(text[2]==' ') if(text[3]!=' ') value=text[3]-'0'; else value=0; else value=(text[2]-'0')*10+text[3]-'0'; return(value); } /* GetButton */