Back to index

gcompris  8.2.2
Defines | Functions | Variables
fifteen.c File Reference
#include "gcompris/gcompris.h"
#include <time.h>

Go to the source code of this file.

Defines

#define PIECE_SIZE   50
#define SOUNDLISTFILE   PACKAGE

Functions

static void start_board (GcomprisBoard *agcomprisBoard)
static void pause_board (gboolean pause)
static void end_board (void)
static gboolean is_our_board (GcomprisBoard *gcomprisBoard)
static void set_level (guint level)
static void game_won (void)
static GnomeCanvasItem * fifteen_create_item (GnomeCanvasGroup *parent)
static void fifteen_destroy_all_items (void)
static void fifteen_next_level (void)
static void free_stuff (GtkObject *obj, gpointer data)
static gint piece_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
static void scramble (GnomeCanvasItem **board, guint number_of_scrambles)
static char * get_piece_color (int piece)
static void test_win (GnomeCanvasItem **board)

Variables

static GcomprisBoard * gcomprisBoard = NULL
static gboolean board_paused = TRUE
static int gamewon
static GnomeCanvasGroup * boardRootItem = NULL
static BoardPlugin menu_bp

Define Documentation

#define PIECE_SIZE   50

Definition at line 24 of file fifteen.c.

#define SOUNDLISTFILE   PACKAGE

Definition at line 26 of file fifteen.c.


Function Documentation

static void end_board ( void  ) [static]

Definition at line 121 of file fifteen.c.

Here is the call graph for this function:

static GnomeCanvasItem * fifteen_create_item ( GnomeCanvasGroup *  parent) [static]

Definition at line 190 of file fifteen.c.

{
  int i;
  int x, y;
  GnomeCanvasItem **board;
  GnomeCanvasItem *text;
  char buf[20];
  GdkPixbuf *pixmap = NULL;

  boardRootItem = GNOME_CANVAS_GROUP(
                                 gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
                                                     gnome_canvas_group_get_type (),
                                                     "x", (double) (BOARDWIDTH-(4*PIECE_SIZE))/2,
                                                     "y", (double) (BOARDHEIGHT-(4*PIECE_SIZE))/2,
                                                     NULL));

  /* Load the cute frame */
  pixmap = gc_pixmap_load("images/fifteen_frame.png");

  gnome_canvas_item_new (boardRootItem,
                      gnome_canvas_pixbuf_get_type (),
                      "pixbuf", pixmap,
                      "x", (double)-1*((gdk_pixbuf_get_width(pixmap)-(4*PIECE_SIZE))/2),
                      "y", (double)-1*((gdk_pixbuf_get_height(pixmap)-(4*PIECE_SIZE))/2)-2,
                      NULL);
  gdk_pixbuf_unref(pixmap);


  board = g_new (GnomeCanvasItem *, 16);
  g_object_set_data (G_OBJECT (boardRootItem), "board", board);
  g_signal_connect (boardRootItem, "destroy",
                  G_CALLBACK (free_stuff),
                  board);

  for (i = 0; i < 15; i++) {
    y = i / 4;
    x = i % 4;

    board[i] = gnome_canvas_item_new (boardRootItem,
                                  gnome_canvas_group_get_type (),
                                  "x", (double) (x * PIECE_SIZE),
                                  "y", (double) (y * PIECE_SIZE),
                                  NULL);

    gnome_canvas_item_new (GNOME_CANVAS_GROUP (board[i]),
                        gnome_canvas_rect_get_type (),
                        "x1", 0.0,
                        "y1", 0.0,
                        "x2", (double) PIECE_SIZE,
                        "y2", (double) PIECE_SIZE,
                        "fill_color", get_piece_color (i),
                        "outline_color", "black",
                        "width_pixels", 0,
                        NULL);

    sprintf (buf, "%d", i + 1);

    text = gnome_canvas_item_new (GNOME_CANVAS_GROUP (board[i]),
                              gnome_canvas_text_get_type (),
                              "text", buf,
                              "x", (double) PIECE_SIZE / 2.0,
                              "y", (double) PIECE_SIZE / 2.0,
                              "font", gc_skin_font_board_medium,
                              "anchor", GTK_ANCHOR_CENTER,
                              "fill_color", "black",
                              NULL);

    g_object_set_data (G_OBJECT (board[i]), "piece_num", GINT_TO_POINTER (i));
    g_object_set_data (G_OBJECT (board[i]), "piece_pos", GINT_TO_POINTER (i));
    g_object_set_data (G_OBJECT (board[i]), "text", text);
    g_signal_connect (board[i], "event",
                    G_CALLBACK (piece_event),
                    NULL);
  }

  board[15] = NULL;

  /* Select level difficulty */
  switch(gcomprisBoard->level)
    {
    case 1:
      scramble(board, 10);
      break;
    case 2:
      scramble(board, 50);
      break;
    case 3:
    case 4:
      scramble(board, 100);
      break;
    case 5:
      scramble(board, 150);
      break;
    default:
      scramble(board, 256);
    }

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fifteen_destroy_all_items ( void  ) [static]

Definition at line 182 of file fifteen.c.

{
  if(boardRootItem!=NULL)
    gtk_object_destroy (GTK_OBJECT(boardRootItem));

  boardRootItem = NULL;
}

Here is the caller graph for this function:

static void fifteen_next_level ( void  ) [static]

Definition at line 161 of file fifteen.c.

{
  gchar *img;

  img = gc_skin_image_get("gcompris-bg.jpg");
  gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
                       img);
  g_free(img);

  gc_bar_set_level(gcomprisBoard);

  fifteen_destroy_all_items();
  gamewon = FALSE;

  /* Create the level */
  fifteen_create_item(gnome_canvas_root(gcomprisBoard->canvas));


}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_stuff ( GtkObject *  obj,
gpointer  data 
) [static]

Definition at line 312 of file fifteen.c.

{
  g_free (data);
}

Here is the caller graph for this function:

static void game_won ( void  ) [static]

Definition at line 290 of file fifteen.c.

{
  gcomprisBoard->sublevel++;

  if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
    /* Try the next level */
    gcomprisBoard->sublevel=1;
    gcomprisBoard->level++;
    if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
      gc_bonus_end_display(BOARD_FINISHED_RANDOM);
      return;
    }
    gc_sound_play_ogg ("sounds/bonus.ogg", NULL);
  }
  fifteen_next_level();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * get_piece_color ( int  piece) [static]

Definition at line 334 of file fifteen.c.

{
  static char buf[50];
  int x, y;
  int r, g, b;

  y = piece / 4;
  x = piece % 4;

  r = ((4 - x) * 255) / 4;
  g = ((4 - y) * 255) / 4;
  b = 128;

  sprintf (buf, "#%02x%02x%02x", r, g, b);

  return buf;
}

Here is the caller graph for this function:

static gboolean is_our_board ( GcomprisBoard *  gcomprisBoard) [static]

Definition at line 143 of file fifteen.c.

{
  if (gcomprisBoard)
    {
      if(g_strcasecmp(gcomprisBoard->type, "fifteen")==0)
       {
         /* Set the plugin entry */
         gcomprisBoard->plugin=&menu_bp;

         return TRUE;
       }
    }
  return FALSE;
}
static void pause_board ( gboolean  pause) [static]

Definition at line 87 of file fifteen.c.

{
  if(gcomprisBoard==NULL)
    return;

  if(gamewon == TRUE && pause == FALSE) /* the game is won */
    {
      game_won();
    }

  board_paused = pause;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gint piece_event ( GnomeCanvasItem *  item,
GdkEvent *  event,
gpointer  data 
) [static]

Definition at line 353 of file fifteen.c.

{
  GnomeCanvasItem **board;
  GnomeCanvasItem *text;
  int num, pos, newpos;
  int x, y;
  double dx = 0.0, dy = 0.0;
  int move;

  board = g_object_get_data (G_OBJECT (item->parent), "board");
  num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "piece_num"));
  pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "piece_pos"));
  text = g_object_get_data (G_OBJECT (item), "text");

  switch (event->type) {
  case GDK_ENTER_NOTIFY:
    gnome_canvas_item_set (text,
                        "fill_color", "white",
                        NULL);
    break;

  case GDK_LEAVE_NOTIFY:
    gnome_canvas_item_set (text,
                        "fill_color", "black",
                        NULL);
    break;

  case GDK_BUTTON_PRESS:
    y = pos / 4;
    x = pos % 4;

    move = TRUE;

    if ((y > 0) && (board[(y - 1) * 4 + x] == NULL)) {
      dx = 0.0;
      dy = -1.0;
      y--;
    } else if ((y < 3) && (board[(y + 1) * 4 + x] == NULL)) {
      dx = 0.0;
      dy = 1.0;
      y++;
    } else if ((x > 0) && (board[y * 4 + x - 1] == NULL)) {
      dx = -1.0;
      dy = 0.0;
      x--;
    } else if ((x < 3) && (board[y * 4 + x + 1] == NULL)) {
      dx = 1.0;
      dy = 0.0;
      x++;
    } else
      move = FALSE;

    if (move) {
      newpos = y * 4 + x;
      board[pos] = NULL;
      board[newpos] = item;
      g_object_set_data (G_OBJECT (item), "piece_pos", GINT_TO_POINTER (newpos));
      gnome_canvas_item_move (item, dx * PIECE_SIZE, dy * PIECE_SIZE);
      /* FIXME : Workaround for bugged canvas */
      gnome_canvas_update_now(gcomprisBoard->canvas);

      test_win (board);
    }

    break;

  default:
    break;
  }

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scramble ( GnomeCanvasItem **  board,
guint  number_of_scrambles 
) [static]

Definition at line 427 of file fifteen.c.

{
  int i;
  int pos, oldpos;
  int dir;
  int x, y;

  srand (time (NULL));

  /* First, find the blank spot */

  for (pos = 0; pos < 16; pos++)
    if (board[pos] == NULL)
      break;

  /* "Move the blank spot" around in order to scramble the pieces */

  for (i = 0; i < number_of_scrambles; i++) {
  retry_scramble:
    dir = rand () % 4;

    x = y = 0;

    if ((dir == 0) && (pos > 3)) /* up */
      y = -1;
    else if ((dir == 1) && (pos < 12)) /* down */
      y = 1;
    else if ((dir == 2) && ((pos % 4) != 0)) /* left */
      x = -1;
    else if ((dir == 3) && ((pos % 4) != 3)) /* right */
      x = 1;
    else
      goto retry_scramble;

    oldpos = pos + y * 4 + x;
    board[pos] = board[oldpos];
    board[oldpos] = NULL;
    g_object_set_data (G_OBJECT (board[pos]), "piece_pos", GINT_TO_POINTER (pos));
    gnome_canvas_item_move (board[pos], -x * PIECE_SIZE, -y * PIECE_SIZE);
    pos = oldpos;
  }
  /* FIXME : Workaround for bugged canvas */
  gnome_canvas_update_now(gcomprisBoard->canvas);
}

Here is the caller graph for this function:

static void set_level ( guint  level) [static]

Definition at line 132 of file fifteen.c.

{

  if(gcomprisBoard!=NULL)
    {
      gcomprisBoard->level=level;
      gcomprisBoard->sublevel=1;
      fifteen_next_level();
    }
}

Here is the call graph for this function:

static void start_board ( GcomprisBoard *  agcomprisBoard) [static]

Definition at line 102 of file fifteen.c.

{

  if(agcomprisBoard!=NULL)
    {
      gcomprisBoard=agcomprisBoard;
      gcomprisBoard->level=1;
      gcomprisBoard->maxlevel=6;
      gcomprisBoard->sublevel=1;
      gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
      gc_bar_set(GC_BAR_LEVEL);

      fifteen_next_level();

      gamewon = FALSE;
      pause_board(FALSE);
    }
}

Here is the call graph for this function:

static void test_win ( GnomeCanvasItem **  board) [static]

Definition at line 318 of file fifteen.c.

{
  int i;

  for (i = 0; i < 15; i++)
    if (!board[i] || (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (board[i]), "piece_num")) != i))
      return;


  gamewon = TRUE;
  fifteen_destroy_all_items();
  gc_bonus_display(gamewon, BONUS_SMILEY);

}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

gboolean board_paused = TRUE [static]

Definition at line 29 of file fifteen.c.

GnomeCanvasGroup* boardRootItem = NULL [static]

Definition at line 39 of file fifteen.c.

int gamewon [static]

Definition at line 36 of file fifteen.c.

GcomprisBoard* gcomprisBoard = NULL [static]

Definition at line 28 of file fifteen.c.

BoardPlugin menu_bp [static]
Initial value:
  {
    NULL,
    NULL,
    "The fifteen game",
    "Move the items one by one, to rearrange them in increasing order",
    "Bruno Coudoin <bruno.coudoin@free.fr>",
    NULL,
    NULL,
    NULL,
    NULL,
    start_board,
    pause_board,
    end_board,
    is_our_board,
    NULL,
    NULL,
    set_level,
    NULL,
    NULL,
    NULL,
    NULL
  }

Definition at line 51 of file fifteen.c.