home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 605b.lha / Spades_v2.10 / Source / Spades.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-06  |  13.6 KB  |  443 lines

  1. /**********************************************************
  2. * PROGRAM: Spades                                         *
  3. * AUTHOR: Copyright 1992 Gregory M. Stelmack              *
  4. * COMPILER: SAS/C 5.10b                                   *
  5. *      Copyright (C) 1988 Lattice, Inc.                   *
  6. *      Copyright (C) 1990 SAS Institute, Inc.             *
  7. * VESRION DATES:                                          *
  8. *      Version 1.0  -- February 5, 1990                   *
  9. *      Version 1.1  -- April 28, 1990                     *
  10. *           Images used for cards -- file "Spades.images" *
  11. *           must be in current directory to run.          *
  12. *           Title graphics added. New routine for         *
  13. *           choosing dealer.                              *
  14. *      Version 1.11 -- August 23, 1990                    *
  15. *           Fixed memory freeing bug. Added some prompts. *
  16. *      Version 1.12 -- October 3, 1990                    *
  17. *           Removed LIBRARY_VERSION from OpenLibrary()    *
  18. *           calls, replacing it with zero. An attempt to  *
  19. *           let it run under pre-1.3.                     *
  20. *      Version 1.20 -- April 4, 1991                      *
  21. *           Error messages now pause. Revised strategy.   *
  22. *           Window can be sized and dragged, and screen   *
  23. *           moved to back to allow other things to be     *
  24. *           done.                                         *
  25. *      Version 2.00 -- January 26, 1992                   *
  26. *           Window is now a backdrop, and the screen      *
  27. *           gadgets are visible. Menus now used to select *
  28. *           most options, and rules for NIL bids and Bags *
  29. *           have been added as optional. Computer players *
  30. *           do not yet take these rules into account. Due *
  31. *           to use of EasyRequest() for About, Spades now *
  32. *           requires V36 of Intuition Library (meaning    *
  33. *           you need AmigaDOS 2.xx).                      *
  34. *      Version 2.10 -- February 3, 1992                   *
  35. *           Code clean up. Source broken up into multiple *
  36. *           modules to allow for expansion room. Option to*
  37. *           Save a Hand implemented. Computer strategy    *
  38. *           now accounts for optional rules. More use of  *
  39. *           V36 Library functions (including GadTools).   *
  40. **********************************************************/
  41.  
  42. /* Include files */
  43.  
  44. #ifndef INCLUDE_H
  45. #include "Include.h"
  46. #endif
  47.  
  48. #include "Graphics.h"
  49.  
  50. /* Structures needed for libraries */
  51.  
  52. struct IntuitionBase *IntuitionBase;
  53. struct GfxBase       *GfxBase;
  54. struct Library       *DiskfontBase;
  55. struct Library       *GadToolsBase;
  56.  
  57. /* OS Structures */
  58.  
  59. struct Screen       *CustScr;
  60. struct Window       *Wdw;
  61. struct Viewport     *WVP;
  62. APTR                VI;          /* VisualInfo for GadTools */
  63.  
  64. /*************************** Arrays ***************************/
  65. int Deck[52];
  66. int Hand[4][13];
  67. int Bid[4];
  68. int Mode[4];
  69. int HighCardLeft[4];
  70. int Card[4] = {0,0,0,0};
  71. int Value[13];
  72. int SuitNumber[4];
  73. int CardX[4] = {100,1,100,209};
  74. int CardY[4] = {99,60,1,60};
  75. int MsgX[4] = {116,45,116,195};
  76. int MsgY[4] = {96,84,50,84};
  77. BOOL OutOfSuit[4][4];
  78. int TricksTaken[4];
  79. int TrickLeader[14];
  80. int CardPlayed[4][13];
  81.  
  82. /******************** Other Global Variables ******************/
  83. char *String = "      ";   /* Temporary String Storage */
  84.  
  85. int PlayerScore=0, CompScore=0, PlayerTricks=0, CompTricks=0;
  86. int HandLead=0, Button=0, TrickLead=0, PlayerBid=0, CompBid=0;
  87. int ShortSuit=0, LongSuit=0, HighCard=0, Winner=0;
  88. int PlayerBags=0, CompBags=0;
  89. BOOL SpadePlayed=FALSE, AllDone=FALSE, ScreenOpen=FALSE;
  90. BOOL BagsRule=FALSE, NilRule=FALSE, SaveHand=FALSE;
  91. char *CardData;
  92.  
  93. SHORT Mx=0, My=0;        /* Mouse Coordinates */
  94.  
  95. /**************** Module Local Variables and Structures **********/
  96.  
  97. struct EasyStruct    ErrorES =
  98. {
  99.    sizeof(struct EasyStruct),
  100.    0,
  101.    "Spades Error",
  102.    NULL,
  103.    "QUIT"
  104. };
  105.  
  106. /********************* Program Begins Here ********************/
  107.  
  108. /**********************************************************
  109. * Function: main                                          *
  110. * Purpose: Open everything, play the game, close          *
  111. *          everything.                                    *
  112. **********************************************************/
  113. main()
  114. {
  115.    /* Initialize the Amiga */
  116.    
  117.    OpenAll();
  118.    
  119.    /* Start Game */
  120.  
  121.    Spades();
  122.     
  123.    /* Close Everything */
  124.  
  125.    WrapUp();
  126. }
  127.  
  128. /**********************************************************
  129. * Function: OpenAll                                       *
  130. * Parameters: None                                        *
  131. * Return Values: None                                     *
  132. * Purpose: Handle the Amiga initialization                *
  133. **********************************************************/
  134. void OpenAll()
  135. {
  136.    BPTR fh;
  137.    LONG count=0;
  138.    BOOL success;
  139.    
  140.    /* Open the required libraries. */
  141.    
  142.    IntuitionBase = (struct IntuitionBase *) 
  143.       OpenLibrary("intuition.library", 36L);
  144.    if (IntuitionBase == NULL) 
  145.       PError("Can't open Intuition Library");
  146.  
  147.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
  148.    if (GfxBase == NULL)
  149.       PError("Can't open Graphics Library");
  150.  
  151.    GadToolsBase = OpenLibrary("gadtools.library", 36L);
  152.    if (GadToolsBase == NULL)
  153.       PError("Can't open GadTools Library");
  154.       
  155.     /* Load Graphic Images */
  156.  
  157.    CardData = (char *)AllocMem(CARDMEMSIZE,MEMF_CHIP);
  158.    if (!CardData)
  159.       PError("Could not allocate image memory!");
  160.    fh = Open("Spades.images",MODE_OLDFILE);
  161.    if (fh==NULL)
  162.       PError("Can't open images file!");
  163.    count = Read(fh,CardData,CARDMEMSIZE);
  164.    (void)Close(fh);
  165.    if (count==-1)
  166.       PError("Error reading images file!");
  167.  
  168.     /* Open the screen and window */
  169.     
  170.    if ((NewWindowStructure1.Screen = CustScr =
  171.       (struct Screen *)OpenScreen(&NewScreenStructure)) == NULL)
  172.       PError("Can't open new screen");
  173.       
  174.    if (( Wdw = (struct Window *)OpenWindow(&NewWindowStructure1)) == NULL)
  175.    {
  176.       CloseScreen(CustScr);
  177.       PError("Can't open new window");
  178.    }
  179.    
  180.    ScreenOpen = TRUE;
  181.       
  182.     /* Find the viewport and load color map */
  183.  
  184.    WVP = (struct ViewPort *)ViewPortAddress(Wdw);
  185.    LoadRGB4(WVP,&Palette[0],PENS);
  186.  
  187.    /* Create and attach the menu */
  188.  
  189.    VI = GetVisualInfo(CustScr,NULL);
  190.    if (VI == NULL)
  191.       PError("Could not get VisualInfo");
  192.    SpadesMenu = CreateMenus(&SpadesNewMenu[0],GTMN_FrontPen,BLKP);
  193.    if (SpadesMenu == NULL)
  194.       PError("Could not create Menu");
  195.    success = LayoutMenus(SpadesMenu,VI,NULL);
  196.    if (success == FALSE)
  197.       PError("Could not layout Menu");
  198.    SetMenuStrip(Wdw,SpadesMenu);
  199.  
  200.    /* Seed random number generator with TIMER */
  201.  
  202.    srand(time(NULL));
  203. }
  204.  
  205. /**********************************************************
  206. * Function: PError                                        *
  207. * Parameters: s -- pointer to string to print             *
  208. * Return Values: None                                     *
  209. * Purpose: Handle a fatal error                           *
  210. **********************************************************/
  211. void PError(s)
  212. char *s;
  213. {
  214.    ErrorES.es_TextFormat = s;
  215.    
  216.    if (ScreenOpen)
  217.          (void)EasyRequest(Wdw,&ErrorES,NULL,NULL);
  218.    else
  219.          (void)EasyRequest(NULL,&ErrorES,NULL,NULL);
  220.  
  221.    WrapUp();
  222. }
  223.  
  224. /**********************************************************
  225. * Function: WrapUp                                        *
  226. * Parameters: none                                        *
  227. * Return Values: none                                     *
  228. * Purpose: close everything and exit                      *
  229. **********************************************************/
  230. void WrapUp()
  231. {
  232.    if (CardData)      FreeMem((char *)CardData,CARDMEMSIZE);
  233.    if (SpadesMenu)    FreeMenus(SpadesMenu);
  234.    if (Wdw)           CloseWindow(Wdw);
  235.    if (VI)            FreeVisualInfo(VI);
  236.    if (CustScr)       CloseScreen(CustScr);
  237.    if (GfxBase)       CloseLibrary(GfxBase);
  238.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  239.    exit(0);
  240. }
  241.  
  242. /**********************************************************
  243. * Function: Spades                                        *
  244. * Parameters: None                                        *
  245. * Return Values: None                                     *
  246. * Purpose: Play a game of spades. Loop until someone      *
  247. *          scores 500.                                    *
  248. **********************************************************/
  249. void Spades()
  250. {
  251.    AllDone=FALSE;
  252.  
  253.    /* Loop until player no longer wants to play. */
  254.   
  255.    while (!AllDone)
  256.    {
  257.       PlayerScore=CompScore=0;
  258.       HandLead=FindDealer();
  259.       PlayerBags=CompBags=0;
  260.       
  261.       /* Loop until someone reaches 500 and there is no tie. */
  262.  
  263.       while (((PlayerScore<500)&&(CompScore<500))||
  264.             (PlayerScore==CompScore))
  265.       {
  266.          SetUpScreen();
  267.          InitVars();
  268.          PrintScore();
  269.          DealCards();
  270.          GetBids();
  271.          PrintBids();
  272.          PlayHand();
  273.       }
  274.  
  275.       FinishRoutine();
  276.    }
  277. }
  278.  
  279. /**********************************************************
  280. * Function: FindDealer                                    *
  281. * Parameters: none                                        *
  282. * Return Values: the player determined to initially deal. *
  283. * Purpose: find out who deals first in a game.            *
  284. **********************************************************/
  285. int FindDealer()
  286. {
  287.    int player=0, card=0, i;
  288.    BOOL done=FALSE;
  289.  
  290.    SetRast(RP,BLUP);    /* Clear Screen */
  291.    SetAPen(RP,YELP);
  292.    SetBPen(RP,BLUP);
  293.  
  294.    for (i=0 ; i<52 ; i++) Deck[i]=0;   /* Set deck to undealt */
  295.  
  296.     Move(RP,70,70);         /* Warn player of what's happening */
  297.    Text(RP,"Ace of Spades",13);
  298.    Move(RP,98,78);
  299.    Text(RP,"deals",5);
  300.  
  301.    while(!done)            /* Loop until dealer found */
  302.    {
  303.       while(Deck[card=rand()%52]) ;    /* Find undealt card  */
  304.       Deck[card]=1;                    /* Mark card as dealt */
  305.       DrawCard(CardX[player],CardY[player],card);  /* Draw card */
  306.       Delay(10);           /* Pause */
  307.       if (card==51)        /* Ace of Spades */
  308.       {
  309.          done=TRUE;
  310.          Move(RP,MsgX[player],MsgY[player]);
  311.          Text(RP,"*",1);
  312.       }
  313.       player=(++player)%4;    /* Increment player */
  314.    }
  315.   
  316.    Move(RP,200,150);          /* Wait for player */
  317.    Text(RP,"Click mouse",11);
  318.    ReadMouse();
  319.  
  320.    SetRast(RP,BLUP);
  321.    return((++player)%4);   /* Must return player 2 to left of
  322.                               dealer. Program will later
  323.                               decrement player to find new dealer
  324.                               who should be to left of current dealer */
  325. }
  326.   
  327. /**********************************************************
  328. * Function: InitVars                                      *
  329. * Parameters: none                                        *
  330. * Return Values: none                                     *
  331. * Purpose: Initialize variables and arrays for a new hand.*
  332. **********************************************************/
  333. void InitVars()
  334. {
  335.    int i;
  336.  
  337.    /* Set Leader */
  338.  
  339.    HandLead=(--HandLead+4)%4;
  340.    TrickLead=HandLead;
  341.  
  342.    /* Reset HighCardLeft */
  343.  
  344.    HighCardLeft[0]=12;
  345.    HighCardLeft[1]=12;
  346.    HighCardLeft[2]=12;
  347.    HighCardLeft[3]=12;
  348.    
  349.    /* Reset OutOfSuit */
  350.   
  351.    for (i=0 ; i<4 ; i++)
  352.    {
  353.       OutOfSuit[i][DIAMONDS]=FALSE;
  354.       OutOfSuit[i][CLUBS]   =FALSE;
  355.       OutOfSuit[i][HEARTS]  =FALSE;
  356.       OutOfSuit[i][SPADES]  =FALSE;
  357.    }
  358.   
  359.    /* Determine Modes */
  360.    
  361.    for (i=0 ; i<4 ; i++)
  362.    {
  363.       Mode[i]=0;
  364.       if (i==HandLead) Mode[i]+=2;  /* Leader should bid higher */
  365.       if (i==0||i==2)               /* Human players -- check score */
  366.       {
  367.          if ((PlayerScore>400)&&(CompScore<350)) Mode[i]-=1;
  368.          if (PlayerScore<(CompScore-100)) Mode[i]+=1;
  369.          if (PlayerScore<(CompScore-200)) Mode[i]+=1;
  370.          if (PlayerScore>(CompScore+100)) Mode[i]-=1;
  371.       }
  372.       if (i==1||i==3)               /* Computer players -- check score */
  373.       {
  374.          if ((CompScore>400)&&(PlayerScore<350)) Mode[i]-=1;
  375.          if (CompScore<(PlayerScore-100)) Mode[i]+=1;
  376.          if (CompScore<(PlayerScore-200)) Mode[i]+=1;
  377.          if (CompScore>(PlayerScore+100)) Mode[i]-=1;
  378.       }
  379.    }
  380. }
  381.  
  382. /**********************************************************
  383. * Function: DealCards                                     *
  384. * Parameters: none                                        *
  385. * Return Values: none                                     *
  386. * Purpose: Shuffle & deal the deck to the players.        *
  387. **********************************************************/
  388. void DealCards()
  389. {
  390.    int i,j,player,cardnum[4];
  391.   
  392.    for (i=0 ; i<4 ; i++) cardnum[i]=0; /* Reset cards for each player */
  393.    for (i=0 ; i<52 ; i++) Deck[i]=0;   /* Set whole deck to undealt   */
  394.   
  395.    /* Shuffle and Deal Deck */
  396.   
  397.    for (i=0 ; i<52 ; i++)
  398.    {
  399.       while(Deck[j=rand()%52]) ;    /* Find undealt card */
  400.       Deck[j]=((i/13)+1);           /* Store owning player */
  401.    }
  402.   
  403.    /* Transfer cards to player hands */
  404.  
  405.    for (i=0 ; i<52 ; i++)
  406.    {
  407.       player=Deck[i]-1;                    /* Get owning player */
  408.       Hand[player][cardnum[player]++]=i+1; /* Store card, increment counter */
  409.    }
  410. }
  411.  
  412. /**********************************************************
  413. * Function: itoa                                          *
  414. * Parameters: n -- number to convert                      *
  415. *             s -- pointer to result string               *
  416. * Return Values: none                                     *
  417. * Purpose: Convert an integer to a string so it can be    *
  418. *          used by the Text function. Lattice does not    *
  419. *          have one.                                      *
  420. **********************************************************/
  421. void itoa(n,s)
  422. char *s;
  423. int n;
  424. {
  425.    int i=0;
  426.    BOOL sign=FALSE;
  427.   
  428.    if (n<0)
  429.    {
  430.       sign=TRUE;
  431.       n=-n;
  432.    }
  433.  
  434.    do
  435.    {
  436.       s[i++]=n%10+'0';
  437.    } while((n/=10)>0);
  438.  
  439.    if (sign) s[i++]='-';
  440.    s[i]='\0';
  441.    strrev(s);
  442. }
  443.