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

📄 klondike.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************/
/*                                                              */
/*                        klondike.c                            */
/*                                                              */
/*             The "Klondike" card game for Seal                */
/*                                                              */
/*                     Copyright (c) 2002                       */
/*                      Tobias Johansson                        */
/*                     All Rights Reserved                      */
/*                                                              */
/* mail:  tobbe_snodd@hotmail.com                               */
/* web:   http://hem.passagen.se/sealfiles                      */
/*                                                              */
/* Klondike 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, or (at your option) any later version.                    */
/*                                                              */
/* Klondike 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 Klondike; see the file COPYING.  If not,  */
/* write to the Free Software Foundation, 675 Mass Ave,         */
/* Cambridge, MA 02139, USA.                                    */
/*                                                              */
/****************************************************************/


// 3/4/2002  - Better skin support added by Tobias Johansson



#include "allegro.h"
#include "seal.h"
#include "app.h"
#include "view.h"
#include "cards.h"
#include "menus.h"
#include "helpsys.h"

#define MSG_KLOND_NEW     100001
#define MSG_KLOND_DECK    100002
#define MSG_KLOND_HELP    100003
#define MSG_CARDS_ABOUT   100004
#define MSG_TAKE_THREE	  100005
#define MSG_KLOND_SELGAME 100006
#define MSG_KLOND_STAT    100007
#define MSG_KLOND_STATRES 100008

#define TEXT_ABOUT      "Klondike 1.1\n\n(c) 2002 Tobias Johansson\n\nEmail:   tobbe_snodd@hotmail.com\nWeb:   hem.passagen.se/sealfiles\n"


p_appwin   winMain;
p_view     vGame;
p_menu     menu;
p_menuview gameMenu;

t_card deck[53];
t_card piles[12][25];    // piles[0]    = stock,      piles[1-7] = lower piles, 
l_int  pilesCount[12];   // piles[8-11] = suite piles

l_int  drawnCards[4];
l_int  curCard, fromCard, fromPile, toPile; 
l_int  drawThreeCards;
l_int  curGame = 0;

l_bool isGameOver  = FALSE;
l_bool startedGame = FALSE;
l_int  winCount;
l_int  lostCount;


SetInfoAppName      ("Klondike");
SetInfoDesciption   ("Seal version of the very famous patience game.");
SetInfoCopyright    ("(c) Copyright 2002 Tobias Johansson. All rights reserved.");
SetInfoManufacturer ("Tobias Johansson");



void   init_deck        (void);
void   init_game        (void);
void   deselect_all     (void);
void   move_card        (void);
void   draw_from_stock  (void);
void   redraw_vGame     (p_view v);
void   trans_event      (p_object o, p_event event);
p_menu create_game_menu (void);



void redraw_win_title(void) {

   // Redraws the title of the window to show
   // which game is currently selected.

   if (winMain) {
      _free(WINDOW(winMain)->caption);
      WINDOW(winMain)->caption = set_format_text(NULL, "Klondike - game #%d", curGame);

      TEST_SUB_VIEWS(VIEW(winMain), WINDOW(winMain)->draw_title(WINDOW(winMain)));
  };
};



void init_deck(void) {

   // Create a new empty deck

   curCard = 52;
   fromPile = fromCard = 0;

   cards_init_deck(deck);
   curGame = cards_shuffle_deck_ex(deck);
   redraw_win_title();
   deselect_all();
};



l_int init_deck_sel_game(void) {

   // Create a new empty deck

   l_int selGame;

   selGame = cards_game_select(curGame);
   if (selGame) {
      curCard = 52;
      fromPile = fromCard = 0;
      curGame = selGame;
      cards_init_deck(deck);
      cards_shuffle_deck_select(deck, curGame);
      redraw_win_title();

      return 1;
   };
   return 0;
};



void init_game(void) {
   l_int tc, tp;

   // Fill up the seven lower piles.

   for (tp=1 ; tp<=7 ;tp++) {
      for (tc=0 ; tc<=tp-1 ; tc++) {
         piles[tp][tc].showFace = false;
         piles[tp][tc].card = deck[curCard].card;
         curCard--;
      };
      piles[tp][tp-1].showFace = true;
      pilesCount[tp] = tp;
   };

   // Fill up the stock (the hand) with 
   // the rest of the cards in the deck.

   for (tc=curCard ; tc>0 ; tc--) {
      piles[0][tc].card     = deck[tc].card;
      piles[0][tc].showFace = true;
   };

   // Empty the four suite piles.

   for (tp=8 ; tp<=11 ;tp++) pilesCount[tp] = 0;

   // Remove old cards drawn from stock.

   for (tp=0 ; tp<=2 ;tp++) drawnCards[tp] = 0;

   pilesCount[0] = curCard;
};



l_int check_if_won(void) {

   // The game is won if the number of cards 
   // in the four upper piles equals 52.

   l_int p, c = 0;
   for (p=8 ; p<12 ; p++) c += pilesCount[p];
   if (c == 52) {
      return 1;
   } else {
      return 0;
   };
};



void deselect_all(void) {

   // Deselect all cards in all piles.

   l_int tp, tc;
   for (tp=0 ; tp<=11 ;tp++) {
      for (tc=0 ; tc<=pilesCount[tp] ; tc++) {
         piles[tp][tc].selected = false;
      };
   };
   fromCard = 0;
   fromPile = 0;
   toPile   = 0;
};



void move_card(void) {

   // Moves fromCard from fromPile to toPile.

   l_int c;
   if (!isGameOver) startedGame = TRUE;

   // If moved from the deck or one of the suite piles.

   if (fromPile == 0 || fromPile >= 8) {
      pilesCount[toPile]++;
      piles[toPile][(pilesCount[toPile])-1] = piles[fromPile][fromCard-1];
      pilesCount[fromPile]--;
      for (c=fromCard-1 ; c<=pilesCount[fromPile] ; c++) 
         piles[fromPile][c] = piles[fromPile][c+1];

      // Remove the top one of the three turned cards.

      if (fromPile == 0) {
         for (c=0 ; c<3 ; c++) drawnCards[c] = drawnCards[c+1];
         if (drawnCards[0] == 0) {
            if (curCard < pilesCount[0]) {
               drawnCards[0] = curCard + 1;
            };
         };
      };
   } else {

      // Move the selected card (and the ones on top of it if any)
      // from one of the seven lower piles to another one.

      for (c=fromCard-1 ; c<pilesCount[fromPile] ; c++) {
         piles[toPile][(pilesCount[toPile])] = piles[fromPile][c];
         pilesCount[toPile]++;
      };
      pilesCount[fromPile] = fromCard-1;
   }; 
   deselect_all();
};



void draw_from_stock(void) {
   l_int c;

   // Go back to the topmost card if the bottom 
   // card of the stock is reached.

   if (curCard < 0) curCard = pilesCount[0];   

   // Remove old cards.

   for (c=0 ; c<=2 ; c++) drawnCards[c] = 0;

   // Get three new or one new card from the stock.

   if (drawThreeCards) {
      for (c=0 ; c<3 ; c++) {
         drawnCards[c] = curCard;
         curCard--;

         // Exit loop if reached bottom of pile.

         if (curCard < 1) break;
      };
   } else {
      drawnCards[0] = curCard;
      drawnCards[1] = 0;
      drawnCards[2] = 0;
      curCard--;
   };      
};



l_int get_clicked_card(l_int cPile, l_int curY, l_int startY) {

   // Returns the card that was clicked in one of the seven piles.
   // cPile is pile to look in, curY is current vert. position of
   // mouse pointer and startY is the Y-coord. to start looking at
   // (the top edge of the topmost card on the screen).

   // Loop through the cards in the pile and add the height of the
   // current card (CARD_LOFFSET or CARD_SOFFSET depending on if the
   // card is turned or not) to startY. If curY is between startY 
   // and startY + the cards' height then return the number of the 
   // current card.

   l_int c;
   for (c=0 ; c<pilesCount[cPile] ; c++) {
      if (piles[cPile][c].showFace) {
         if (curY >= startY && curY < (startY + CARD_LOFFSET)) {
            return c;
         };
         startY += CARD_LOFFSET;
      } else {
         if (curY >= startY && curY < (startY + CARD_SOFFSET)) {
            return 0;
         };
         startY += CARD_SOFFSET;
      };
   };
   if (curY >= startY && curY <= (startY + CARD_HEIGHT))
      return pilesCount[cPile];
   else 
      return 0;
};



void redraw_vGame(p_view v) {
   t_point p;
   l_int   cCard, cPile, curY;
   t_rect  r = v->size_limits(v); 
   BITMAP  *out = v->begin_paint(v, &p, r);
   if (out) {

      // Draw green background.

      rectfill(out, p.x, p.y, p.x+600, p.y+400, COLOR(CO_GREEN));

      // Draw the seven lower piles.

      for (cPile=1 ; cPile<8 ; cPile++) {
         curY = 120;
         for (cCard=0 ; cCard<pilesCount[cPile] ; cCard++) {
            if (cCard-1 >= 0) {
               if (piles[cPile][cCard-1].showFace) 
                  curY += CARD_LOFFSET;
               else
                  curY += CARD_SOFFSET;
            };
            cards_blit_card(out, p.x+15+((cPile-1)*80), p.y+curY, piles[cPile][cCard]);
         };
      };

      // Draw the four upper suite piles.

      for (cPile=8 ; cPile<12 ; cPile++) {
         if (!pilesCount[cPile]) {
            cards_blit_symbol(out, p.x+255+((cPile-8)*80), p.y+12, C_EMPTY);
         } else {
            cards_blit_card(out, p.x+255+((cPile-8)*80), p.y+12, piles[cPile][(pilesCount[cPile]-1)]);
         };
      };

      // Draw back of the stock (the hand).

      if (pilesCount[0] && curCard) {
         cards_blit_back(out, p.x+15, p.y+12);
      } else {
         cards_blit_symbol(out, p.x+15, p.y+12, C_CIRCLE);
      };

      // Draw the current card(s) drawn from the stock.

      if (curCard <= pilesCount[0]) {
         for (cCard=0 ; cCard<3 ; cCard++) {
           cards_blit_card(out, p.x+95+(cCard*13), p.y+12,  piles[0][(drawnCards[cCard])]); 
         };
      };
   };
   v->end_of_paint(v, r);
};



void trans_event(p_object o, p_event event) {
   l_int c, cc, cPile, i;
   t_point p;
   RETVIEW(o, event);
   if (event->type & EV_MOUSE) {

      if (OBJECT(mouse)->state & MO_SF_MOUSELUP) {
         p = VIEW(vGame)->get_local_point(VIEW(vGame), mouse->where);

         p.y += 45;  // I know this is ugly, but I didnt feel like
                     // changing all the coordinates when updating. (to do)

         if (p.x > +15 && p.x < +91 && p.y > +55 && p.y < +151) {

⌨️ 快捷键说明

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