📄 game.c
字号:
/* */ remove_piece(app, from_x, from_y); /* */ app->game.CellStatus[to_x][to_y] = OCCUPIED; gnome_canvas_item_show(app->gui.PieceNormal[to_x][to_y]); if(from_x == to_x) {/* horizontal jump */ diff = from_y - to_y; if(diff == -2) diff = from_y + 1; else diff = from_y - 1; remove_piece(app, from_x, diff); } else {/* vertical jump */ diff = from_x - to_x; if(diff == -2) diff = from_x + 1; else diff= from_x - 1; remove_piece(app, diff, from_y); } }/** * valid_move: * @app: * @x: * @y: * * function description: * * return values: */voidplay(GoalApp *app, gint x, gint y){ /* * ok, i know that is a very bad idea and hard to maintain to manage the * game this way. the better idea was to react on signals, but when i started * to code i choose this way * * Maybe one day i reconvert it to signals. * */ /* check if app is running in board_event_cb */ if(app->game.FirstPieceRemoved) {/* ------------------------------->>>>>>>>>>>>>>>>> on this branch is the real game management */ if(app->game.JumpStarted) {/* we have select a piece, an would like jump now */ if(valid_move(app, app->game.JumpStartPosX, app->game.JumpStartPosY, x, y)) {/* great, this is an valid move */ make_move(app, app->game.JumpStartPosX, app->game.JumpStartPosY, x, y); gnome_canvas_item_set(app->gui.PieceTouched, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceTouched); } else {/* -------------------- failure !!!!!!!!!!!!!!!!!!!! -------------------- */ gnome_canvas_item_show(app->gui.PieceNormal[app->game.JumpStartPosX][app->game.JumpStartPosY]); if(app->game.CellStatus[x][y] == OCCUPIED) { gnome_canvas_item_set(app->gui.PieceTouched, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceTouched); } else { gnome_canvas_item_set(app->gui.PieceEmpty, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmpty); } } app->game.JumpStarted = FALSE; app->game.JumpStartPosX = 0; app->game.JumpStartPosY = 0; gnome_canvas_item_hide(app->gui.PieceMarked); gnome_canvas_item_hide(app->gui.PieceEmpty); } else {/* begin a new jump */ if(app->game.CellStatus[x][y] == OCCUPIED) {/* start jump but only if there is an piece */ app->game.JumpStarted = TRUE; app->game.JumpStartPosX = x; app->game.JumpStartPosY = y; gnome_canvas_item_set(app->gui.PieceMarked, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_hide(app->gui.PieceNormal[x][y]); gnome_canvas_item_show(app->gui.PieceMarked); gnome_canvas_item_hide(app->gui.PieceTouched); } } if(app->game.ShowBoardHints) { gnome_canvas_item_hide(app->gui.PieceNegativ); gnome_canvas_item_hide(app->gui.PieceEmptyPositiv); gnome_canvas_item_hide(app->gui.PieceEmptyNegativ); } } else {/* --------------------------------->>>>>>>>>>>>>>>>> only used for "solitaire" game type */ remove_piece(app, x, y); app->game.FirstPieceRemoved = TRUE; gnome_canvas_item_hide(app->gui.PieceTouched); gnome_canvas_item_set(app->gui.PieceEmpty, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmpty); } /* ------------------------------------------->>>>>>>>>>>>>>>>>>>>>> terminate the game <<<<<<<<<<<<<<<<<<<<<<<< ---------*/ if(!one_move_possible(app)) {/* no jump possible, finish this game */ g_print("game finished\n"); terminate_game(app); }}/** * show_board_hints: * @app: * @x: * @y: * * function description: * * return values: */void show_board_hints(GoalApp *app, gint x, gint y){ /* * ok, i know that is a very bad idea and hard to maintain to manage the * game this way. the better idea was to react on signals, but when i started * to code i choose this way * */ if((app->game.MovePosX == x) && (app->game.MovePosY == y)) return; if(app->game.FirstPieceRemoved) { if(app->game.JumpStarted) { if(app->game.ShowBoardHints) { gnome_canvas_item_hide(app->gui.PieceNegativ); gnome_canvas_item_hide(app->gui.PieceEmptyPositiv); gnome_canvas_item_hide(app->gui.PieceEmptyNegativ); } if((app->game.JumpStartPosX != x) || (app->game.JumpStartPosY != y)) {/* else do nothing */ /*g_print("##\n");*/ if(app->game.CellStatus[x][y] == OCCUPIED) { if(app->game.ShowBoardHints) { gnome_canvas_item_set(app->gui.PieceNegativ, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceNegativ); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("You can not jump on this field")); } else { gnome_canvas_item_set(app->gui.PieceTouched, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceTouched); gnome_canvas_item_hide(app->gui.PieceEmpty); gnome_appbar_clear_stack(GNOME_APPBAR(app->gui.Appbar)); } } else {/* or app->game.CellStatus[x][y] == EMPTY state */ if(valid_move(app, app->game.JumpStartPosX, app->game.JumpStartPosY, x, y)) { if(app->game.ShowBoardHints) { gnome_canvas_item_set(app->gui.PieceEmptyPositiv, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmptyPositiv); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("Click on this this field to jump")); } else { gnome_canvas_item_hide(app->gui.PieceTouched); gnome_canvas_item_set(app->gui.PieceEmpty, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmpty); gnome_appbar_clear_stack(GNOME_APPBAR(app->gui.Appbar)); } } else { if(app->game.ShowBoardHints) { gnome_canvas_item_set(app->gui.PieceEmptyNegativ, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmptyNegativ); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("You can not jump on this field")); } else { gnome_canvas_item_hide(app->gui.PieceTouched); gnome_canvas_item_set(app->gui.PieceEmpty, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmpty); gnome_appbar_clear_stack(GNOME_APPBAR(app->gui.Appbar)); } } } } } else {/* app->game.JumpStarted */ if(app->game.CellStatus[x][y] == OCCUPIED) { gnome_canvas_item_set(app->gui.PieceTouched, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceTouched); gnome_canvas_item_hide(app->gui.PieceEmpty); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("Click on this gaming piece to mark it")); } else { gnome_canvas_item_set(app->gui.PieceEmpty, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceEmpty); gnome_canvas_item_hide(app->gui.PieceTouched); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("Empty field")); } } } else {/* app->game.FirstPieceRemoved */ gnome_canvas_item_set(app->gui.PieceTouched, "x", (double)(x * app->gui.PieceWidth), "y", (double)(y * app->gui.PieceHeight), NULL); gnome_canvas_item_show(app->gui.PieceTouched); gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar),_("Click on a gaming piece to remove it")); } /* store x and y */ app->game.MovePosX = x; app->game.MovePosY = y;}/** * terminate_game: * @app: * * function description: * * return values: nothing */void terminate_game(GoalApp *app){ gint number_of_pieces; gchar *msg; gint ret; app->game.GameIsRunning = FALSE; app->game.JumpStarted = FALSE; app->game.FirstPieceRemoved = FALSE; /* get the number of pieces */ number_of_pieces = count_pieces(app); /* build the message string */ if(number_of_pieces == 1) if(app->game.GameType == SOLITAIRE) msg = g_strdup_printf(_("Game finished.\nYou left %i piece on the board.\nYou are a Solitaire champion!\nStart a new game?"), number_of_pieces); else msg = g_strdup_printf(_("Game finished.\nYou left %i piece on the board.\nStart a new game?"), number_of_pieces); else msg = g_strdup_printf(_("Game finished.\nYou left %i pieces on the board.\nStart a new game?"), number_of_pieces); app->gui.GameFinishedMsgBox = gnome_message_box_new(msg, GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL); g_free(msg); gtk_widget_show(app->gui.GameFinishedMsgBox); gtk_window_set_modal(GTK_WINDOW(app->gui.GameFinishedMsgBox), TRUE); ret = gnome_dialog_run(GNOME_DIALOG(app->gui.GameFinishedMsgBox)); switch (ret) { case 0 : /* YES button pressed */ init_new_game(app); app->game.GameIsRunning = TRUE; app->game.JumpStarted = FALSE; if(app->game.GameType == SOLITAIRE) app->game.FirstPieceRemoved = FALSE; else app->game.FirstPieceRemoved = TRUE; /* set text to appbar */ gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar), _("New game started.")); break; case 1 : /* NO button pressed */ break; default: /* dialog closed by window manager */ break; }}/** * count_pieces: * @app: * * function description: * * return values: number of pieces which at the moment on the board */gint count_pieces(GoalApp *app){ gint x, y, z; z = 0; for(x = 0; x < NUMBER_CELLS; x++) { for(y = 0; y < NUMBER_CELLS; y++) { if(app->game.CellStatus[x][y] == OCCUPIED) z++; } } return z;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -