Back to index

gcompris  8.2.2
money.c
Go to the documentation of this file.
00001 /* gcompris - money.c
00002  *
00003  * Copyright (C) 2001 Bruno Coudoin
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include "gcompris/gcompris.h"
00021 #include "money_widget.h"
00022 
00023 #define SOUNDLISTFILE PACKAGE
00024 
00025 static GcomprisBoard *gcomprisBoard = NULL;
00026 static gboolean board_paused = TRUE;
00027 
00028 static void    start_board (GcomprisBoard *agcomprisBoard);
00029 static void    pause_board (gboolean pause);
00030 static void    end_board (void);
00031 static gboolean       is_our_board (GcomprisBoard *gcomprisBoard);
00032 static void    set_level (guint level);
00033 static void    process_ok(void);
00034 static int     gamewon;
00035 static void    game_won(void);
00036 
00037 static GnomeCanvasGroup *boardRootItem = NULL;
00038 
00039 static void           money_destroy_all_items(void);
00040 static void           money_next_level(void);
00041 
00042 Money_Widget    *tux_money    = NULL;
00043 Money_Widget    *seller_money = NULL;
00044 
00045 static double  price_target = 0;
00046 
00047 typedef struct {
00048   char *image;
00049   guint status;
00050   float value;
00051   GnomeCanvasItem *item;
00052 } MoneyItem;
00053 
00054 // List of images to use in the game
00055 static gchar *imageList[] =
00056 {
00057   "gcompris/misc/apple.png",
00058   "gcompris/misc/bicycle.png",
00059   "gcompris/misc/bottle.png",
00060   "gcompris/misc/carot.png",
00061   "gcompris/misc/cerise.png",
00062   "gcompris/misc/crown.png",
00063   "gcompris/misc/eggpot.png",
00064   "gcompris/misc/flower.png",
00065   "gcompris/misc/football.png",
00066   "gcompris/misc/lamp.png",
00067   "gcompris/misc/light.png",
00068   "gcompris/misc/peer.png",
00069   "gcompris/misc/pencil.png",
00070   "gcompris/misc/strawberry.png"
00071 };
00072 #define NUMBER_OF_IMAGES 14
00073 
00074 #define WITHOUT_CENTS       1
00075 #define WITH_CENTS   2
00076 static char currentMode = WITHOUT_CENTS;
00077 
00078 /* Description of this plugin */
00079 static BoardPlugin menu_bp =
00080   {
00081     NULL,
00082     NULL,
00083     "Money",
00084     "Pratise money usage",
00085     "Bruno Coudoin <bruno.coudoin@free.fr>",
00086     NULL,
00087     NULL,
00088     NULL,
00089     NULL,
00090     start_board,
00091     pause_board,
00092     end_board,
00093     is_our_board,
00094     NULL,
00095     process_ok,
00096     set_level,
00097     NULL,
00098     NULL,
00099     NULL,
00100     NULL
00101   };
00102 
00103 /*
00104  * Main entry point mandatory for each Gcompris's game
00105  * ---------------------------------------------------
00106  *
00107  */
00108 
00109 GET_BPLUGIN_INFO(money)
00110 
00111 /*
00112  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00113  *
00114  */
00115 static void pause_board (gboolean pause)
00116 {
00117   if(gcomprisBoard==NULL)
00118     return;
00119 
00120   if(gamewon == TRUE && pause == FALSE) /* the game is won */
00121     {
00122       game_won();
00123     }
00124 
00125   board_paused = pause;
00126 }
00127 
00128 /*
00129  */
00130 static void start_board (GcomprisBoard *agcomprisBoard)
00131 {
00132 
00133   if(agcomprisBoard!=NULL)
00134     {
00135       gcomprisBoard=agcomprisBoard;
00136       gcomprisBoard->level=1;
00137       gcomprisBoard->sublevel=1;
00138       gcomprisBoard->number_of_sublevel=10; /* Go to next level after this number of 'play' */
00139       gc_bar_set(GC_BAR_LEVEL|GC_BAR_OK);
00140 
00141       /* Default mode */
00142       if(!gcomprisBoard->mode)
00143        {
00144          gcomprisBoard->maxlevel=9;
00145          currentMode=WITHOUT_CENTS;
00146        }
00147       else if(g_strncasecmp(gcomprisBoard->mode, "WITH_CENTS", 1)==0)
00148        {
00149          gcomprisBoard->maxlevel=5;
00150          currentMode=WITH_CENTS;
00151        }
00152       money_next_level();
00153 
00154       gamewon = FALSE;
00155       pause_board(FALSE);
00156     }
00157 }
00158 /* ======================================= */
00159 static void end_board ()
00160 {
00161   if(gcomprisBoard!=NULL)
00162     {
00163       pause_board(TRUE);
00164       money_destroy_all_items();
00165     }
00166   gcomprisBoard = NULL;
00167 }
00168 
00169 /* ======================================= */
00170 static void set_level (guint level)
00171 {
00172 
00173   if(gcomprisBoard!=NULL)
00174     {
00175       gcomprisBoard->level=level;
00176       gcomprisBoard->sublevel=1;
00177       money_next_level();
00178     }
00179 }
00180 /* ======================================= */
00181 gboolean is_our_board (GcomprisBoard *gcomprisBoard)
00182 {
00183   if (gcomprisBoard)
00184     {
00185       if(g_strcasecmp(gcomprisBoard->type, "money")==0)
00186        {
00187          /* Set the plugin entry */
00188          gcomprisBoard->plugin=&menu_bp;
00189 
00190          return TRUE;
00191        }
00192     }
00193   return FALSE;
00194 }
00195 
00196 /*-------------------------------------------------------------------------------*/
00197 /*-------------------------------------------------------------------------------*/
00198 /* set initial values for the next level */
00199 static void money_next_level()
00200 {
00201   GdkPixbuf       *pixmap = NULL;
00202   guint                 min_price = 0, max_price = 0;
00203   guint                 number_of_item = 0;
00204   guint                 i;
00205   gchar                *display_format;
00206   gchar                *img;
00207 
00208   img = gc_skin_image_get("money-bg.png");
00209   gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
00210                        img);
00211   g_free(img);
00212 
00213   gc_bar_set_level(gcomprisBoard);
00214 
00215   money_destroy_all_items();
00216   gamewon = FALSE;
00217 
00218   boardRootItem = GNOME_CANVAS_GROUP(gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00219                                                      gnome_canvas_group_get_type (),
00220                                                      "x", (double) 0,
00221                                                      "y", (double) 0,
00222                                                      NULL));
00223 
00224   tux_money = MONEY_WIDGET(money_widget_new());
00225   money_widget_set_position(tux_money,
00226                          boardRootItem,
00227                          100.0, 400.0,
00228                          700.0, 500.0,
00229                          5, 2,
00230                          FALSE);
00231 
00232   /* Select level difficulty */
00233   switch(currentMode)
00234     {
00235     case WITHOUT_CENTS:
00236       switch(gcomprisBoard->level)
00237        {
00238        case 1:
00239          number_of_item = 1;
00240          min_price      = 3;
00241          max_price      = 10;
00242          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00243          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00244          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00245          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00246          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00247          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00248          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00249          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00250          break;
00251        case 2:
00252          number_of_item = 1;
00253          min_price      = 10;
00254          max_price      = 20;
00255          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00256          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00257          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00258          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00259          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00260          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00261          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00262          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00263          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00264          break;
00265        case 3:
00266          number_of_item = 2;
00267          min_price      = 20;
00268          max_price      = 30;
00269          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00270          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00271          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00272          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00273          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00274          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00275          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00276          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00277          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00278          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00279          break;
00280        case 4:
00281          number_of_item = 2;
00282          min_price      = 30;
00283          max_price      = 40;
00284          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00285          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00286          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00287          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00288          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00289          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00290          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00291          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00292          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00293          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00294          break;
00295        case 5:
00296          number_of_item = 3;
00297          min_price      = 40;
00298          max_price      = 50;
00299          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00300          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00301          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00302          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00303          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00304          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00305          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00306          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00307          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00308          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00309          break;
00310        case 6:
00311          number_of_item = 3;
00312          min_price      = 50;
00313          max_price      = 60;
00314          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00315          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00316          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00317          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00318          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00319          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00320          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00321          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00322          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00323          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00324          break;
00325        case 7:
00326          number_of_item = 4;
00327          min_price      = 60;
00328          max_price      = 70;
00329          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00330          money_widget_add(tux_money, MONEY_EURO_PAPER_50E);
00331          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00332          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00333          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00334          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00335          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00336          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00337          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00338          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00339          break;
00340        case 8:
00341          number_of_item = 4;
00342          min_price      = 70;
00343          max_price      = 80;
00344          money_widget_add(tux_money, MONEY_EURO_PAPER_50E);
00345          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00346          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00347          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00348          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00349          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00350          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00351          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00352          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00353          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00354          break;
00355        case 9:
00356          number_of_item = 4;
00357          min_price      = 50;
00358          max_price      = 100;
00359          money_widget_add(tux_money, MONEY_EURO_PAPER_10E);
00360          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00361          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00362          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00363          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00364          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00365          money_widget_add(tux_money, MONEY_EURO_PAPER_50E);
00366          money_widget_add(tux_money, MONEY_EURO_PAPER_20E);
00367          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00368          money_widget_add(tux_money, MONEY_EURO_PAPER_5E);
00369          break;
00370        }
00371       break;
00372     case WITH_CENTS:
00373       switch(gcomprisBoard->level)
00374        {
00375        case 1:
00376          number_of_item = 1;
00377          min_price      = 1;
00378          max_price      = 3;
00379          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00380          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00381          money_widget_add(tux_money, MONEY_EURO_COIN_5C);
00382          money_widget_add(tux_money, MONEY_EURO_COIN_2C);
00383          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00384          money_widget_add(tux_money, MONEY_EURO_COIN_50C);
00385          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00386          money_widget_add(tux_money, MONEY_EURO_COIN_10C);
00387          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00388          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00389          break;
00390        case 2:
00391          number_of_item = 1;
00392          min_price      = 1;
00393          max_price      = 3;
00394          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00395          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00396          money_widget_add(tux_money, MONEY_EURO_COIN_5C);
00397          money_widget_add(tux_money, MONEY_EURO_COIN_2C);
00398          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00399          money_widget_add(tux_money, MONEY_EURO_COIN_50C);
00400          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00401          money_widget_add(tux_money, MONEY_EURO_COIN_10C);
00402          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00403          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00404          break;
00405        case 3:
00406          number_of_item = 2;
00407          min_price      = 1;
00408          max_price      = 3;
00409          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00410          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00411          money_widget_add(tux_money, MONEY_EURO_COIN_5C);
00412          money_widget_add(tux_money, MONEY_EURO_COIN_2C);
00413          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00414          money_widget_add(tux_money, MONEY_EURO_COIN_50C);
00415          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00416          money_widget_add(tux_money, MONEY_EURO_COIN_10C);
00417          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00418          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00419          break;
00420        case 4:
00421          number_of_item = 3;
00422          min_price      = 1;
00423          max_price      = 3;
00424          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00425          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00426          money_widget_add(tux_money, MONEY_EURO_COIN_5C);
00427          money_widget_add(tux_money, MONEY_EURO_COIN_2C);
00428          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00429          money_widget_add(tux_money, MONEY_EURO_COIN_50C);
00430          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00431          money_widget_add(tux_money, MONEY_EURO_COIN_10C);
00432          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00433          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00434          break;
00435        case 5:
00436          number_of_item = 4;
00437          min_price      = 1;
00438          max_price      = 3;
00439          money_widget_add(tux_money, MONEY_EURO_COIN_2E);
00440          money_widget_add(tux_money, MONEY_EURO_COIN_1E);
00441          money_widget_add(tux_money, MONEY_EURO_COIN_5C);
00442          money_widget_add(tux_money, MONEY_EURO_COIN_2C);
00443          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00444          money_widget_add(tux_money, MONEY_EURO_COIN_50C);
00445          money_widget_add(tux_money, MONEY_EURO_COIN_20C);
00446          money_widget_add(tux_money, MONEY_EURO_COIN_10C);
00447          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00448          money_widget_add(tux_money, MONEY_EURO_COIN_1C);
00449          break;
00450        }
00451       break;
00452     }
00453 
00454   seller_money = MONEY_WIDGET(money_widget_new());
00455   money_widget_set_position(seller_money,
00456                          boardRootItem,
00457                          100.0,  30.0,
00458                          700.0, 130.0,
00459                          5, 2,
00460                          FALSE);
00461 
00462   money_widget_set_target(seller_money, tux_money);
00463   money_widget_set_target(tux_money, seller_money);
00464 
00465   /* Display what to buy */
00466   price_target = 0;
00467   for(i=1; i<=number_of_item; i++)
00468   {
00469     double object_price;
00470     gchar *text;
00471 
00472     pixmap = gc_pixmap_load(imageList[RAND(0, NUMBER_OF_IMAGES-1)]);
00473 
00474     gnome_canvas_item_new ( boardRootItem,
00475                          gnome_canvas_pixbuf_get_type (),
00476                          "pixbuf", pixmap,
00477                          "x", (double) (i*BOARDWIDTH)/(number_of_item+1)
00478                          - gdk_pixbuf_get_width(pixmap)/2,
00479                          "y", (double) 200,
00480                          NULL);
00481 
00482     /* Diplay the price */
00483     object_price  = (double) RAND(min_price/number_of_item, max_price/number_of_item);
00484 
00485     if(currentMode==WITH_CENTS)
00486       {
00487        /* Set here the way to display money. Change only the money sign, and it's place, always keep %.2f, it will be replaced by 0,34 if decimal is ',' in your locale */
00488        display_format = _("$ %.2f");
00489        /* Add random cents */
00490        if(gcomprisBoard->level == 1)
00491          {
00492            object_price += (double)((double) RAND(1, 9))/10.0;
00493          }
00494        else
00495          {
00496            object_price += (double)((double) RAND(1, 99))/100.0;
00497          }
00498       }
00499     else
00500       {
00501        display_format = _("$ %.0f");
00502       }
00503 
00504     price_target += object_price;
00505     text = g_strdup_printf(display_format, object_price);
00506     gnome_canvas_item_new(boardRootItem,
00507                        gnome_canvas_text_get_type (),
00508                        "text", text,
00509                        "font", gc_skin_font_board_big,
00510                        "x", (double) (i*BOARDWIDTH)/(number_of_item+1),
00511                        "y", (double) 180,
00512                        "anchor", GTK_ANCHOR_CENTER,
00513                        "fill_color", "white",
00514                        NULL);
00515     g_free(text);
00516     gdk_pixbuf_unref(pixmap);
00517   }
00518 
00519 }
00520 /* ==================================== */
00521 /* Destroy all the items */
00522 static void money_destroy_all_items()
00523 {
00524   if(boardRootItem!=NULL)
00525     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00526 
00527   if(tux_money!=NULL)
00528     gtk_object_destroy (GTK_OBJECT (tux_money));
00529   tux_money = NULL;
00530 
00531   if(seller_money!=NULL)
00532     gtk_object_destroy (GTK_OBJECT (seller_money));
00533   seller_money = NULL;
00534 
00535   boardRootItem = NULL;
00536 }
00537 
00538 /* ==================================== */
00539 static void game_won()
00540 {
00541   gcomprisBoard->sublevel++;
00542 
00543   if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
00544     /* Try the next level */
00545     gcomprisBoard->sublevel=1;
00546     gcomprisBoard->level++;
00547     if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
00548       gc_bonus_end_display(BOARD_FINISHED_RANDOM);
00549       return;
00550     }
00551     gc_sound_play_ogg ("sounds/bonus.ogg", NULL);
00552   }
00553   money_next_level();
00554 }
00555 
00556 /* ==================================== */
00557 static void process_ok()
00558 {
00559 
00560   if(board_paused)
00561     /*return FALSE*/;
00562 
00563   /* FIXME: Why do I need this trick !! */
00564   if(price_target >= money_widget_get_total(seller_money) - 0.001 &&
00565      price_target <= money_widget_get_total(seller_money) + 0.001 )
00566     {
00567       gamewon = TRUE;
00568       money_destroy_all_items();
00569       gc_bonus_display(gamewon, BONUS_SMILEY);
00570     }
00571   else
00572     gc_bonus_display(gamewon, BONUS_SMILEY);
00573 }