home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / Battleship 2.1 / Battleship.sounds.c next >
Encoding:
C/C++ Source or Header  |  1994-06-07  |  31.5 KB  |  1,588 lines  |  [TEXT/KAHL]

  1. #include    "Battleship.sounds.h"
  2.  
  3. /********/
  4. /* main */
  5. /********/
  6.  
  7. void    main ( void )
  8. {
  9.     ToolBoxInit ();
  10.     MenuBarInit ();
  11.     
  12.     HandleAppleChoice ( iAbout );
  13.     useColor = IsColour();
  14.  
  15.     WindowInit ();
  16.     PlaceEnemyShips ();
  17.     
  18.     NewGame ();
  19.     EventLoop ();
  20. }
  21.             
  22.  
  23. /**************/
  24. /* ToolBoxInit*/
  25. /**************/
  26.  
  27. void    ToolBoxInit ( void )
  28. {
  29.     InitGraf ( &thePort );
  30.     InitFonts ();
  31.     InitWindows ();
  32.     InitMenus ();
  33.     TEInit ();
  34.     InitDialogs ( nil );
  35.     InitCursor ();
  36. }
  37.  
  38. /**************/
  39. /* WindowInit */
  40. /**************/
  41.  
  42. void    WindowInit ( void )
  43. {
  44.     if ( useColor )
  45.         youWindow = GetNewCWindow ( kYouWindowID, nil, kMoveToFront );
  46.     else
  47.         youWindow = GetNewWindow ( kYouWindowID, nil, kMoveToFront );
  48.     
  49.     if ( youWindow == nil )
  50.     {
  51.         SysBeep ( 10 );
  52.         ExitToShell ();
  53.     }
  54.     
  55.     SetWRefCon ( youWindow, (long) kYouWindowID );
  56.  
  57.     SetPort ( youWindow );
  58.     ShowWindow ( youWindow );
  59.  
  60.     if ( useColor )
  61.         enemyWindow = GetNewCWindow ( kEnemyWindowID, nil, kMoveToFront );
  62.     else
  63.         enemyWindow = GetNewWindow ( kEnemyWindowID, nil, kMoveToFront );
  64.     
  65.     if ( enemyWindow == nil )
  66.     {
  67.         SysBeep ( 10 );
  68.         ExitToShell ();
  69.     }
  70.     
  71.     SetWRefCon ( enemyWindow, (long) kEnemyWindowID );
  72.     SetPort ( enemyWindow );
  73.     ShowWindow ( enemyWindow );
  74. }
  75.  
  76.  
  77. /***************/
  78. /* MenuBarInit */
  79. /***************/
  80.  
  81. void    MenuBarInit ( void )
  82. {
  83.     Handle            menuBar;
  84.     MenuHandle        menu;
  85.     
  86.     menuBar = GetNewMBar ( kBaseResID );
  87.     SetMenuBar ( menuBar );
  88.     
  89.     menu = GetMHandle ( mApple );
  90.     AddResMenu ( menu, 'DRVR' );
  91.     
  92.     DrawMenuBar ();
  93.     
  94.     HandleSound ();
  95. }
  96.  
  97. /***************/
  98. /* HandleSound */
  99. /***************/
  100.  
  101. void    HandleSound ( void )
  102. {
  103.     MenuHandle    menuHandle;
  104.     
  105.     menuHandle = GetMHandle ( mOptions );
  106.     
  107.     
  108.     if ( gHasSound )
  109.     {
  110.         CheckItem ( menuHandle, iSound, kRemoveCheckMark );
  111.         gHasSound = !gHasSound;
  112.     }
  113.     else
  114.     {
  115.         CheckItem ( menuHandle, iSound, kAddCheckMark );
  116.         gHasSound = !gHasSound;
  117.     }
  118. }
  119.  
  120. /*************/
  121. /* EventLoop */
  122. /*************/
  123.  
  124. void    EventLoop ( void )
  125. {
  126.     EventRecord    event;
  127.     DialogPtr    dialog;
  128.     Boolean        dialogDone = FALSE;
  129.     int            result;
  130.     Handle        mySndHandle;
  131.     
  132.     gDone = false;
  133.     while ( gDone == false )
  134.     {
  135.         if ( WaitNextEvent ( everyEvent, &event, MAXLONG, nil ) )
  136.             DoEvent ( &event );
  137.  
  138.         if ( enemyCount >= 17 ) /* you win! */
  139.         {
  140.             SelectWindow ( enemyWindow );
  141.             SetPort ( enemyWindow );
  142.             DrawDots ( enemy );
  143.             
  144.             if ( gHasSound )
  145.             {
  146.                 mySndHandle = GetResource ( 'snd ', kYouWinSnd );
  147.                 if ( mySndHandle != NULL )
  148.                     SndPlay ( nil, mySndHandle, TRUE );
  149.             }
  150.             
  151.             dialog = GetNewDialog ( kBaseResID + 1, nil, kMoveToFront );
  152.             SetDialogDefaultItem ( dialog, ok );
  153.             SetDialogCancelItem ( dialog, cancel );
  154.             ParamText( kCongratulationsStr, kYouWinStr, "\p", "\p" );
  155.             SetPort ( dialog );
  156.             ShowWindow ( dialog );
  157.             while ( !dialogDone )
  158.             {
  159.                 ModalDialog ( nil, &result );
  160.                 
  161.                 switch ( result )
  162.                 {
  163.                     case ok:
  164.                         dialogDone = TRUE;
  165.                         DisposDialog  ( dialog );
  166.                         NewGame ();
  167.                         break;
  168.                     case cancel:
  169.                         DisposDialog  ( dialog );
  170.                         dialogDone = TRUE;
  171.                         gDone = TRUE;
  172.                         break;
  173.                 }
  174.             }
  175.             dialogDone = FALSE;
  176.         }
  177.         else if ( ( gYouHasGone ) && ( !gDone ) )
  178.         {
  179.             PickEnemyShot ();
  180.             gYouHasGone = !gYouHasGone;
  181.         }
  182.         if ( youCount >= 17 ) /* computer wins! */
  183.         {
  184.             SelectWindow ( enemyWindow );
  185.             SetPort ( enemyWindow );
  186.             DrawDots ( enemy );
  187.             
  188.             if ( gHasSound )
  189.             {
  190.                 mySndHandle = GetResource ( 'snd ', kYouLoseSnd );
  191.                 if ( mySndHandle != NULL )
  192.                     SndPlay ( nil, mySndHandle, TRUE );
  193.             }
  194.             
  195.             dialog = GetNewDialog ( kBaseResID + 1, nil, kMoveToFront );
  196.             SetDialogDefaultItem ( dialog, ok );
  197.             SetDialogCancelItem ( dialog, cancel );
  198.             ParamText( kSorryStr, kYouLoseStr, "\p", "\p" );
  199.             SetPort ( dialog );
  200.             ShowWindow ( dialog );
  201.             while ( !dialogDone )
  202.             {
  203.                 ModalDialog ( nil, &result );
  204.                 
  205.                 switch ( result )
  206.                 {
  207.                     case ok:
  208.                         dialogDone = TRUE;
  209.                         DisposDialog  ( dialog );
  210.                         NewGame ();
  211.                         break;
  212.                     case cancel:
  213.                         DisposDialog  ( dialog );
  214.                         dialogDone = TRUE;
  215.                         gDone = TRUE;
  216.                         break;
  217.                 }
  218.             }
  219.             dialogDone = FALSE;
  220.         }
  221.     }
  222. }
  223.  
  224.  
  225. /***********/
  226. /* DoEvent */
  227. /***********/
  228.  
  229. void    DoEvent ( EventRecord *eventPtr )
  230. {
  231.     Boolean    becomingActive;
  232.     char    theChar;
  233.     
  234.     switch ( eventPtr->what )
  235.     {
  236.         case mouseDown:
  237.             HandleMouseDown ( eventPtr );
  238.             break;
  239.         case keyDown:
  240.         case autoKey:
  241.             theChar = eventPtr->message & charCodeMask;
  242.             if ( (eventPtr->modifiers & cmdKey) != 0 )
  243.                 HandleMenuChoice ( MenuKey ( theChar ) );
  244.             break;
  245.         case updateEvt:
  246.             DoUpdate ( eventPtr );
  247.             break;
  248.         case activateEvt:
  249.             becomingActive = ( ( eventPtr->modifiers &activeFlag ) == activeFlag );
  250.             break;
  251.     }
  252. }
  253.  
  254. /*******************/
  255. /* HandleMouseDown */
  256. /*******************/
  257.  
  258. void    HandleMouseDown ( EventRecord *eventPtr )
  259. {
  260.     WindowPtr    window;
  261.     short int    thePart;
  262.     long        menuChoice;
  263.     
  264.     thePart = FindWindow ( eventPtr->where, &window );
  265.     
  266.     switch ( thePart )
  267.     {
  268.         case inMenuBar:
  269.             menuChoice = MenuSelect ( eventPtr->where );
  270.             HandleMenuChoice ( menuChoice );
  271.             break;
  272.         case inSysWindow:
  273.             SystemClick ( eventPtr, window );
  274.             break;
  275.         case inContent:
  276.             SelectWindow ( window );
  277.             if ( GetWRefCon ( window ) == kEnemyWindowID )
  278.             {
  279.                 SetPort ( window );
  280.                 CheckPoint ( eventPtr->where );
  281.             }
  282.             break;
  283.         case inDrag:
  284.             DragWindow ( window, eventPtr->where, &screenBits.bounds );
  285.             break;
  286.         case inGoAway:
  287.             if ( TrackGoAway ( window, eventPtr->where ) )
  288.                 gDone = true;
  289.             break;
  290.     }
  291. }
  292.  
  293. /************/
  294. /* DoUpdate */
  295. /************/
  296.  
  297. void    DoUpdate ( EventRecord *eventPtr )
  298. {
  299.     WindowPtr    window;
  300.     
  301.     window = ( WindowPtr ) eventPtr->message;
  302.     
  303.     BeginUpdate ( window );
  304.     
  305.     if ( GetWRefCon ( window ) == kEnemyWindowID )
  306.     {
  307.         SetPort ( window );
  308.         DrawDots ( enemy );
  309.     }
  310.  
  311.     if ( GetWRefCon ( window ) == kYouWindowID )
  312.     {
  313.         SetPort ( window );
  314.         DrawDots ( you );
  315.     }
  316.     
  317.     EndUpdate ( window );
  318. }
  319.  
  320. /********************/
  321. /* HandleMenuChoice */
  322. /********************/
  323.  
  324. void    HandleMenuChoice ( long menuChoice )
  325. {
  326.     short    menu;
  327.     short    item;
  328.     
  329.     if ( menuChoice != 0 )
  330.     {
  331.         menu = HiWord ( menuChoice );
  332.         item = LoWord ( menuChoice );
  333.         
  334.         switch ( menu )
  335.         {
  336.             case mApple:
  337.                 HandleAppleChoice ( item );
  338.                 break;
  339.             case mFile:
  340.                 HandleFileChoice ( item );
  341.                 break;
  342.             case mOptions:
  343.                 HandleOptionsChoice ( item );
  344.         }
  345.         
  346.         HiliteMenu ( 0 );
  347.     }
  348. }
  349.  
  350. /********************/
  351. /* HandleAppleChoice*/
  352. /********************/
  353.  
  354. void    HandleAppleChoice ( short item )
  355. {
  356.     MenuHandle    appleMenu;
  357.     Handle        mySndHandle;
  358.     Str255        accName;
  359.     short        accNumber;
  360.     DialogPtr    dialog;
  361.     Boolean        dialogDone = FALSE, showHelp = FALSE;
  362.     int            result;
  363.     
  364.     if ( gHasSound )
  365.     {
  366.         mySndHandle = GetResource ( 'snd ', kBombDropSnd );
  367.         if ( mySndHandle != NULL )
  368.             SndPlay ( nil, mySndHandle, TRUE );
  369.         
  370.         mySndHandle = GetResource ( 'snd ', kExplosionSnd );
  371.         if ( mySndHandle != NULL )
  372.             SndPlay ( nil, mySndHandle, TRUE );
  373.     }
  374.     
  375.     switch ( item )
  376.     {
  377.         case iAbout:
  378.             dialog = GetNewDialog ( kBaseResID + 3, nil, kMoveToFront );
  379.             ParamText( kVersionNumberStr, "\p", "\p", "\p" );
  380.             SetDialogDefaultItem ( dialog, ok );
  381.             SetDialogCancelItem ( dialog, cancel );
  382.             SetPort ( dialog );
  383.             ShowWindow ( dialog );
  384.             
  385.             while ( !dialogDone )
  386.             {
  387.                 ModalDialog ( nil, &result );
  388.                 
  389.                 switch ( result )
  390.                 {
  391.                     case ok:
  392.                         dialogDone = TRUE;
  393.                         break;
  394.                     case cancel:
  395.                         showHelp = TRUE;
  396.                         dialogDone = TRUE;
  397.                         break;
  398.                 }
  399.             }
  400.             DisposDialog  ( dialog );
  401.             dialogDone = FALSE;
  402.         
  403.             if ( showHelp )
  404.             {
  405.                 dialog = GetNewDialog ( kBaseResID + 4, nil, kMoveToFront );
  406.                 ParamText( kVersionNumberStr, "\p", "\p", "\p" );
  407.                 SetDialogDefaultItem ( dialog, ok );
  408.                 SetPort ( dialog );
  409.                 ShowWindow ( dialog );
  410.                 while ( !dialogDone )
  411.                 {
  412.                     ModalDialog ( nil, &result );
  413.                     
  414.                     switch ( result )
  415.                     {
  416.                         case ok:
  417.                             dialogDone = TRUE;
  418.                             break;
  419.                     }
  420.                 }
  421.                 DisposDialog  ( dialog );
  422.             }
  423.             break;
  424.         default:
  425.             appleMenu = GetMHandle ( mApple );
  426.             GetItem ( appleMenu, item, accName );
  427.             accNumber = OpenDeskAcc ( accName );
  428.             break;
  429.     }
  430. }
  431.  
  432. /********************/
  433. /* HandleFileChoice */
  434. /********************/
  435.  
  436. void     HandleFileChoice ( short item )
  437. {
  438.     switch ( item )
  439.     {
  440.         case iQuit:
  441.             gDone = TRUE;
  442.             break;
  443.         case iNew:
  444.             NewGame ();
  445.             break;
  446.     }
  447. }
  448.  
  449. /***********************/
  450. /* HandleOptionsChoice */
  451. /***********************/
  452.  
  453. void    HandleOptionsChoice ( short item )
  454. {
  455.     switch ( item )
  456.     {
  457.         case iSound:
  458.             HandleSound ();
  459.             break;
  460.     }
  461. }
  462.  
  463. /***********/
  464. /* NewGame */
  465. /***********/
  466.  
  467. void    NewGame ( void )
  468. {
  469.     int            i;
  470.     DialogPtr    dialog;
  471.     
  472.     youCount = 0;
  473.     enemyCount = 0;
  474.     shotCount = 0;
  475.     gYouHasGone = FALSE;
  476.     
  477.     for ( i = 0; i < kNumShips; i++ )
  478.         hitShips[i] = 0;
  479.     
  480.     GridInit ( enemy );
  481.     GridInit ( you );
  482.     SetPort ( enemyWindow );
  483.     DrawDots ( enemy );
  484.     SetPort ( youWindow );
  485.     DrawDots ( you );
  486.     PlaceEnemyShips ();
  487.     
  488.     dialog = GetNewDialog ( kBaseResID, nil, kMoveToFront );
  489.     SetDialogDefaultItem ( dialog, ok );
  490.     SetDialogCancelItem ( dialog, cancel );
  491.     ParamText( kRotateStr, kPlaceStr, "\p", "\p" );
  492.     SetPort ( dialog );
  493.     ShowWindow ( dialog );
  494.     DrawDialog ( dialog );
  495.     
  496.     SelectWindow ( youWindow );
  497.     SetPort ( youWindow );
  498.     
  499.     PlaceAShip ( kCarrierMin, kCarrierMax, kHorizCarrierID, kCarrier );
  500.     PlaceAShip ( kBattleshipMin, kBattleshipMax, kHorizBattleshipID, kBattleship );
  501.     PlaceAShip ( kCruiserMin, kCruiserMax, kHorizCruiserID, kCruiser );
  502.     PlaceAShip ( kSubMin, kSubMax, kHorizSubID, kSub );
  503.     PlaceAShip ( kDestroyerMin, kDestroyerMax, kHorizDestroyerID, kDestroyer );
  504.     
  505.     DisposeDialog ( dialog );
  506.     
  507.     SelectWindow ( enemyWindow );
  508.     SetPort ( enemyWindow );
  509. }
  510.  
  511. /**************/
  512. /* PlaceAShip */
  513. /**************/
  514.  
  515. void    PlaceAShip ( int theMin, int theMax, int theHorizID, int theShip )
  516. {
  517.     EventRecord            event;
  518.     Point                thePoint, tempPoint, oldPoint;
  519.     Rect                theRect, tempRect, oldRect;
  520.     char                theChar;
  521.     Boolean                horiz = TRUE, oldHoriz = TRUE;
  522.     
  523.     do /* gets a random temp point for the placement of the first ship */
  524.     {
  525.         tempPoint.v = Randomize ();
  526.         tempPoint.h = Randomize ();
  527.         
  528.         Inbounds ( &tempPoint, horiz, theMin, theMax );
  529.  
  530.     } while ( !ItFits ( horiz, tempPoint, theMin, theMax ) );
  531.     
  532.     PtToShipRect ( tempPoint, &oldRect, horiz, theMin, theMax );
  533.     PtToRect ( tempPoint, &tempRect );
  534.     oldPoint = tempPoint;
  535.     
  536.     DrawShipPart ( theHorizID, oldRect );
  537.     
  538.     while ( !Button () )
  539.     {
  540.         GetMouse ( &thePoint );
  541.  
  542.         if ( WaitNextEvent ( everyEvent, &event, MAXLONG, nil ) )
  543.         {
  544.             if ( ( event.what == keyDown ) || ( event.what == autoKey ) )
  545.                 horiz = !horiz;
  546. /*            theChar = event.message & charCodeMask;
  547.             if ( theChar == 'm' )
  548.                 horiz = !horiz;
  549. */        }
  550.         
  551.         tempPoint.v = thePoint.v / kPixelSize;
  552.         tempPoint.h = thePoint.h / kPixelSize;
  553.         
  554.         /* This is really long.  If someone can shorten it, I would appreciate it. */
  555.         if (         ( !PtInRect ( thePoint, &tempRect ) ) &&
  556.                     ( Inbounds ( &tempPoint, horiz, theMin, theMax ) ) && 
  557.                     ( ItFits ( horiz, tempPoint, theMin, theMax ) ) && 
  558.                     ( ( oldPoint.h != tempPoint.h ) || ( oldPoint.v != tempPoint.v ) ) || 
  559.                     ( ( oldHoriz != horiz ) &&
  560.                     ( Inbounds ( &tempPoint, horiz, theMin, theMax ) ) &&
  561.                     ( ItFits ( horiz, tempPoint, theMin, theMax ) ) ) )
  562.         {
  563.             EraseShipPart ( oldRect );
  564.             
  565.             if ( oldHoriz )
  566.                 DrawHorizDots ( oldPoint, tempPoint, &theRect, theMin, theMax );
  567.             else
  568.                 DrawVertDots ( oldPoint, tempPoint, &theRect, theMin, theMax );
  569.             
  570.             PtToShipRect ( tempPoint, &tempRect, horiz, theMin, theMax );
  571.             if ( horiz )
  572.                 DrawShipPart ( theHorizID, tempRect );
  573.             else
  574.                 DrawShipPart ( theHorizID + 1, tempRect );
  575.     
  576.             PtToShipRect ( tempPoint, &oldRect, horiz, theMin, theMax );
  577.             PtToRect ( tempPoint, &tempRect );
  578.             oldPoint = tempPoint;
  579.             oldHoriz = horiz;
  580.         }
  581.         else if ( horiz != oldHoriz )
  582.             horiz = oldHoriz;
  583.     }
  584.     
  585.     SetShipToGrid ( you, oldPoint, horiz, theMin, theMax, theShip );
  586.     
  587.     while ( Button () );
  588. }
  589.  
  590. /**********/
  591. /* ItFits */
  592. /**********/
  593.  
  594. Boolean    ItFits ( Boolean horiz, Point thePoint, int theMin, int theMax )
  595. {
  596.     Boolean fits = FALSE;
  597.     
  598.     if  ( horiz )
  599.         fits = FitsHoriz ( you, thePoint.h - theMin, thePoint.v, 1 + theMin + theMax );
  600.     else
  601.         fits = FitsVert ( you, thePoint.h, thePoint.v - theMin, 1 + theMin + theMax );
  602.         
  603.     return ( fits );
  604. }
  605.  
  606. /*****************/
  607. /* DrawHorizDots */
  608. /*****************/
  609.  
  610. void    DrawHorizDots ( Point aPoint, Point tempPoint, Rect *theRect, int min, int max )
  611. {
  612.     int            i = aPoint.h;
  613.     int            test = i + max;
  614.     PicHandle    picture;
  615.     
  616.     picture = GetPicture ( kNullDotID );
  617.     if ( picture == nil )
  618.     {
  619.         SysBeep ( 10 );
  620.         ExitToShell ();
  621.     }
  622.     
  623.     for ( aPoint.h = i - min; aPoint.h <= test; aPoint.h++ ) 
  624.     {
  625.         /* PtToDotRect ( aPoint, theRect ); */
  626.         (*theRect).left = ( aPoint.h + 1 ) * 19 - 10;
  627.         (*theRect).top = ( aPoint.v + 1 ) * 19 - 10;
  628.         (*theRect).right = ( aPoint.h + 1 ) * 19;
  629.         (*theRect).bottom = ( aPoint.v + 1 ) * 19;
  630.         
  631.         DrawPicture ( picture, theRect );
  632.     }
  633.     
  634. }
  635.  
  636. /****************/
  637. /* DrawVertDots */
  638. /****************/
  639.  
  640. void    DrawVertDots ( Point aPoint, Point tempPoint, Rect *theRect, int min, int max )
  641. {
  642.     int         i = aPoint.v;
  643.     int            test = i + max;
  644.     PicHandle    picture;
  645.     
  646.     picture = GetPicture ( kNullDotID );
  647.     if ( picture == nil )
  648.     {
  649.         SysBeep ( 10 );
  650.         ExitToShell ();
  651.     }
  652.     
  653.     for ( aPoint.v = i - min; aPoint.v <= test; aPoint.v++ )
  654.     {
  655.         /* PtToDotRect ( aPoint, theRect ); */
  656.         (*theRect).left = ( aPoint.h + 1 ) * 19 - 10;
  657.         (*theRect).top = ( aPoint.v + 1 ) * 19 - 10;
  658.         (*theRect).right = ( aPoint.h + 1 ) * 19;
  659.         (*theRect).bottom = ( aPoint.v + 1 ) * 19;
  660.         
  661.         DrawPicture ( picture, theRect );
  662.     }
  663.     
  664. }
  665.  
  666. /***************/
  667. /* PtToDotRect */
  668. /***************/
  669.  
  670. void    PtToDotRect ( Point aPoint, Rect *aRect )
  671. {
  672.     (*aRect).left = ( aPoint.h + 1 ) * 19 - 10;
  673.     (*aRect).top = ( aPoint.v + 1 ) * 19 - 10;
  674.     (*aRect).right = ( aPoint.h + 1 ) * 19;
  675.     (*aRect).bottom = ( aPoint.v + 1 ) * 19;
  676. }
  677.  
  678. /************/
  679. /* PtToRect */
  680. /************/
  681.  
  682. void    PtToRect ( Point aPoint, Rect *aRect )
  683. {
  684.     (*aRect).left = ( aPoint.h + 1 ) * 19 - 16;
  685.     (*aRect).top = ( aPoint.v + 1 ) * 19 - 16;
  686.     (*aRect).right = ( aPoint.h + 1 ) * 19 + 6;
  687.     (*aRect).bottom = ( aPoint.v + 1 ) * 19 + 6;
  688. }
  689.  
  690. /****************/
  691. /* PtToShipRect */
  692. /****************/
  693.  
  694. void    PtToShipRect ( Point aPoint, Rect *aRect, Boolean horiz, int min, int max )
  695. {
  696.     if ( horiz )
  697.     {
  698.         (*aRect).left = ( aPoint.h + 1 ) * 19 - 10 - ( kPixelSize * min );
  699.         (*aRect).top = ( aPoint.v + 1 ) * 19 - 10;
  700.         (*aRect).right = ( aPoint.h + 1 ) * 19 + ( kPixelSize * max );
  701.         (*aRect).bottom = ( aPoint.v + 1 ) * 19;
  702.     }
  703.     else
  704.     {
  705.         (*aRect).left = ( aPoint.h + 1 ) * 19 - 10;
  706.         (*aRect).top = ( aPoint.v + 1 ) * 19 - 10 - ( kPixelSize * min );
  707.         (*aRect).right = ( aPoint.h + 1 ) * 19;
  708.         (*aRect).bottom = ( aPoint.v + 1 ) * 19 + ( kPixelSize * max );
  709.     }
  710. }
  711.  
  712. /*****************/
  713. /* SetShipToGrid */
  714. /*****************/
  715. /* purpose: This function takes the current location of the ship upon a mouse down
  716. /*             and puts it into the grid.
  717. /* variables: The grid to set it to; the point of the current mouse location
  718. /*            after it has been translated to the grid coordinates; the vertical
  719. /*            or horizontal orientation of the ship; the minimum grid point that the
  720. /*            ship is at; the maximum grid point that the ship is at; the character
  721. /*            type of the ship.
  722.  */
  723.  
  724. void    SetShipToGrid ( Grid theGrid[][kGridSize], Point tempPoint, 
  725.                             Boolean horiz, int min, int max, int c )
  726. {
  727.     int i;
  728.     
  729.     if ( horiz )
  730.     {
  731.         if ( ( c == kCarrier ) || ( c == kBattleship ) ||
  732.                 ( c == kDestroyer ) || ( c == kCruiser ) )
  733.             theGrid[tempPoint.h - min][tempPoint.v].shipResID = 133;
  734.         else
  735.             theGrid[tempPoint.h - min][tempPoint.v].shipResID = 134;
  736.         
  737.         theGrid[tempPoint.h - min][tempPoint.v].shipType = c;
  738.         
  739.         for ( i = tempPoint.h - ( min - 1 ); i <= tempPoint.h + ( max - 1 ); i++ )
  740.         {
  741.             theGrid[i][tempPoint.v].shipResID = 135;
  742.             theGrid[i][tempPoint.v].shipType = c;
  743.         }
  744.         
  745.         if ( ( c == kSub ) || ( c == kCruiser ) || ( c == kDestroyer ) )
  746.             theGrid[tempPoint.h + max][tempPoint.v].shipResID = 136;
  747.         else
  748.             theGrid[tempPoint.h + max][tempPoint.v].shipResID = 137;
  749.  
  750.         theGrid[tempPoint.h + max][tempPoint.v].shipType = c;
  751.     }
  752.     else
  753.     {
  754.         if ( ( c == kCarrier ) || ( c == kBattleship ) ||
  755.                 ( c == kDestroyer ) || ( c == kCruiser ) )
  756.             theGrid[tempPoint.h][tempPoint.v - min].shipResID = 138;
  757.         else
  758.             theGrid[tempPoint.h][tempPoint.v - min].shipResID = 139;
  759.         
  760.         theGrid[tempPoint.h][tempPoint.v - min].shipType = c;
  761.         
  762.         for ( i = tempPoint.v - ( min - 1 ); i <= tempPoint.v + ( max - 1 ); i++ )
  763.         {
  764.             theGrid[tempPoint.h][i].shipResID = 140;
  765.             (theGrid[tempPoint.h][i].shipType) = c;
  766.         }
  767.         
  768.         if ( ( c == kSub ) || ( c == kCruiser ) || ( c == kDestroyer ) )
  769.             theGrid[tempPoint.h][tempPoint.v + max].shipResID = 141;
  770.         else
  771.             theGrid[tempPoint.h][tempPoint.v + max].shipResID = 142;
  772.         
  773.         (theGrid[tempPoint.h][tempPoint.v + max].shipType) = c;
  774.     }
  775. }
  776.  
  777. /************/
  778. /* DrawDots */
  779. /************/
  780.  
  781. void    DrawDots ( Grid theGrid[][kGridSize] )
  782. {
  783.     Rect        pictureRect;
  784.     WindowPtr    window;
  785.     PicHandle    hitDot, missDot, nullDot;
  786.     int            i, j, windowSize;
  787.     Boolean        isYou = FALSE;
  788.     
  789.     if ( theGrid == you )
  790.         isYou = TRUE;
  791.     
  792.     window = FrontWindow ();
  793.     windowSize = window->portRect.right - window->portRect.left;
  794.  
  795.     EraseRect ( &window->portRect );
  796.     
  797.     if ( useColor )
  798.     {
  799.         hitDot = GetPicture ( kHitDotID );
  800.         if ( hitDot == nil )
  801.         {
  802.             SysBeep ( 10 );
  803.             ExitToShell ();
  804.         }
  805.     }
  806.     else
  807.     {
  808.         hitDot = GetPicture ( kBWHitDotID );
  809.         if ( hitDot == nil )
  810.         {
  811.             SysBeep ( 10 );
  812.             ExitToShell ();
  813.         }
  814.     }
  815.  
  816.     missDot = GetPicture ( kMissDotID );
  817.     if ( missDot == nil )
  818.     {
  819.         SysBeep ( 10 );
  820.         ExitToShell ();
  821.     }
  822.  
  823.     nullDot = GetPicture ( kNullDotID );
  824.     if ( nullDot == nil )
  825.     {
  826.         SysBeep ( 10 );
  827.         ExitToShell ();
  828.     }
  829.     
  830.     i = 0;
  831.     for ( i; i <= 9; i++ )
  832.     {
  833.         j = 0;
  834.         for ( j; j <= 9; j++ )
  835.         {
  836.             pictureRect.left = ( i + 1 ) * 19 - 10;
  837.             pictureRect.top = ( j + 1 ) * 19 - 10;
  838.             pictureRect.right = ( i + 1 ) * 19;
  839.             pictureRect.bottom = ( j + 1 ) * 19;
  840.             
  841.             if ( isYou && ( theGrid[i][j].shipResID != 0 ) )
  842.                 DrawShipPart ( theGrid[i][j].shipResID, pictureRect );
  843.             else if ( ( ( enemyCount >= 17 ) || ( youCount >= 17 ) ) &&
  844.                             ( theGrid[i][j].shipResID != 0 ) )
  845.                 DrawShipPart ( theGrid[i][j].shipResID, pictureRect );
  846.             
  847.             if ( theGrid[i][j].hitOrMiss == noTry )
  848.                 DrawPicture ( nullDot, &pictureRect );
  849.             else if ( theGrid[i][j].hitOrMiss == miss )
  850.                 DrawPicture ( missDot, &pictureRect );
  851.             else
  852.                 DrawPicture ( hitDot, &pictureRect );
  853.         }
  854.     }
  855.     CheckIfSink ( kCarrier, kNoSound );
  856.     CheckIfSink ( kBattleship, kNoSound );
  857.     CheckIfSink ( kCruiser, kNoSound );
  858.     CheckIfSink ( kSub, kNoSound );
  859.     CheckIfSink ( kDestroyer, kNoSound );
  860. }
  861.  
  862. /****************/
  863. /* DrawShipPart */
  864. /****************/
  865.  
  866. void    DrawShipPart ( int resID, Rect pictureRect )
  867. {
  868.     PicHandle    picture;
  869.  
  870.     pictureRect.left -= 3;
  871.     pictureRect.top -= 3;
  872.     pictureRect.right += 3;
  873.     pictureRect.bottom += 3;
  874.             
  875.     picture = GetPicture ( resID );
  876.     if ( picture == nil )
  877.     {
  878.         SysBeep ( 10 );
  879.         ExitToShell ();
  880.     }
  881.  
  882.     DrawPicture ( picture, &pictureRect );
  883. }
  884.  
  885. /*****************/
  886. /* EraseShipPart */
  887. /*****************/
  888.  
  889. void    EraseShipPart ( Rect pictureRect )
  890. {
  891.     pictureRect.left -= 3;
  892.     pictureRect.top -= 3;
  893.     pictureRect.right += 3;
  894.     pictureRect.bottom += 3;
  895.             
  896.     EraseRect ( &pictureRect );
  897. }
  898.  
  899. /************/
  900. /* GridInit */
  901. /************/
  902.  
  903. void    GridInit ( Grid aGrid[][kGridSize] )
  904. {
  905.     int        i, j;
  906.     
  907.     for ( i = 0; i < kGridSize; i++ )
  908.     {
  909.         for ( j = 0; j < kGridSize; j++ )
  910.         {
  911.             aGrid[i][j].shipType = kNoShip;
  912.             aGrid[i][j].shipResID = 0;
  913.             aGrid[i][j].hitOrMiss = noTry;
  914.         }
  915.     }
  916. }
  917.  
  918. /*******************/
  919. /* PlaceEnemyShips */
  920. /*******************/
  921.  
  922. void    PlaceEnemyShips ( void )
  923. {
  924.     int        s;
  925.     
  926.     GetDateTime( &randSeed );
  927.     
  928.     GridInit ( enemy );
  929.  
  930.     PlaceAnEnemyShip ( kCarrierSize, kCarrierMin, kCarrierMax, kCarrier );
  931.     PlaceAnEnemyShip ( kBattleshipSize, kBattleshipMin, kBattleshipMax, kBattleship );
  932.     PlaceAnEnemyShip ( kCruiserSize, kCruiserMin, kCruiserMax, kCruiser );
  933.     PlaceAnEnemyShip ( kSubSize, kSubMin, kSubMax, kSub );
  934.     PlaceAnEnemyShip ( kDestroyerSize, kDestroyerMin, kDestroyerMax, kDestroyer );
  935. }
  936.  
  937. /********************/
  938. /* PlaceAnEnemyShip */
  939. /********************/
  940.  
  941. void    PlaceAnEnemyShip ( int shipSize, int min, int max, int c )
  942. {
  943.     Boolean                ItDoesntFit = TRUE, horiz;
  944.     int                 dir;
  945.     Point                aPoint;
  946.     
  947.     while ( ItDoesntFit )
  948.     {
  949.         aPoint.h = Randomize ();
  950.         aPoint.v = Randomize ();
  951.         
  952.         dir = Randomize ();
  953.         
  954.         if ( ( ( float ) dir / 2 ) == ( dir / 2 ) )       /* It's even so horizontal */
  955.         {
  956.             if ( ( aPoint.h <= 10 - shipSize ) && ( aPoint.h >= 0 ) && 
  957.                         ( FitsHoriz ( enemy, aPoint.h, aPoint.v, shipSize ) ) )
  958.             {
  959.                 horiz = TRUE;
  960.                 aPoint.h += min;
  961.                 SetShipToGrid ( enemy, aPoint, horiz, min, max, c );
  962.                 ItDoesntFit = FALSE;
  963.             }
  964.         }
  965.         else                                            /* It's odd so vertical */
  966.         {
  967.             if ( ( aPoint.v <= 10 - shipSize ) && ( aPoint.v >= 0 ) && 
  968.                         ( FitsVert ( enemy, aPoint.h, aPoint.v, shipSize ) ) )
  969.             {
  970.                 horiz = FALSE;
  971.                 aPoint.v += min;
  972.                 SetShipToGrid ( enemy, aPoint, horiz, min, max, c );
  973.                 ItDoesntFit = FALSE;
  974.             }
  975.         }
  976.     }
  977. }
  978.  
  979. /************/
  980. /* FitsVert */
  981. /************/
  982.  
  983. Boolean    FitsVert ( Grid theGrid[][kGridSize], int x, int y, int shipSize )
  984. {
  985.     Boolean fits = TRUE;
  986.     int        i;
  987.     
  988.     for ( i = y; i < y + shipSize; i++ )
  989.     {
  990.         if ( theGrid[x][i].shipResID != 0 )
  991.             fits = FALSE;
  992.     }
  993.     return ( fits );
  994. }
  995.  
  996. /*************/
  997. /* FitsHoriz */
  998. /*************/
  999.  
  1000. Boolean    FitsHoriz ( Grid theGrid[][kGridSize], int x, int y, int shipSize )
  1001. {
  1002.     Boolean fits = TRUE;
  1003.     int        i;
  1004.     
  1005.     for ( i = x; i < x + shipSize; i++ )
  1006.     {
  1007.         if ( theGrid[i][y].shipResID != 0 )
  1008.             fits = FALSE;
  1009.     }
  1010.     return ( fits );
  1011. }
  1012.  
  1013. /*************/
  1014. /* Randomize */
  1015. /*************/
  1016.  
  1017. int        Randomize ( void )
  1018. {
  1019.     long    randomNumber;
  1020.     
  1021.     randomNumber = Random ();
  1022.     
  1023.     if ( randomNumber < 0 )
  1024.         randomNumber *= -1;
  1025.     
  1026.     if ( randomNumber == 0 )
  1027.         return ( randomNumber );
  1028.     else
  1029.         return ( ( ( randomNumber * kRandomRange ) / kRandomUpperLimit ) );
  1030. }
  1031.  
  1032. /**************/
  1033. /* CheckPoint */
  1034. /**************/
  1035.  
  1036. void    CheckPoint ( Point mouseLocal )
  1037. {
  1038.     Rect        dotRect;
  1039.     Point        mouseCopy;
  1040.     Handle        mySndHandle;
  1041.     
  1042.     GlobalToLocal ( &mouseLocal );
  1043.     mouseCopy = mouseLocal;
  1044.     
  1045.     if ( mouseLocal.v == 200 )
  1046.         mouseLocal.v = 9;
  1047.     else
  1048.         mouseLocal.v /= kPixelSize;
  1049.     if ( mouseLocal.h == 200 )
  1050.         mouseLocal.h = 9;
  1051.     else
  1052.         mouseLocal.h /= kPixelSize;
  1053.     
  1054.     PtToDotRect ( mouseLocal, &dotRect );
  1055.             
  1056.     if ( ( PtInRect ( mouseCopy, &dotRect ) ) &&
  1057.                  ( enemy[mouseLocal.h][mouseLocal.v].hitOrMiss == noTry ) )
  1058.     {
  1059.         if ( gHasSound )
  1060.         {
  1061.             mySndHandle = GetResource ( 'snd ', kBombDropSnd );
  1062.             if ( mySndHandle != NULL )
  1063.                 SndPlay ( nil, mySndHandle, TRUE );
  1064.         }
  1065.         
  1066.         if ( enemy[mouseLocal.h][mouseLocal.v].shipResID == 0 )
  1067.         {
  1068.             enemy[mouseLocal.h][mouseLocal.v].hitOrMiss = miss;
  1069.             DrawOneDot ( kMissDotID, &dotRect );
  1070.         
  1071.             if ( gHasSound )
  1072.             {
  1073.                 mySndHandle = GetResource ( 'snd ', kSplashSnd );
  1074.                 if ( mySndHandle != NULL )
  1075.                     SndPlay ( nil, mySndHandle, TRUE );
  1076.             }
  1077.         }
  1078.         else
  1079.         {
  1080.             enemy[mouseLocal.h][mouseLocal.v].hitOrMiss = hit;
  1081.             (hitShips[(enemy[mouseLocal.h][mouseLocal.v].shipType)])++;
  1082.             DrawOneDot ( kHitDotID, &dotRect );
  1083.             CheckIfSink ( (enemy[mouseLocal.h][mouseLocal.v].shipType), kSound );
  1084.             
  1085.             if ( gHasSound )
  1086.             {
  1087.                 mySndHandle = GetResource ( 'snd ', kExplosionSnd );
  1088.                 if ( mySndHandle != NULL  )
  1089.                     SndPlay ( nil, mySndHandle, TRUE );
  1090.             }
  1091.             
  1092.             enemyCount++;
  1093.         }
  1094.         
  1095.         gYouHasGone = TRUE;
  1096.     }
  1097. }
  1098.  
  1099.  
  1100. /***************/
  1101. /* CheckIfSink */
  1102. /***************/
  1103.  
  1104. int        CheckIfSink ( int theShip, Boolean play )
  1105. {
  1106.     Boolean    drawParts = FALSE;
  1107.     int        i = 0;
  1108.     int        j = 0;
  1109.     Rect    theRect;
  1110.     Handle    mySndHandle;
  1111.     
  1112.     switch ( theShip )
  1113.     {
  1114.         case kCarrier:
  1115.             if ( hitShips[theShip] == kCarrierSize )
  1116.                 drawParts = TRUE;
  1117.             break;
  1118.         case kBattleship:
  1119.             if ( hitShips[theShip] == kBattleshipSize )
  1120.             {
  1121.                 drawParts = TRUE;
  1122.                 if ( gHasSound && play )
  1123.                 {
  1124.                     mySndHandle = GetResource ( 'snd ', kYouSankSnd );
  1125.                     if ( mySndHandle != NULL )
  1126.                         SndPlay ( nil, mySndHandle, TRUE );
  1127.                 }
  1128.             }
  1129.             break;
  1130.         case kCruiser:
  1131.             if ( hitShips[theShip] == kCruiserSize )
  1132.                 drawParts = TRUE;
  1133.             break;
  1134.         case kSub:
  1135.             if ( hitShips[theShip] == kSubSize )
  1136.                 drawParts = TRUE;
  1137.             break;
  1138.         case kDestroyer:
  1139.             if ( hitShips[theShip] == kDestroyerSize )
  1140.                 drawParts = TRUE;
  1141.             break;
  1142.     }
  1143.     if ( drawParts )
  1144.     {
  1145.         for ( i = 0; i < kGridSize; i++ )
  1146.         {
  1147.             for ( j = 0; j < kGridSize; j++ )
  1148.             {
  1149.                 if ( (enemy[i][j].shipType) == theShip )
  1150.                 {
  1151.                     theRect.left = ( i + 1 ) * 19 - 10;
  1152.                     theRect.top = ( j + 1 ) * 19 - 10;
  1153.                     theRect.right = ( i + 1 ) * 19;
  1154.                     theRect.bottom = ( j + 1 ) * 19;
  1155.                     
  1156.                     DrawShipPart ( enemy[i][j].shipResID,theRect );
  1157.                 }
  1158.             }
  1159.         }
  1160.     }
  1161. }
  1162.  
  1163.  
  1164. /**************/
  1165. /* DrawOneDot */
  1166. /**************/
  1167.  
  1168. void    DrawOneDot ( int dotID, Rect *dotRect )
  1169. {
  1170.     PicHandle    picture;
  1171.     
  1172.     picture = GetPicture ( dotID );
  1173.     if ( picture == nil )
  1174.     {
  1175.         SysBeep ( 10 );
  1176.         ExitToShell ();
  1177.     }
  1178.     DrawPicture ( picture, dotRect );
  1179. }
  1180.  
  1181. /************/
  1182. /* Inbounds */
  1183. /************/
  1184.  
  1185. Boolean    Inbounds ( Point *tempPoint, Boolean horiz, int min, int max )
  1186. {
  1187.     Boolean    vTest = TRUE;
  1188.     Boolean hTest = TRUE;
  1189.     
  1190.     if ( horiz )
  1191.     {
  1192.         if ( (*tempPoint).h < min )
  1193.         {
  1194.             (*tempPoint).h = min;
  1195.             hTest = FALSE;
  1196.         }
  1197.         if ( (*tempPoint).h > ( 9 - max ) )
  1198.         {
  1199.             (*tempPoint).h = ( 9 - max );
  1200.             hTest = FALSE;
  1201.         }
  1202.         if ( (*tempPoint).v < 0 )
  1203.         {
  1204.             (*tempPoint).v = 0;
  1205.             vTest = FALSE;
  1206.         }
  1207.         if ( (*tempPoint).v > 9 )
  1208.         {
  1209.             (*tempPoint).v = 9;
  1210.             vTest = FALSE;
  1211.         }
  1212.     }
  1213.     
  1214.     else
  1215.     {
  1216.         if ( (*tempPoint).v < min )
  1217.         {
  1218.             (*tempPoint).v = min;
  1219.             hTest = FALSE;
  1220.         }
  1221.         if ( (*tempPoint).v > ( 9 - max ) )
  1222.         {
  1223.             (*tempPoint).v = ( 9 - max );
  1224.             hTest = FALSE;
  1225.         }
  1226.         if ( (*tempPoint).h < 0 )
  1227.         {
  1228.             (*tempPoint).h = 0;
  1229.             vTest = FALSE;
  1230.         }
  1231.         if ( (*tempPoint).h > 9 )
  1232.         {
  1233.             (*tempPoint).h = 9;
  1234.             vTest = FALSE;
  1235.         }
  1236.     }
  1237.         
  1238.     if ( ( hTest == FALSE ) && ( vTest == FALSE ) )
  1239.         return ( FALSE );
  1240.     else
  1241.         return ( TRUE );
  1242. }
  1243.  
  1244. /*****************/
  1245. /* PickEnemyShot */
  1246. /*****************/
  1247.  
  1248. void    PickEnemyShot ( void )
  1249. {
  1250.     Rect                theRect;
  1251.     
  1252.     static cond            lastTry = miss;
  1253.     static Point        lastPoint =  {0,0}, firstHitPoint  = {0,0};
  1254.     static Boolean        keepTrying = FALSE, isHorizontal = FALSE, hitsYet = FALSE;
  1255.     static Direction    lastDir = right;
  1256.     static Point        thisPoint = {0,0};
  1257.     
  1258.     if ( !youCount )
  1259.     {
  1260.         lastTry = miss;
  1261.         keepTrying = FALSE;
  1262.         isHorizontal = FALSE;
  1263.         hitsYet = FALSE;
  1264.         lastDir = right;
  1265.     }
  1266.  
  1267.     if ( keepTrying == TRUE )
  1268.     {
  1269.         if ( ( lastDir == right ) && ( thisPoint.h < 9 ) )
  1270.         {
  1271.             thisPoint.h++;
  1272.             
  1273.             if ( you[thisPoint.h][thisPoint.v].hitOrMiss == noTry )
  1274.             {
  1275.                 lastTry = PlaceTheShot ( thisPoint );
  1276.                 
  1277.                 if ( lastTry == miss )
  1278.                 {
  1279.                     thisPoint = firstHitPoint;
  1280.                     lastDir = left;
  1281.                 }
  1282.                 
  1283.                 if ( lastTry ==  hit )
  1284.                 {
  1285.                     lastPoint = thisPoint;
  1286.                     hitsYet = TRUE;
  1287.                     isHorizontal = TRUE;
  1288.                 }
  1289.                 return;
  1290.             }
  1291.             else
  1292.             {
  1293.                 thisPoint = firstHitPoint;
  1294.                 lastDir = left;
  1295.             }
  1296.         }
  1297.         else if ( ( lastDir == right ) && ( ( isHorizontal ) || ( thisPoint.h == 9 ) ) )
  1298.         {
  1299.             thisPoint = firstHitPoint;
  1300.             lastDir = left;
  1301.         }
  1302.         
  1303.         if ( ( lastDir == left ) && ( thisPoint.h > 0 ) )
  1304.         {
  1305.             thisPoint.h--;
  1306.             
  1307.             if ( you[thisPoint.h][thisPoint.v].hitOrMiss == noTry )
  1308.             {
  1309.                 lastTry = PlaceTheShot ( thisPoint );
  1310.                 
  1311.                 switch ( lastTry )
  1312.                 {
  1313.                     case hit:
  1314.                         lastPoint = thisPoint;
  1315.                         isHorizontal = TRUE;
  1316.                         hitsYet = TRUE;
  1317.                         break;
  1318.  
  1319.                     case miss:
  1320.                         if ( hitsYet )
  1321.                         {
  1322.                             keepTrying = FALSE;
  1323.                             lastDir = right;
  1324.                             hitsYet = FALSE;
  1325.                         }
  1326.                         else
  1327.                         {
  1328.                             thisPoint = firstHitPoint;
  1329.                             lastDir = up;
  1330.                         }
  1331.                         break;
  1332.                 }
  1333.                     
  1334.                 return;
  1335.             }
  1336.             else
  1337.             {
  1338.                 if  ( hitsYet )
  1339.                 {
  1340.                     lastDir = right;
  1341.                     keepTrying = FALSE;
  1342.                     hitsYet = FALSE;
  1343.                 }
  1344.                 else
  1345.                 {
  1346.                     thisPoint = firstHitPoint;
  1347.                     lastDir = up;
  1348.                 }
  1349.             }
  1350.         }
  1351.         else if ( ( isHorizontal ) || ( lastDir == left ) )
  1352.         {
  1353.             if  ( hitsYet )
  1354.             {
  1355.                 lastDir = right;
  1356.                 keepTrying = FALSE;
  1357.                 hitsYet = FALSE;
  1358.             }
  1359.             else
  1360.             {
  1361.                 lastDir = up;
  1362.             }
  1363.         }
  1364.  
  1365.         if ( ( lastDir == up ) && ( thisPoint.v > 0 ) )
  1366.         {
  1367.             thisPoint.v--;
  1368.             
  1369.             if ( you[thisPoint.h][thisPoint.v].hitOrMiss == noTry )
  1370.             {
  1371.                 lastTry = PlaceTheShot ( thisPoint );
  1372.                 
  1373.                 if ( lastTry == miss )
  1374.                 {
  1375.                     thisPoint = firstHitPoint;
  1376.                     lastDir = down;
  1377.                 }
  1378.                 
  1379.                 if ( lastTry ==  hit )
  1380.                 {
  1381.                     lastPoint = thisPoint;
  1382.                     hitsYet = TRUE;
  1383.                 }
  1384.                 return;
  1385.             }
  1386.             else
  1387.             {
  1388.                 thisPoint = firstHitPoint;
  1389.                 lastDir = down;
  1390.             }
  1391.         }
  1392.         else if ( ( !isHorizontal ) && (lastDir == up ) )
  1393.         {
  1394.             lastDir = down;
  1395.             thisPoint = firstHitPoint;
  1396.         }
  1397.         
  1398.         if ( ( lastDir == down ) && ( thisPoint.v < 9 ) )
  1399.         {
  1400.             thisPoint.v++;
  1401.             
  1402.             if ( you[thisPoint.h][thisPoint.v].hitOrMiss == noTry )
  1403.             {
  1404.                 lastTry = PlaceTheShot ( thisPoint );
  1405.                 
  1406.                 if ( lastTry == miss )
  1407.                 {
  1408.                     if ( hitsYet )
  1409.                     {
  1410.                         keepTrying = FALSE;
  1411.                         lastDir = right;
  1412.                         hitsYet = FALSE;
  1413.                     }
  1414.                     else
  1415.                     {
  1416.                         lastPoint = thisPoint;
  1417.                         lastDir = up;
  1418.                     }
  1419.                 }
  1420.                 
  1421.                 if ( lastTry == hit )
  1422.                 {
  1423.                     hitsYet = TRUE;
  1424.                 }
  1425.                     
  1426.                 return;
  1427.             }
  1428.             else
  1429.             {
  1430.                 lastDir = right;
  1431.                 hitsYet = FALSE;
  1432.             }
  1433.         }
  1434.         else if ( !isHorizontal )
  1435.         {
  1436.             lastDir = right;
  1437.             hitsYet = FALSE;
  1438.             keepTrying  = FALSE;
  1439.         }
  1440.     }
  1441.  
  1442.     do
  1443.     {
  1444.         do
  1445.         {
  1446.             thisPoint.h = Randomize ();
  1447.         } while ( ( thisPoint.h < 0 ) || ( thisPoint.h > 9 ) );
  1448.         do
  1449.         {
  1450.             thisPoint.v = Randomize ();
  1451.         } while ( ( thisPoint.v < 0 ) || ( thisPoint.v > 9 ) );
  1452.     }  while ( IsBadRandom ( thisPoint, shotCount < kMinSpacedShots ) );
  1453.     
  1454.     lastTry = PlaceTheShot ( thisPoint );
  1455.     
  1456.     if ( lastTry == hit )
  1457.     {
  1458.         firstHitPoint = thisPoint;
  1459.         keepTrying = TRUE;
  1460.     }
  1461.     else
  1462.         keepTrying = FALSE;
  1463.     
  1464.     lastDir = right;
  1465.     lastPoint = thisPoint;
  1466.     isHorizontal = FALSE;
  1467.     
  1468.     return;
  1469. }
  1470.  
  1471. /***************/
  1472. /* IsBadRandom */
  1473. /***************/
  1474.  
  1475. Boolean    IsBadRandom ( Point thePoint, Boolean canCheck )
  1476. {
  1477.     Point    tempPoint = thePoint;
  1478.     
  1479.     if ( ( you[thePoint.h][thePoint.v].hitOrMiss == hit ) ||
  1480.                 ( you[thePoint.h][thePoint.v].hitOrMiss == miss ) )
  1481.         return ( TRUE );
  1482.     
  1483.     if ( canCheck ) /* After a certain number of tries which is #define, 
  1484.                         this will be false.  It prevents having random
  1485.                         guesses next to each other early in the game. */
  1486.     {
  1487.         if ( thePoint.h > 0 )
  1488.         {
  1489.             if ( ( you[thePoint.h - 1][thePoint.v].hitOrMiss == hit ) ||
  1490.                         ( you[thePoint.h - 1][thePoint.v].hitOrMiss == miss ) )
  1491.                 return ( TRUE );
  1492.         }
  1493.         if ( thePoint.h < 9 )
  1494.         {
  1495.             if ( ( you[thePoint.h + 1][thePoint.v].hitOrMiss == hit ) ||
  1496.                         ( you[thePoint.h + 1][thePoint.v].hitOrMiss == miss ) )
  1497.                 return ( TRUE );
  1498.         }
  1499.         if ( thePoint.v > 0 )
  1500.         {
  1501.             if ( ( you[thePoint.h][thePoint.v-1].hitOrMiss == hit ) ||
  1502.                         ( you[thePoint.h][thePoint.v-1].hitOrMiss == miss ) )
  1503.                 return ( TRUE );
  1504.         }
  1505.         if ( thePoint.v < 9 )
  1506.         {
  1507.             if ( ( you[thePoint.h][thePoint.v+1].hitOrMiss == hit ) ||
  1508.                         ( you[thePoint.h][thePoint.v+1].hitOrMiss == miss ) )
  1509.                 return ( TRUE );
  1510.         }
  1511.     }
  1512.     
  1513.     /* If the point is surrounded by white on all sides, why guess there? */
  1514.     if ( ( you[thePoint.h - 1][thePoint.v].hitOrMiss == miss ) && 
  1515.             ( you[thePoint.h + 1][thePoint.v].hitOrMiss == miss ) &&
  1516.             ( you[thePoint.h][thePoint.v - 1].hitOrMiss == miss ) &&
  1517.             ( you[thePoint.h][thePoint.v + 1].hitOrMiss == miss ) )
  1518.         return ( TRUE );
  1519.     
  1520.     return ( FALSE );
  1521. }
  1522.  
  1523. /****************/
  1524. /* PlaceTheShot */
  1525. /****************/
  1526.  
  1527. cond    PlaceTheShot ( Point thePoint )
  1528. {
  1529.     Rect  theRect;
  1530.     Handle        mySndHandle;
  1531.     
  1532.     SetPort ( youWindow );
  1533.     
  1534.     if ( gHasSound )
  1535.     {
  1536.         mySndHandle = GetResource ( 'snd ', kBombDropSnd );
  1537.         if ( mySndHandle != NULL )
  1538.             SndPlay ( nil, mySndHandle, TRUE );
  1539.     }
  1540.     
  1541.     if ( you[thePoint.h][thePoint.v].shipResID != 0 )
  1542.     {
  1543.         you[thePoint.h][thePoint.v].hitOrMiss = hit;
  1544.         
  1545.         if ( gHasSound )
  1546.         {
  1547.             mySndHandle = GetResource ( 'snd ', kExplosionSnd );
  1548.             if ( mySndHandle != NULL )
  1549.                 SndPlay ( nil, mySndHandle, TRUE );
  1550.         }
  1551.         
  1552.         youCount++;
  1553.     }
  1554.     else
  1555.     {
  1556.         you[thePoint.h][thePoint.v].hitOrMiss = miss;
  1557.         
  1558.         if ( gHasSound )
  1559.         {
  1560.             mySndHandle = GetResource ( 'snd ', kSplashSnd );
  1561.             if ( mySndHandle != NULL )
  1562.                 SndPlay ( nil, mySndHandle, TRUE );
  1563.         }
  1564.     }
  1565.     
  1566.     PtToDotRect ( thePoint, &theRect );
  1567.     DrawOneDot ( you[thePoint.h][thePoint.v].hitOrMiss, &theRect );
  1568.     
  1569.     shotCount++;
  1570.     
  1571.     return ( you[thePoint.h][thePoint.v].hitOrMiss );
  1572. }
  1573.  
  1574. /************/
  1575. /* IsColour */
  1576. /************/
  1577.  
  1578. Boolean    IsColour( void )
  1579. {
  1580.     SysEnvRec        mySE;
  1581.     
  1582.     /* Check to see if colour quickdraw is installed */
  1583.     SysEnvirons( 2, &mySE );
  1584.     return( mySE.hasColorQD );
  1585. }
  1586.  
  1587.  
  1588.