⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpegsol.c

📁 JavaScript 计数器的游戏。要运行这个游戏
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   GNOME Peg Solitaire: The Peg Solitaire game for GNOME. *   Copyright (C) 2001, 2002 Andreas T. Hagli <ahagli@online.no> *  *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <math.h> /* For sin() and cos().  */#include <config.h>#include <gnome.h>/* Uncomment the next line to enable icon.  *//* #define GPEGSOL_ICON */#ifdef GPEGSOL_ICON#include <libgnomeui/gnome-window-icon.h>#ifndef GNOME_ICONDIR#define GNOME_ICONDIR "/usr/share/pixmaps"#endif#endif#define GPEGSOL_VERSION "0.3"#define MAX_WIN_SIZE 800#define MIN_WIN_SIZE 200#define CELL_SIZE 32.0#define STILL_PEG_SIZE 18.4#define MOVING_PEG_SIZE 25.8#define PREVIEW_CELL_SIZE 16#define MAX_BOARD_SIZE 10#define N_GAMETYPES 17#define S_N_GAMETYPES "17" /* Needed for output.  */static GnomeApp* app;static GnomeCanvas* canvas;static GnomeCanvasGroup* board_group;static GnomeCanvasGroup* peg_group[MAX_BOARD_SIZE][MAX_BOARD_SIZE];enum game_types { CROSS, PLUS, FIREPLACE, UP_ARROW, PYRAMID, DIAMOND,		  CROSSBOW, LONGBOW, SOLITARE,		  FRENSH, SQUARE, DRAUGHTSBOARD, THE_X,		  BIG_DIAMOND, TRIANGULAR, HEXAGONAL, STELLAR };enum sounds { PICK_UP, DROP_VALID, YOU_WIN, YOU_LOSE };static struct board_cell {  double indent;  gboolean hole;  gboolean peg;} board[MAX_BOARD_SIZE][MAX_BOARD_SIZE];static gboolean hex_struct;static int board_size;static int sel_peg_x=-1, sel_peg_y=-1;static int undo_vars[MAX_BOARD_SIZE*MAX_BOARD_SIZE][4]; /* Four values for each move.  */static int moves = 0;static int undo_count = 0;static enum game_types game_type;static gboolean sound;static int win_size;static gboolean restored = FALSE;/* For preferences.  */static GtkWidget *pref_dialog;static GtkWidget *preview;static gboolean pref_sound;static enum game_types pref_game_type;static int pref_board_size;static struct board_cell pref_board[MAX_BOARD_SIZE][MAX_BOARD_SIZE];static int session_xpos = -1;static int session_ypos = -1;static int session_game_type = -1;static int session_win_size = -1;static int session_sound = -1;static voidplay_sound (enum sounds sound_id){  if (!sound)    return;  switch (sound_id)    {    case PICK_UP:      gnome_triggers_do (NULL, NULL, "gpegsol", "pick-up", NULL);      break;    case DROP_VALID:      gnome_triggers_do (NULL, NULL, "gpegsol", "drop", NULL);      break;    case YOU_WIN:      gnome_triggers_do (NULL, NULL, "gpegsol", "you-win", NULL);      break;    case YOU_LOSE:      gnome_triggers_do (NULL, NULL, "gpegsol", "you-lose", NULL);      break;    default:      break;    }}/* scale_peg: Moves the pegcenter to (0,0) scales it and moves it back.  */static voidscale_peg (GnomeCanvasItem *peg, int x, int y, double value){  double affine1[6];  double affine2[6];  double x1, x2, y1, y2;  gnome_canvas_item_get_bounds (peg, &x1, &y1, &x2, &y2);  art_affine_translate (affine1, -x1, -y1);  art_affine_scale (affine2, value, value);  art_affine_multiply (affine1, affine1, affine2);  art_affine_translate (affine2, x1 + (1-value)*(x2-x1)/2,			y1 + (1-value)*(y2-y1)/2);  art_affine_multiply (affine1, affine1, affine2);  gnome_canvas_item_affine_relative (peg, affine1);}static voidpick_up_peg (int x, int y){  if (board[x][y].peg)    {      sel_peg_x = x;      sel_peg_y = y;      play_sound (PICK_UP);    }  else    sel_peg_x = -1;}/* get_indent: Returns the needed indent value to create six-sided board.  */static gbooleanget_indent (int y){  if (!hex_struct)    return FALSE;  if ((board_size/2)*2 == board_size && (y/2)*2 == y)    return TRUE;  else if ((board_size/2)*2 != board_size && (y/2)*2 != y)    return TRUE;  else    return FALSE;}static intcount_pegs (void){  int n = 0;  int x, y;  for (x = 0; x < board_size; x++)    for (y = 0; y < board_size; y++)      if (board[x][y].peg)	n++;  return n;}static voidgame_over (void){  char msg[80];  int pegs;  if ((pegs = count_pegs ()) == 1)    {      play_sound (YOU_WIN);      sprintf (msg, _("Congratulations! You made it!"));    }  else    {      play_sound (YOU_LOSE);      sprintf (msg, _("Sorry, you had %d pegs left."), pegs);    }  gnome_app_flash (GNOME_APP(app), msg);}/* check_game_over: Returns false is finds a valid move. True otherwise.  */static gbooleancheck_game_over (void){  int x, y;  for (x = 0; x < board_size; x++)    for (y = 0; y < board_size; y++)      {	if (!hex_struct &&	    ((x < board_size-2 && board[x+2][y].hole &&	      board[x][y].peg && board[x+1][y].peg && !board[x+2][y].peg) ||	     (x >= 2 && board[x-2][y].hole &&	      board[x][y].peg && board[x-1][y].peg && !board[x-2][y].peg) ||	     (y < board_size-2 && board[x][y+2].hole &&	      board[x][y].peg && board[x][y+1].peg && !board[x][y+2].peg) ||	     (y >= 2 && board[x][y-2].hole &&	      board[x][y].peg && board[x][y-1].peg && !board[x][y-2].peg)))	  return FALSE;	else if (hex_struct &&	    ((x+2 <= board_size && board[x+2][y].hole &&	      board[x][y].peg && board[x+1][y].peg && !board[x+2][y].peg) ||	     (x-2 > 0 && board[x-2][y].hole &&	      board[x][y].peg && board[x-1][y].peg && !board[x-2][y].peg) ||	     (y+2 <= board_size && x-1 > 0 && board[x-1][y+2].hole &&	      board[x][y].peg && board[x][y+1].peg && !board[x-1][y+2].peg &&	      get_indent (y)) ||	     (y+2 <= board_size && x+1 <= board_size && board[x+1][y+2].hole &&	      board[x][y].peg && board[x+1][y+1].peg && !board[x+1][y+2].peg &&	      get_indent (y)) ||	     (y-2 > 0 && x-1 > 0 && board[x-1][y-2].hole &&	      board[x][y].peg && board[x][y-1].peg && !board[x-1][y-2].peg &&	      get_indent (y)) ||	     (y-2 > 0 && x+1 <= board_size && board[x+1][y-2].hole &&	      board[x][y].peg && board[x+1][y-1].peg && !board[x+1][y-2].peg &&	      get_indent (y)) ||	     (y+2 <= board_size && board[x-1][y+2].hole &&	      board[x][y].peg && board[x-1][y+1].peg && !board[x-1][y+2].peg &&	      !get_indent (y)) ||	     (y+2 <= board_size && board[x+1][y+2].hole &&	      board[x][y].peg && board[x][y+1].peg && !board[x+1][y+2].peg &&	      !get_indent (y)) ||	     (y-2 > 0 && x-1 > 0 && board[x-1][y-2].hole &&	      board[x][y].peg && board[x-1][y-1].peg && !board[x-1][y-2].peg &&	      !get_indent (y)) ||	     (y-2 > 0 && x+1 <= board_size && board[x+1][y-2].hole &&	      board[x][y].peg && board[x][y-1].peg && !board[x+1][y-2].peg &&	      !get_indent (y))))	  return FALSE;      }  return TRUE;}static voidremove_peg (int x, int y){  board[x][y].peg = FALSE;  gnome_canvas_item_hide (GNOME_CANVAS_ITEM(peg_group[x][y]));}static voidrestore_peg (int x, int y){  board[x][y].peg = TRUE;  gnome_canvas_item_show (GNOME_CANVAS_ITEM(peg_group[x][y]));}/* drop_peg: Drops the peg if valid move. If not, returns peg.  */static voiddrop_peg (int x, int y){  gboolean valid = FALSE;  if (!board[x][y].peg && board[x][y].hole)    {      if (!hex_struct &&	  sel_peg_x == x && sel_peg_y == (y-2) &&	  board[x][(y-1)].peg)	{	  remove_peg (sel_peg_x, sel_peg_y);	  remove_peg (sel_peg_x, sel_peg_y+1);	  restore_peg (x, y);	  valid = TRUE;	}      else if (!hex_struct &&	       sel_peg_x == x && sel_peg_y == y+2 &&	       board[x][y+1].peg)	{	  remove_peg (sel_peg_x, sel_peg_y);	  remove_peg (sel_peg_x, sel_peg_y-1);	  restore_peg (x, y);	  valid = TRUE;	}      else if (hex_struct &&	       sel_peg_x == x+1 && sel_peg_y == y-2)	{	  if (!get_indent (y) && board[x][y-1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x-1, sel_peg_y+1);	      restore_peg (x, y);	      valid = TRUE;	    }	  else if (board[x+1][y-1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x, sel_peg_y+1);	      restore_peg (x, y);	      valid = TRUE;	    }	}      else if (hex_struct &&	       sel_peg_x == x-1 && sel_peg_y == y-2)	{	  if (!get_indent (y) && board[x-1][y-1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x, sel_peg_y+1);	      restore_peg (x, y);	      valid = TRUE;	    }	  else if (board[x][y-1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x+1, sel_peg_y+1);	      restore_peg (x, y);	      valid = TRUE;	    }	}      else if (hex_struct &&	       sel_peg_x == x+1 && sel_peg_y == y+2)	{	  if (!get_indent (y) && board[x][y+1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x-1, sel_peg_y-1);	      restore_peg (x, y);	      valid = TRUE;	    }	  else if (board[x+1][y+1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x, sel_peg_y-1);	      restore_peg (x, y);	      valid = TRUE;	    }	}      else if (hex_struct &&	       sel_peg_x == x-1 && sel_peg_y == y+2)	{	  if (!get_indent (y) && board[x-1][y+1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x, sel_peg_y-1);	      restore_peg (x, y);	      valid = TRUE;	    }	  else if (board[x][y+1].peg)	    {	      remove_peg (sel_peg_x, sel_peg_y);	      remove_peg (sel_peg_x+1, sel_peg_y-1);	      restore_peg (x, y);	      valid = TRUE;	    }	}      /* Here it does not matter if it is hex structure or not.  */      else if (sel_peg_x == x-2 && sel_peg_y == y && board[x-1][y].peg)	{	  remove_peg (sel_peg_x, sel_peg_y);	  remove_peg (sel_peg_x+1, sel_peg_y);	  restore_peg (x, y);	  valid = TRUE;	}      else if (sel_peg_x == x+2 && sel_peg_y == y && board[x+1][y].peg)	{	  remove_peg (sel_peg_x, sel_peg_y);	  remove_peg (sel_peg_x-1, sel_peg_y);	  restore_peg (x, y);	  valid = TRUE;	}      if (valid)	{	  if (undo_count != 0)	    undo_count = 0;	  undo_vars[moves][0] = sel_peg_x;	  undo_vars[moves][1] = sel_peg_y;	  undo_vars[moves][2] = x;	  undo_vars[moves][3] = y;	  moves++;	  play_sound (DROP_VALID);	  if (check_game_over ())	    game_over ();	}      else	restore_peg (sel_peg_x, sel_peg_y);      sel_peg_x = -1;      sel_peg_y = -1;    }}/* resize_event: Resize the canvas if the window is resized.  */static gintresize_event (GtkWidget *widget, GtkAllocation *allocation, void *d){  double factor;  int dominant;  dominant = allocation->height < allocation->width ?     allocation->height : allocation->width;  win_size = dominant;  factor = win_size / CELL_SIZE / board_size / 1.15;  gnome_canvas_set_pixels_per_unit (canvas, factor);  return TRUE;}/* item_event: Handles picking up, dropping and moving of a peg.  */static gintitem_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data){  GdkCursor *fleur;  static gboolean dragging;  static double org_x, org_y;  static double x, y;  double item_x, item_y;  double new_x, new_y;  item_x = event->button.x;  item_y = event->button.y;  gnome_canvas_item_w2i (item->parent, &item_x, &item_y);  switch (event->type)     {    case GDK_BUTTON_PRESS:      if (event->button.button == 1)	{	  if (check_game_over ())	    return FALSE;	  fleur = gdk_cursor_new (GDK_FLEUR);	  gnome_canvas_item_grab (item,				  GDK_POINTER_MOTION_MASK | 				  GDK_BUTTON_RELEASE_MASK,				  fleur,				  event->button.time);	  gdk_cursor_destroy (fleur);	  x = event->button.x;	  y = event->button.y;	  org_x = x - (int)(x + board[(int)(x/CELL_SIZE)][(int)(y/CELL_SIZE)].indent)%(int)CELL_SIZE;	  org_y = y - (int)y%(int)CELL_SIZE;	  dragging = TRUE;	  pick_up_peg ((x-get_indent(y/CELL_SIZE)*CELL_SIZE/2)/CELL_SIZE,		       y/CELL_SIZE);	  gnome_canvas_item_raise_to_top (item);	  gnome_canvas_item_move (item,				  x - org_x - CELL_SIZE/2,				  y - org_y - CELL_SIZE/2);	  scale_peg (item, x, y, (MOVING_PEG_SIZE/STILL_PEG_SIZE));	}    case GDK_MOTION_NOTIFY:      if (dragging && (event->motion.state & GDK_BUTTON1_MASK))         {	  int bx, by;          new_x = event->button.x;          new_y = event->button.y;	  by = (int)(new_y/CELL_SIZE);	  bx = (int)((new_x-(CELL_SIZE/2)*get_indent(by))/CELL_SIZE);	  /* If a peg is dragged over a possible move, it will signalize that by  temporarily moving it to that hole.  */	  if (board[bx][by].hole && !board[bx][by].peg &&	      ((bx == sel_peg_x && by == sel_peg_y+2 && board[bx][by-1].peg &&		!hex_struct) ||	       (bx == sel_peg_x && by == sel_peg_y-2 && board[bx][by+1].peg &&		!hex_struct) ||	       (bx == sel_peg_x-1 && by == sel_peg_y+2 && board[bx][by-1].peg &&		hex_struct && !get_indent (by)) ||	       (bx == sel_peg_x-1 && by == sel_peg_y+2 && board[bx+1][by-1].peg &&		hex_struct && get_indent (by)) ||	       (bx == sel_peg_x+1 && by == sel_peg_y+2 && board[bx-1][by-1].peg &&		hex_struct && !get_indent (by)) ||	       (bx == sel_peg_x+1 && by == sel_peg_y+2 && board[bx][by-1].peg &&		hex_struct && get_indent (by)) ||	       (bx == sel_peg_x-1 && by == sel_peg_y-2 && board[bx][by+1].peg &&		hex_struct && !get_indent (by)) ||	       (bx == sel_peg_x-1 && by == sel_peg_y-2 && board[bx+1][by+1].peg &&		hex_struct && get_indent (by)) ||	       (bx == sel_peg_x+1 && by == sel_peg_y-2 && board[bx-1][by+1].peg &&		hex_struct && !get_indent (by)) ||	       (bx == sel_peg_x+1 && by == sel_peg_y-2 && board[bx][by+1].peg &&		hex_struct && get_indent (by)) ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -