home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / On The Edge 3.0 / main.c next >
Encoding:
Text File  |  1994-12-12  |  14.1 KB  |  596 lines  |  [TEXT/KAHL]

  1. // On the Edge
  2.  
  3. #include "main.h"
  4.  
  5. #define FindSuit(card) ( (card) & 3 )
  6. #define FindValue(card) ( ( (card) >> 2 ) + 1 )
  7.  
  8. WindowPtr myWindow;
  9. Handle suits;
  10. Byte deck[52];
  11. Byte grid[4][4];
  12. Boolean multiple[4][4];
  13. Byte deckPos;
  14. Boolean finished = false, gameInProgress = false, selectingMultiples = false;
  15. Boolean colorQDAvail;
  16. RGBColor litGray = {0xE000, 0xE000, 0xE000},
  17.          midGray = {0xD000, 0xD000, 0xD000},
  18.          drkGray = {0xA000, 0xA000, 0xA000};
  19.  
  20. void main( void )
  21. {
  22.     Initialize( );
  23.     
  24.     RetrieveResources( );
  25.     
  26.     EmptyGrid( );
  27.     
  28.     do EventLoop( ); 
  29.     while( !finished );
  30. }
  31.  
  32. void StartGame( void )
  33. {
  34.     DialogPtr myDialog;
  35.     short response;
  36.     
  37.     if( gameInProgress )
  38.     {
  39.         myDialog = GetNewDialog( 129, nil, (WindowPtr) -1L );
  40.         
  41.         ShowWindow( myDialog );
  42.         SetPort( myDialog );
  43.         
  44.         OutlineButton( myDialog, iYes );
  45.         
  46.         ModalDialog( nil, &response );
  47.         
  48.         DisposDialog( myDialog );
  49.         
  50.         if( response == iNo )
  51.             return;
  52.     }
  53.     
  54.     gameInProgress = true;
  55.     
  56.     selectingMultiples = false;
  57.     
  58.     EmptyGrid( );
  59.  
  60.     SetPort( myWindow );
  61.     BackColor( whiteColor );
  62.     EraseRect( &( myWindow->portRect ) );
  63.     RedrawWindow( );
  64. }
  65.  
  66. void EmptyGrid( void )
  67. {
  68.     short count, count2;
  69.         
  70.     for( count = 0; count <= 3; count++ )
  71.     {
  72.         for( count2 = 0; count2 <= 3; count2++ )
  73.         {
  74.             grid[count][count2] = Empty;
  75.             multiple[count][count2] = false;
  76.         }
  77.     }
  78.     
  79.     Shuffle( );
  80. }
  81.  
  82. void PromptMessage( short messageID )
  83. {
  84.     Str255 message;
  85.     
  86.     GetIndString( message, 128, messageID );
  87.     
  88.     SetPort( myWindow );
  89.     MoveTo( 20, 290 );
  90.     TextFont( systemFont );
  91.     TextSize( 12 );
  92.     ForeColor( blackColor );
  93.     
  94.     DrawString( message );
  95. }
  96.  
  97. void ClearMessage( void )
  98. {
  99.     Rect myRect = {257, 0, 320, 256};
  100.     
  101.     BackColor( whiteColor );
  102.     EraseRect( &myRect );
  103. }
  104.  
  105. void EventLoop( void )
  106. {
  107.     EventRecord e;
  108.     WindowPtr window;
  109.     short part;
  110.     
  111.     do {
  112.         SetCursor( &qd.arrow );
  113.         WaitNextEvent( everyEvent, &e, -1L, nil );
  114.         
  115.         switch( e.what )
  116.         {
  117.             case keyDown:
  118.             if( e.modifiers & cmdKey )
  119.                 HandleMenus( MenuKey( e.message & charCodeMask ) );
  120.             break;
  121.             
  122.             case mouseDown:
  123.             part = FindWindow( e.where, &window );
  124.             switch( part )
  125.             {        
  126.                 case inDrag:
  127.                 DragWindow( window, e.where, &qd.screenBits.bounds );
  128.                 break;
  129.                 
  130.                 case inMenuBar:
  131.                 HandleMenus( MenuSelect( e.where ) );
  132.                 break;
  133.                 
  134.                 case inSysWindow:
  135.                 SystemClick( &e, window );
  136.                 break;
  137.                 
  138.                 case inContent:
  139.                 SetPort( window );
  140.                 GlobalToLocal( &e.where );
  141.                 HandleClick( &e.where );
  142.                 break;
  143.             }
  144.             break;
  145.             
  146.             case updateEvt:    
  147.             BeginUpdate( (WindowPtr) e.message );
  148.             SetPort( (WindowPtr) e.message );
  149.             RedrawWindow( );
  150.             EndUpdate( (WindowPtr) e.message );
  151.             break;
  152.         }
  153.     }
  154.     while( !finished );
  155. }
  156.  
  157. void HandleMenus( long selection )
  158. {
  159.     register short menu, item;
  160.     
  161.     menu = selection>>16;
  162.     item = (short) selection;
  163.  
  164.     switch( menu )
  165.     {
  166.         case mApple:
  167.         
  168.         if( item == iAbout )
  169.         {
  170.             Alert( 128, nil );
  171.         }
  172.         else
  173.         {
  174.             MenuHandle appleMenu;
  175.             Str255 deskAccessory;
  176.             
  177.             appleMenu = GetMHandle( mApple );
  178.             GetItem( appleMenu, item, deskAccessory );
  179.             OpenDeskAcc( deskAccessory );
  180.         }
  181.         break;
  182.         
  183.         case mFile:
  184.         switch( item )
  185.         {
  186.             case iPlay:
  187.             StartGame( );
  188.             break;
  189.             
  190.             case iHelp:
  191.             Alert( 130, nil );
  192.             Alert( 131, nil );
  193.             break;
  194.             
  195.             case iQuit:
  196.             finished = true;
  197.             break;
  198.         }
  199.         break;
  200.         
  201.         case mEdit:
  202.         break;
  203.     }
  204.     HiliteMenu( 0 );
  205.         
  206. }
  207.  
  208. void HandleClick( Point *wherePtr )
  209. {
  210.     if( gameInProgress )
  211.     {
  212.         if( selectingMultiples )
  213.             SelectMultiples( wherePtr );
  214.         else
  215.             PlaceCards( wherePtr );
  216.     }
  217. }
  218.  
  219. void SelectMultiples( Point *wherePtr )
  220. {
  221.     Rect myRect;
  222.     Point where;
  223.     short total = 0, count, count2;
  224.     
  225.     where = *wherePtr;
  226.     
  227.     where.h >>= 6;
  228.     where.v >>= 6;
  229.     
  230.     if( where.v > 3 )
  231.     {
  232.         FinishSelecting( );
  233.         return;
  234.     }
  235.     
  236.     for( count = 0; count <=3; count++ )
  237.     {
  238.         for( count2 = 0; count2 <=3; count2++ )
  239.         {
  240.             if( multiple[count][count2] )
  241.                 total += FindValue( grid[count][count2] );
  242.         }
  243.     }
  244.     
  245.     if( multiple[where.h][where.v] )
  246.     {
  247.         multiple[where.h][where.v] = false;
  248.         DrawSquare( where.h, where.v );
  249.         return;
  250.     }
  251.     else
  252.     {
  253.         total += FindValue( grid[where.h][where.v] );
  254.         
  255.         if( total > 10 )
  256.             return;
  257.         
  258.         multiple[where.h][where.v] = true;
  259.         DrawSquare( where.h, where.v );
  260.         
  261.         if( total == 10 )
  262.         {
  263.             for( count = 0; count <=3; count++ )
  264.             {
  265.                 for( count2 = 0; count2 <=3; count2++ )
  266.                 {
  267.                     if( multiple[count][count2] )
  268.                     {
  269.                         grid[count][count2] = Empty;
  270.                         multiple[count][count2] = false;
  271.                         
  272.                         DrawSquare( count, count2 );
  273.                     }
  274.                 }
  275.             }
  276.         }
  277.     }
  278. }
  279.  
  280. void PlaceCards( Point *wherePtr )
  281. {
  282.     Point where;
  283.     Byte currentCard, cardValue;
  284.     short count, count2;
  285.     
  286.     where = *wherePtr;
  287.     
  288.     where.h >>= 6;
  289.     where.v >>= 6;
  290.     
  291.     if( where.v > 3 )
  292.         return;
  293.     
  294.     if( grid[ where.h ][ where.v ] != Empty )
  295.         return;
  296.     
  297.     currentCard = deck[ deckPos ];
  298.     cardValue = FindValue( currentCard );
  299.     
  300.     if( cardValue == King &&
  301.         !( (where.h == 0 || where.h == 3 ) &&
  302.            (where.v == 0 || where.v == 3 ) )
  303.       )
  304.         return;
  305.     
  306.     if( cardValue == Queen &&
  307.         !( (where.h == 1 && where.v == 0) ||
  308.            (where.h == 2 && where.v == 0) ||
  309.            (where.h == 1 && where.v == 3) ||
  310.            (where.h == 2 && where.v == 3) )
  311.       )
  312.         return;
  313.     
  314.     if( cardValue == Jack &&
  315.         !( (where.h == 0 && where.v == 1) ||
  316.            (where.h == 0 && where.v == 2) ||
  317.            (where.h == 3 && where.v == 1) ||
  318.            (where.h == 3 && where.v == 2) )
  319.       )
  320.         return;
  321.     
  322.     grid[where.h][where.v] = currentCard;
  323.     
  324.     DrawCard( currentCard, where.h, where.v );
  325.     
  326.     if( FindValue(grid[0][0]) == King && FindValue(grid[0][3]) == King &&
  327.         FindValue(grid[3][0]) == King && FindValue(grid[3][3]) == King &&
  328.         FindValue(grid[1][0]) == Queen && FindValue(grid[2][0]) == Queen &&
  329.         FindValue(grid[1][3]) == Queen && FindValue(grid[2][3]) == Queen &&
  330.         FindValue(grid[0][1]) == Jack && FindValue(grid[0][2]) == Jack &&
  331.         FindValue(grid[3][1]) == Jack && FindValue(grid[3][2]) == Jack )
  332.     {
  333.         ClearMessage( );
  334.         
  335.         PromptMessage( msgYouWin );
  336.         
  337.         gameInProgress = false;
  338.         
  339.         return;
  340.     }
  341.     
  342.     selectingMultiples = true;
  343.     for( count = 0; count<=3; count++ )
  344.     {
  345.         for( count2 = 0; count2<=3; count2++ )
  346.         {
  347.             if( grid[count][count2] == Empty )
  348.                 selectingMultiples = false;
  349.         }
  350.     }
  351.     
  352.     if( selectingMultiples )
  353.     {
  354.         StartSelecting( );
  355.         return;
  356.     }
  357.     
  358.     DrawNewCard( );
  359. }
  360.  
  361. void StartSelecting( void )
  362. {
  363.     ClearMessage( );
  364.     
  365.     PromptMessage( msgSelectMultOf10 );
  366. }
  367.  
  368. void FinishSelecting( void )
  369. {
  370.     Rect myRect;
  371.     short count, count2;
  372.     
  373.     ClearMessage( );
  374.     
  375.     for( count = 0; count <= 3; count++ )
  376.     {
  377.         for( count2 = 0; count2 <= 3; count2++ )
  378.         {
  379.             if( multiple[count][count2] == true )
  380.             {
  381.                 multiple[count][count2] = false;
  382.                 DrawSquare( count, count2 );
  383.             }
  384.             
  385.             if( grid[count][count2] == Empty )
  386.             {
  387.                 selectingMultiples = false;
  388.             }
  389.         }
  390.     }
  391.     
  392.     if( selectingMultiples )
  393.     {
  394.         gameInProgress = selectingMultiples = false;
  395.         
  396.         ClearMessage( );
  397.         PromptMessage( msgGameOver );
  398.         
  399.         return;
  400.     }
  401.     
  402.     DrawNewCard( );
  403. }
  404.  
  405. void DrawNewCard( void )
  406. {
  407.     short currentCard, cardValue;
  408.     
  409.     currentCard = deck[ ++deckPos ];
  410.     cardValue = FindValue( currentCard );
  411.     DrawCard( currentCard, 3, 4 );
  412.     
  413.     if( ( cardValue == King &&
  414.           !( (grid[0][0] == Empty) ||
  415.              (grid[0][3] == Empty) ||
  416.              (grid[3][0] == Empty) ||
  417.              (grid[3][3] == Empty) )
  418.         )
  419.      || ( cardValue == Queen &&
  420.           !( (grid[1][0] == Empty) ||
  421.              (grid[2][0] == Empty) ||
  422.              (grid[1][3] == Empty) ||
  423.              (grid[2][3] == Empty) )
  424.         )
  425.      || ( cardValue == Jack &&
  426.            !( (grid[0][1] == Empty) ||
  427.              (grid[0][2] == Empty) ||
  428.              (grid[3][1] == Empty) ||
  429.              (grid[3][2] == Empty) )
  430.         )
  431.       )
  432.     {
  433.         gameInProgress = false;
  434.         
  435.         PromptMessage( msgGameOver );
  436.     }
  437. }
  438.  
  439. void RedrawWindow( void )
  440. {
  441.     short count, count2;
  442.     Rect myRect;
  443.     
  444.     for( count = 0; count<=3; count++ )
  445.     {
  446.         for( count2 = 0; count2<=3; count2++ )
  447.         {
  448.             DrawSquare( count2, count );
  449.         }
  450.     }
  451.     
  452.     if( selectingMultiples )
  453.         PromptMessage( msgSelectMultOf10 );
  454.     else
  455.         DrawCard( deckPos < 52? deck[deckPos]: Empty, 3, 4 );
  456.     
  457.     if( !gameInProgress )
  458.     {
  459.         PromptMessage( msgGameOver );
  460.     }
  461. }
  462.  
  463. void DrawSquare( short x, short y )
  464. {
  465.     Rect myRect;
  466.     
  467.     myRect.top = y*64;
  468.     myRect.bottom = myRect.top + 65;
  469.     myRect.left = x*64;
  470.     myRect.right = myRect.left + 65;
  471.     
  472.     ForeColor( blueColor );
  473.     FrameRect( &myRect );
  474.  
  475.     InsetRect( &myRect, 1, 1 );
  476.     if( colorQDAvail )
  477.     {
  478.         RGBBackColor( &litGray );
  479.         EraseRect( &myRect );
  480.         ForeColor( whiteColor );
  481.         FrameRect( &myRect );
  482.         
  483.         InsetRect( &myRect, 1, 1 );
  484.         FrameRect( &myRect );
  485.         InsetRect( &myRect, -1, -1 );
  486.         
  487.         RGBForeColor( &drkGray );
  488.         MoveTo( myRect.right-1, myRect.top );
  489.         LineTo( myRect.right-1, myRect.bottom-1 );
  490.         LineTo( myRect.left, myRect.bottom-1 );
  491.         LineTo( myRect.left+1, myRect.bottom-2 );
  492.         LineTo( myRect.right-2, myRect.bottom-2 );
  493.         LineTole );
  494. }
  495.  
  496. void Initialize( void )
  497. {
  498.     SysEnvRec thisSysInfo;
  499.     
  500.     MaxApplZone( );    
  501.     MoreMasters( );
  502.  
  503.     InitGraf( &qd.thePort );
  504.     InitFonts( );
  505.     FlushEvents( everyEvent, 0L );
  506.     InitWindows( );
  507.     InitMenus( );
  508.     TEInit( );
  509.     InitDialogs( 0L );
  510.     InitCursor( );
  511.  
  512.     // GetDateTime( (unsigned long *)( &randSeed ) ); // seed the random # generator
  513.     GetDateTime( (unsigned long *)LMGetRndSeed() );
  514.     
  515.     SysEnvirons( curSysEnvVers, &thisSysInfo );
  516.     colorQDAvail = thisSysInfo.hasColorQD;
  517. }
  518.  
  519. void RetrieveResources( void )
  520. {
  521.     short count;
  522.     Handle menuBar;
  523.     MenuHandle menu;
  524.     
  525.     // menus
  526.     
  527.     menuBar = GetNewMBar( 128 );
  528.     if( menuBar == nil )
  529.     {
  530.         SysBeep( 1 );
  531.         ExitToShell( );
  532.     }
  533.     
  534.     SetMenuBar( menuBar );
  535.     
  536.     menu = GetMHandle( mApple );
  537.     AddResMenu( menu, 'DRVR' );
  538.     
  539.     DrawMenuBar( );
  540.     
  541.     // window
  542.     
  543.     if( colorQDAvail )
  544.         myWindow = GetNewCWindow( 128, nil, (WindowPtr) -1L );
  545.     else
  546.         myWindow = GetNewWindow( 128, nil, (WindowPtr) -1L );
  547.     
  548.     if( myWindow == nil )
  549.     {
  550.         SysBeep( 1 );
  551.         ExitToShell( );
  552.     }
  553.     ShowWindow( myWindow );
  554.     SetPort( myWindow );
  555.     
  556.     // suit SICNs
  557.     
  558.     suits = GetResource( 'SICN', 128 );
  559. }
  560.  
  561. void Shuffle( void )
  562. {
  563.     short count, count2, swap, temp;
  564.     
  565.     deckPos = 0;
  566.     
  567.     for( count = 0; count <= 51; count++ )
  568.     {
  569.         deck[count] = count;
  570.     }
  571.     
  572.     for( count2 = 1; count2 <= 20; count2++ )
  573.     {
  574.         for( count = 0; count <= 51; count++ )
  575.         {
  576.             swap = RandomBefore( 52 );
  577.             temp = deck[ count ];
  578.             deck[ count ] = deck[ swap ];
  579.             deck[ swap ] = temp;
  580.         }
  581.     }
  582. }
  583.  
  584. short RandomBefore( short what )
  585. {
  586.     short random;
  587.     
  588.     random = Random( );
  589.     
  590.     if( random < 0 )
  591.         random = -random;
  592.     
  593.     random %= what;
  594.     
  595.     return random;
  596. }