home *** CD-ROM | disk | FTP | other *** search
/ Game Fest 1993 / gamefest1993stgcomputerslimited1993.iso / soft / more8 / pro31 / baffled.cpp next >
C/C++ Source or Header  |  1992-11-03  |  30KB  |  1,121 lines

  1. // BAFFLED.CPP -- Written by Steve Brown on Oct 22, 1992
  2. //
  3. //        Locate mirrored baffles, hidden in a box, by moving and firing a
  4. //        laser into it.  Get points by guessing the correct location and
  5. //        angle of the baffles.  VGA graphics.
  6. //
  7.  
  8. #include <time.h>
  9. #include <ctype.h>
  10. #include <process.h>
  11. #include <graphics.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <conio.h>
  16. #include <alloc.h>
  17. #include <dos.h>
  18. #include "baffled.h"
  19.  
  20. void put_square(int sx, int sy, int clr);    // Put baffle selection box
  21. void put_gun(int pos, int stat);             // Put gun on screen
  22.  
  23.  
  24. FILE *in;           // High score file stream
  25. void far *gun[4];   // Different positions of gun
  26. char name[10];      // Name for high score
  27. int getcode(void);  // Get and return a scan code
  28. int nb = 0;         // Number of baffles
  29. int tg = 0;         // Total guesses
  30. int cg = 0;         // Correct guesses
  31. int st = 0;         // Shots taken
  32. int db[20][2];      // Discovered Baffles
  33. int score;          // Score
  34. int key_push;       // Key pressed
  35. int i, j;           // Loop variables
  36. int maxx, maxy;     // Max values for x and y
  37. int cp = 0;         // Current positon of gun
  38. int sx = 1, sy = 1; // Coordinates for baffle selection box
  39. int tx, ty;         // Temparary x,y variables
  40. int dir;            // Direction of gun
  41. int x, y;           // Coordinates for laser beam
  42.  
  43.  
  44. void main(void)
  45. {
  46.   void setup(void);           // Initialize graphics drivers
  47.   void hscore_screen(void);   // High score screen
  48.   void intro_screen(void);    // Intro screen
  49.   void new_game(void);        // Intialize variable for new game
  50.   void play_game(void);       // Play game
  51.  
  52.   setup();
  53.   intro_screen();
  54.   while (TRUE) {
  55.     hscore_screen();
  56.     play_game();
  57.     new_game();
  58.     }
  59. }
  60.  
  61.  
  62. // setup() ----------------------------------------------------------
  63. void setup(void)
  64. {
  65.   int gdriver = VGA, gmode = VGAMED, errorcode;     // Driver stuff
  66.   if (registerbgidriver(EGAVGA_driver) < 0)         // All drives have been
  67.     exit(1);                                        //   loaded into the
  68.   if (registerbgifont(triplex_font) < 0)            //   EXE file during
  69.     exit(1);                                        //   linking of program
  70.   if (registerbgifont(sansserif_font)  < 0)
  71.     exit(1);
  72.   if (registerbgifont(small_font)  < 0)
  73.     exit(1);
  74.  
  75.   initgraph(&gdriver, &gmode, "");
  76.   errorcode = graphresult();
  77.  
  78.   if (errorcode != grOk) {
  79.     printf("Graphics error: %s\n", grapherrormsg(errorcode));
  80.     printf("Press any key to halt:");
  81.     getch();
  82.     exit(1);
  83.     }
  84.   maxx = getmaxx();
  85.   maxy = getmaxy();
  86.  
  87. }
  88.  
  89. // help_screen() ----------------------------------------------------
  90. void help_screen(void)
  91. {
  92.   setcolor(3);
  93.   settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4);
  94.   outtextxy(260, 5, "Help!");
  95.  
  96.   settextstyle(SMALL_FONT, HORIZ_DIR, 6);
  97.   setcolor(9);
  98.   outtextxy(125, 60, "Shoot =");
  99.   setcolor(11);
  100.   outtextxy(125, 60, "        <Spacebar>");
  101.   setcolor(9);
  102.   outtextxy(125, 60 + 15, "Move gun =");
  103.   setcolor(11);
  104.   outtextxy(125, 60 + 15, "           Arrow Keys");
  105.   setcolor(9);
  106.   outtextxy(125, 60 + 30, "Move Baffle Selector =        +");
  107.   setcolor(11);
  108.   outtextxy(125, 60 + 30, "                       <Ctrl>   Arrow keys");
  109.   setcolor(9);
  110.   outtextxy(125, 60 + 45, "Place Baffle =  and  keys");
  111.   setcolor(11);
  112.   outtextxy(125, 60 + 45, "              /    \\");
  113.  
  114.   settextstyle(SMALL_FONT, HORIZ_DIR, 5);
  115.   setcolor(12);
  116.   outtextxy(20, 140, "Instructions:");
  117.   outtextxy(45, 155, "Use the arrow keys to move the laser cannon around the board. Press Spacebar");
  118.   outtextxy(45, 170, "to fire.  To make a guess about the location of a baffle, first use CTRL+Arrow");
  119.   outtextxy(45, 185, "keys to move the baffle placement box to where you think the baffle is located.");
  120.   outtextxy(45, 200, "Then press / or \\ depending on the angle you predict.  If a baffle exists in");
  121.   outtextxy(45, 215, "that location, and has the same angle, the baffle will be revealed.");
  122.  
  123.   setcolor(11);
  124.   outtextxy(20, 235, "Scoring:");
  125.   outtextxy(45, 250, "Scores are a factor of the number of shots you take, the number of guesses");
  126.   outtextxy(45, 265, "you make and the number of baffles chosen. The lower the score, the better.");
  127.  
  128.   setcolor(10);
  129.   outtextxy(20, 290, "Tips:");
  130.   outtextxy(45, 305, "- It is better to waste a shot verifying a baffle, then making a wrong guess.");
  131.   outtextxy(45, 320, "- Add more baffles, to increase your chance of getting a better score.");
  132. }
  133.  
  134.  
  135. // intro_screen() ---------------------------------------------------
  136. void intro_screen(void)
  137. {
  138.   settextstyle(TRIPLEX_FONT, HORIZ_DIR, 7);
  139.   outtextxy(210, -15, "Baffled!");
  140.   settextstyle(SMALL_FONT, HORIZ_DIR, 5);
  141.   setcolor(14);
  142.   outtextxy(20, 60,  "Object of game:");
  143.   outtextxy(45, 75,  "Use the laser cannon to find the location of double sided, mirrored baffles");
  144.   outtextxy(45, 90,  "Baffles will reflect the laser at a 90 degree angle.  These baffles are");
  145.   outtextxy(45, 105,  "located at random intersections on the playing board.  Use the exit location");
  146.   outtextxy(45, 120, "of the laser beam to determine baffle locations.");
  147.  
  148.   setcolor(12);
  149.   outtextxy(20, 140, "Instructions:");
  150.   outtextxy(45, 155, "Use the arrow keys to move the laser cannon around the board. Press Spacebar");
  151.   outtextxy(45, 170, "to fire.  To make a guess about the location of a baffle, first use CTRL+Arrow");
  152.   outtextxy(45, 185, "keys to move the baffle placement box to where you think the baffle is located.");
  153.   outtextxy(45, 200, "Then press / or \\ depending on the angle you predict.  If a baffle exists in");
  154.   outtextxy(45, 215, "that location, and has the same angle, the baffle will be revealed.");
  155.  
  156.   setcolor(11);
  157.   outtextxy(20, 235, "Scoring:");
  158.   outtextxy(45, 250, "Scores are a factor of the number of shots you take, the number of guesses");
  159.   outtextxy(45, 265, "you make and the number of baffles chosen. The lower the score, the better.");
  160.  
  161.   setcolor(10);
  162.   outtextxy(20, 290, "Tips:");
  163.   outtextxy(45, 305, "- It is better to waste a shot verifying a baffle, then making a wrong guess.");
  164.   outtextxy(45, 320, "- Add more baffles, to increase your chance of getting a better score.");
  165.   getch();
  166. }
  167.  
  168.  
  169. // hscore_screen() --------------------------------------------------
  170. void hscore_screen(void)
  171. {
  172.   void get_scores(void);  // Retrieve scores from "HIGHSCORE.DAT"
  173.   char temp[50], tmp[3];  // Temporary strings
  174.   int keypres;            // Key pressed
  175.   int baf_num;            // Num of baffles played
  176.   int dn = 0;             // Cursor postion
  177.   BOOL done = FALSE;      // Determine if done
  178.  
  179.   cleardevice();
  180.   setcolor(10);
  181.   settextstyle(TRIPLEX_FONT, HORIZ_DIR, 5);
  182.   outtextxy((maxx - textwidth("High Scores"))/2, -10, "High Scores");
  183.  
  184.   settextstyle(DEFAULT_FONT, HORIZ_DIR, 2);
  185.  
  186.   get_scores();
  187.   for (int i = 0; i < 10; i++) {
  188.     sprintf(temp, "%2d) %-10s %5s (%2s)", i + 1, hscore[i].name, hscore[i].score, hscore[i].baffle);
  189.     outtextxy((maxx - textwidth(temp))/2, 50 + (i * 20), temp);
  190.     }
  191.  
  192.   settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 2);
  193.   outtextxy(130, 280, "Enter # of baffles or press ESC to quit:");
  194.   i = 0;
  195.   for (i = 0; i < 50; i++)
  196.     temp[i] = '\0';
  197.  
  198.   while(!done) {             // Loop to get # of baffles
  199.     while (!kbhit()) {
  200.       i++;
  201.       if (i < 500) {
  202.         setfillstyle(SOLID_FILL, 3);
  203.         bar(530 + (dn * 10), 303, 540 + (dn * 10), 306);
  204.         }
  205.       else {
  206.         setfillstyle(SOLID_FILL, 0);
  207.         bar(530 + (dn * 10), 303, 540 + (dn * 10), 306);
  208.         }
  209.       if (i > 1000)
  210.         i = 0;
  211.       }
  212.  
  213.     setfillstyle(SOLID_FILL, 0);
  214.     bar(530 + (dn * 10), 303, 540 + (dn * 10), 306);
  215.     keypres = getcode();
  216.     if (isdigit(keypres)) {
  217.       if (dn < 2) {
  218.         temp[dn++] = keypres;
  219.         sprintf(tmp, "%c", keypres);
  220.         outtextxy(535 + ((dn - 1) * 15), 280, tmp);
  221.         }
  222.       else {
  223.         setcolor(11);          // Error routine
  224.         outtextxy(150, 300, "Error: Range is not between 1 and 20");
  225.         outtextxy(165, 320, "   - Press Enter to continue -");
  226.         setcolor(10);
  227.         while (getcode() != 13)
  228.           ;
  229.         setfillstyle(SOLID_FILL, 0);
  230.         bar(150, 305, 600, 400);
  231.         dn = 0;
  232.         temp[0] = '\0';
  233.         temp[1] = '\0';
  234.  
  235.         setfillstyle(SOLID_FILL, 0);
  236.         bar(530 + (dn * 15), 280, 545 + ((dn + 1) * 15), 400);
  237.       }
  238.     }
  239.     if (keypres == ESCKEY) {   // Exit routine
  240.        for (i = 0; i < 4; i++)
  241.          farfree(gun[i]);
  242.        closegraph();
  243.        exit(1);
  244.        }
  245.  
  246.     if (keypres == 8) {        // Backspace routine
  247.       if (dn - 1 >= 0) {
  248.         temp[--dn] = '\0';
  249.         setfillstyle(SOLID_FILL, 0);
  250.         bar(530 + (dn * 15), 280, 545 + ((dn+1) * 15), 400);
  251.         outtextxy(535 + ((dn - 1) * 15), 280, temp);
  252.         }
  253.       }
  254.  
  255.     if (keypres == 13) {       // Enter routine
  256.       baf_num = atoi(temp);
  257.       if (baf_num < 1 || baf_num > 20) {
  258.         setcolor(11);
  259.         outtextxy(150, 300, "Error: Range is not between 1 and 20");
  260.         outtextxy(165, 320, "   - Press Enter to continue -");
  261.         setcolor(10);
  262.         while (getcode() != 13)
  263.           ;
  264.         setfillstyle(SOLID_FILL, 0);
  265.         bar(150, 305, 600, 400);
  266.         dn = 0;
  267.         temp[0] = '\0';
  268.         temp[1] = '\0';
  269.         setfillstyle(SOLID_FILL, 0);
  270.         bar(530 + (dn * 15), 280, 545 + ((dn+1) * 15), 400);
  271.         }
  272.       else {
  273.         done = TRUE;
  274.         nb = baf_num;
  275.         }
  276.       }
  277.   }
  278. }
  279.  
  280. // get_scores() -----------------------------------------------------
  281. void get_scores(void)
  282. {
  283.   int get_value(char *);       // Get entry from file
  284.   int recno = 0;               // Current record number
  285.  
  286.   if ((in = fopen("HIGHSCOR.DAT", "r")) != NULL) {
  287.     while (get_value(hscore[recno].name) != EOF && recno < 10) {
  288.       if (get_value(hscore[recno].score) == EOF)
  289.         break;
  290.       if (get_value(hscore[recno].baffle) == EOF)
  291.         break;
  292.       recno++;
  293.       }
  294.     fclose(in);
  295.     }
  296. }
  297.  
  298.  
  299.  
  300. // get_value() ------------------------------------------------------
  301. int get_value(char *s)
  302. {
  303.   int ch;                      // Character
  304.  
  305.   while ((ch = getc(in)) != EOF && ch != '\n')
  306.     *s++ = ch;
  307.   *s = '\0';
  308.   return ch;
  309. }
  310.  
  311.  
  312. // play_game() ------------------------------------------------------
  313. void play_game(void)
  314. {
  315.   void setup_graph(void);      // Setup playing board
  316.   void put_instruc(void);      // Put instructions on screen
  317.   void put_info(BOOL);         // Put information on screen
  318.   void help_screen(void);      // Construct help screen
  319.   void move_gun(int cm);       // Move gun
  320.   void put_baffle(void);       // Put baffle if found
  321.   void correct_tone(void);     // Tone for correct guess
  322.   void wrong_tone(void);       // Tone for incorrect guess
  323.   void calc_score(void);       // Calculate score
  324.   void get_dir(int cp);        // Get direction of gun
  325.   void shoot_beam(void);       // Shoot beam
  326.   void get_result(void);       // Get result of shot
  327.  
  328.   BOOL exist;                  // True if baffle exists
  329.   BOOL done = FALSE;           // Flag for done
  330.   BOOL win = TRUE;             // Flag for win
  331.   int slot;                    // Slot to shoot down
  332.  
  333.   setup_graph();
  334.   put_instruc();
  335.  
  336.   while (!done) {
  337.     key_push = getcode();
  338.     put_info(TRUE);
  339.     switch (key_push) {
  340.       case LEFTKEY:           // Left arrow key pressed
  341.         if (cp >= 0 && cp < 10)
  342.           move_gun(-1);
  343.         if (cp >= 20 && cp < 30)
  344.           move_gun(1);
  345.         break;
  346.       case RIGHTKEY:          // Right arrow key pressed
  347.         if (cp >= 0 && cp < 10)
  348.           move_gun(1);
  349.         if (cp >= 20 && cp < 30)
  350.           move_gun(-1);
  351.     break;
  352.       case UPKEY:             // Up arrow key pressed
  353.         if (cp >= 10 && cp < 20)
  354.           move_gun(-1);
  355.         if (cp >= 30 && cp < 40)
  356.           move_gun(1);
  357.     break;
  358.       case DOWNKEY:           // Down arrow key pressed
  359.         if (cp >= 10 && cp < 20)
  360.           move_gun(1);
  361.         if (cp >= 30 && cp < 40)
  362.           move_gun(-1);
  363.     break;
  364.       case CTRL_R:            // Ctrl - Right arrow key pressed
  365.     put_square(sx, sy, 5);
  366.     sx++;
  367.     if (sx > 9)
  368.       sx = 9;
  369.     put_square(sx, sy, SCLR);
  370.     break;
  371.       case CTRL_L:            // Ctrl - Left arrow key pressed
  372.     put_square(sx, sy, 5);
  373.     sx--;
  374.     if (sx < 0)
  375.       sx = 0;
  376.     put_square(sx, sy, SCLR);
  377.     break;
  378.       case CTRL_U:            // Ctrl - Up arrow key pressed
  379.     put_square(sx, sy, 5);
  380.     sy--;
  381.     if (sy < 0)
  382.       sy = 0;
  383.     put_square(sx, sy, SCLR);
  384.     break;
  385.       case CTRL_D:            // Ctrl - Down arrow key pressed
  386.     put_square(sx, sy, 5);
  387.     sy++;
  388.     if (sy > 9)
  389.       sy = 9;
  390.     put_square(sx, sy, SCLR);
  391.     break;
  392.       case FORWARD:           // Forward slash pressed
  393.         exist = FALSE;
  394.     put_info(FALSE);
  395.         for (i = 0; i <= cg; i++) {
  396.           if (db[i][1] == sx && db[i][2] == sy)
  397.             exist = TRUE;
  398.           }
  399.  
  400.     if (IntSec[sx][sy].Angle == 1 && exist == FALSE) {
  401.       cg++;
  402.           db[cg][1] = sx;
  403.           db[cg][2] = sy;
  404.           put_baffle();
  405.           correct_tone();
  406.       }
  407.         else
  408.           wrong_tone();
  409.     tg++;
  410.     put_info(TRUE);
  411.         if (cg == nb)
  412.           done = TRUE;
  413.     break;
  414.       case BACK:              // Back slash pressed
  415.         exist = FALSE;
  416.     put_info(FALSE);
  417.         for (i = 0; i <= cg; i++) {
  418.           if (db[i][1] == sx && db[i][2] == sy)
  419.             exist = TRUE;
  420.           }
  421.  
  422.     if (IntSec[sx][sy].Angle == 0 && exist == FALSE) {
  423.       cg++;
  424.           db[cg][1] = sx;
  425.           db[cg][2] = sy;
  426.           put_baffle();
  427.           correct_tone();
  428.       }
  429.         else
  430.           wrong_tone();
  431.     tg++;
  432.     put_info(TRUE);
  433.         if (cg == nb)
  434.           done = TRUE;
  435.  
  436.     break;
  437.       case SHOT:              // Shoot key pressed
  438.         put_info(FALSE);
  439.         st++;
  440.         put_info(TRUE);
  441.     get_dir(cp);
  442.     shoot_beam();
  443.     get_result();
  444.     break;
  445.       case ESCKEY:            // Escape key pressed
  446.         win = FALSE;
  447.         done = TRUE;
  448.         break;
  449.       case 59:                // F1 pressed
  450.         setactivepage(1);
  451.         cleardevice();
  452.         help_screen();
  453.         setvisualpage(1);
  454.         setactivepage(0);
  455.         getch();
  456.         setvisualpage(0);
  457.         break;
  458.       }
  459.     }
  460.     if (win) {                // Game over!
  461.       setcolor(0);
  462.       settextstyle(3, HORIZ_DIR, 1);
  463.       outtextxy(5, 80, "Correct!");
  464.       setcolor(15);
  465.       outtextxy(5, 80, "You Win!");
  466.       settextstyle(SMALL_FONT, HORIZ_DIR, 4);
  467.       outtextxy(0, 110, "Press enter to continue");
  468.       getch();
  469.       calc_score();
  470.       }
  471. }
  472.  
  473.  
  474. // setup_graph() ----------------------------------------------------
  475. void setup_graph(void)
  476. {
  477.   void get_gun(void);          // Get image for gun
  478.   void calc_grid(void);        // Calculate points for grid
  479.   void draw_grid(void);        // Draw the grid
  480.  
  481.   int row, col;                // Baffle coordinates
  482.   int angle;                   // Angle of baffle
  483.  
  484.   randomize();
  485.  
  486.   for (i = 0; i < 10; i++) {   // Loop to initialize struct
  487.     for (j = 0; j < 10; j++) {
  488.       IntSec[i][j].Baffle = FALSE;
  489.       IntSec[i][j].Angle = -1;
  490.       }
  491.     }
  492.  
  493.   for (i = 1; i <= nb; i++) {  // Randomly generate baffles
  494.     row = random(10);
  495.     col = random(10);
  496.     angle = random(2);
  497.     if (IntSec[row][col].Baffle == TRUE)
  498.       i--;
  499.     else {
  500.       IntSec[row][col].Baffle = TRUE;
  501.       IntSec[row][col].Angle = angle;
  502.       }
  503.     }
  504.  
  505.   for (i = 0; i < nb; i++) {   // Intialize array of known baffles
  506.     db[i][1] = -1;
  507.     db[i][2] = -1;
  508.     }
  509.  
  510.   cleardevice();
  511.   get_gun();
  512.   calc_grid();
  513.   draw_grid();
  514.   put_gun(cp, COPY_PUT);
  515.   put_square(sx, sy, SCLR);
  516. }
  517.  
  518. // put_instruc() ----------------------------------------------------
  519. void put_instruc(void)
  520. {
  521.   setcolor(14);
  522.   settextstyle(3, HORIZ_DIR, 1);
  523.   outtextxy(563, 0, "Baffled!");
  524.   settextstyle(SMALL_FONT, HORIZ_DIR, 4);
  525.   outtextxy(545, 18, "By Stephen Brown");
  526.   outtextxy(545, 27, " Oct. 22, 1992");
  527. }
  528.  
  529. // move_gun() -------------------------------------------------------
  530. void move_gun(int cm)
  531. {
  532.    put_gun(cp, XOR_PUT);
  533.    cp += cm;
  534.    switch (cp) {
  535.      case 40:
  536.        cp = 0;
  537.        break;
  538.      case -1:
  539.        cp = 39;
  540.        break;
  541.      }
  542.  
  543.    put_gun(cp, COPY_PUT);
  544. }
  545.  
  546. // put_info() -------------------------------------------------------
  547. void put_info(BOOL clr)
  548. {
  549.   char temp[80];               // Temporary storage
  550.   setcolor(14);
  551.   settextstyle(SMALL_FONT, HORIZ_DIR, 5);
  552.   outtextxy(1, 1, "Num of Baffles:");
  553.   outtextxy(1, 12, "Total Guesses:");
  554.   outtextxy(1, 24, "Baffles Found:");
  555.   outtextxy(1, 36, "Shots Taken: ");
  556.   settextstyle(SMALL_FONT, HORIZ_DIR, 6);
  557.   outtextxy(525, 320, "Score:");
  558.  
  559.   if (clr)
  560.     setcolor(14);
  561.   else
  562.     setcolor(0);
  563.  
  564.   settextstyle(SMALL_FONT, HORIZ_DIR, 5);
  565.   sprintf(temp, "               %d", nb);
  566.   outtextxy(1, 1, temp);
  567.   sprintf(temp, "               %d", tg);
  568.   outtextxy(1, 12, temp);
  569.   sprintf(temp, "               %d", cg);
  570.   outtextxy(1, 24, temp);
  571.   sprintf(temp, "            %d", st);
  572.   outtextxy(1, 36, temp);
  573.  
  574.   settextstyle(SMALL_FONT, HORIZ_DIR, 6);
  575.   score = (100 * (20 - nb)) + st + ((tg - cg) * (30 - nb));
  576.   sprintf(temp, "       %d", score);
  577.   outtextxy(525, 320, temp);
  578.   setcolor(17);
  579.  
  580.   settextstyle(SMALL_FONT, HORIZ_DIR, 5);
  581.   setcolor(9);
  582.   outtextxy(10, 320, "Press      for help");
  583.   setcolor(11);
  584.   outtextxy(10, 320, "      <F1>");
  585. }
  586.  
  587. // put_baffle() -----------------------------------------------------
  588. void put_baffle(void)
  589. {
  590.   for(i = 0; i <= cg; i++) {
  591.     tx = 165 + ((db[i][1]) * 35);
  592.     ty = 60 + ((db[i][2]) * 25);
  593.     setcolor(SCLR);
  594.     if (IntSec[db[i][1]][db[i][2]].Angle == 0)
  595.       line(tx - 5, ty - 5, tx + 5, ty + 5);
  596.  
  597.     if (IntSec[db[i][1]][db[i][2]].Angle == 1)
  598.       line(tx - 5, ty + 5, tx + 5, ty - 5);
  599.     }
  600. }
  601.  
  602.  
  603. // correct_tone() ---------------------------------------------------
  604. void correct_tone(void)
  605. {
  606.   setcolor(0);
  607.   settextstyle(3, HORIZ_DIR, 1);
  608.   outtextxy(5, 80, "Wrong!");
  609.   setcolor(15);
  610.   outtextxy(5, 80, "Correct!");
  611.   sound(400);
  612.   delay(100);
  613.   nosound();
  614.   delay(100);
  615.   sound(400);
  616.   delay(80);
  617.   nosound();
  618.   delay(100);
  619.   sound(600);
  620.   delay(250);
  621.   nosound();
  622. }
  623.  
  624. // wrong_tone() -----------------------------------------------------
  625. void wrong_tone(void)
  626. {
  627.   setcolor(0);
  628.   settextstyle(3, HORIZ_DIR, 1);
  629.   outtextxy(5, 80, "Correct!");
  630.   setcolor(15);
  631.   outtextxy(5, 80, "Wrong!");
  632.   sound(300);
  633.   delay(200);
  634.   nosound();
  635.   delay(150);
  636.   sound(250);
  637.   delay(250);
  638.   nosound();
  639. }
  640.  
  641.  
  642. // get_dir() --------------------------------------------------------
  643. void get_dir(int cp)
  644. {
  645.   if (cp >= 0 && cp < 10) {    // Gun faces down
  646.       dir = DOWN;
  647.       x = cp;
  648.       y = -1;
  649.       }
  650.  
  651.   if (cp >= 10 && cp < 20) {   // Gun faces left
  652.       dir = LEFT;
  653.       x = 10;
  654.       y = cp - 10;
  655.       }
  656.  
  657.   if (cp >= 20 && cp < 30) {   // Gun faces up
  658.       dir = UP;
  659.       x = 29 - cp;
  660.       y = 10;
  661.       }
  662.  
  663.   if (cp >= 30 && cp < 40) {   // Gun faces right
  664.       dir = RIGHT;
  665.       x = -1;
  666.       y = 39 - cp;
  667.       }
  668. }
  669.  
  670. // shoot_beam() -----------------------------------------------------
  671. void shoot_beam(void)
  672. {
  673.   int done = FALSE;
  674.   while(done == FALSE) {
  675.     switch(dir) {
  676.       case DOWN:               // Beam shot down
  677.     while(++y < 10) {
  678.       if (IntSec[x][y].Baffle) {
  679.         if (IntSec[x][y].Angle == 0)
  680.           dir = RIGHT;
  681.         else
  682.           dir = LEFT;
  683.         break;
  684.         }
  685.       }
  686.     if (y == 10)
  687.       done = TRUE;
  688.     break;
  689.  
  690.       case UP:                 // Beam shot up
  691.     while(--y > -1) {
  692.       if (IntSec[x][y].Baffle) {
  693.         if (IntSec[x][y].Angle == 0)
  694.           dir = LEFT;
  695.         else
  696.           dir = RIGHT;
  697.         break;
  698.         }
  699.       }
  700.     if (y == -1)
  701.       done = TRUE;
  702.     break;
  703.  
  704.       case LEFT:               // Beam shot left
  705.     while(--x > -1) {
  706.       if (IntSec[x][y].Baffle) {
  707.         if (IntSec[x][y].Angle == 0)
  708.           dir = UP;
  709.         else
  710.           dir = DOWN;
  711.         break;
  712.         }
  713.       }
  714.     if (x == -1)
  715.       done = TRUE;
  716.     break;
  717.  
  718.       case RIGHT:              // Beam shot right
  719.     while(++x < 10) {
  720.       if (IntSec[x][y].Baffle) {
  721.         if (IntSec[x][y].Angle == 0)
  722.           dir = DOWN;
  723.         else
  724.           dir = UP;
  725.         break;
  726.         }
  727.       }
  728.     if (x == 10)
  729.       done = TRUE;
  730.     break;
  731.     }
  732.   }
  733. }
  734.  
  735.  
  736. // get_result() -----------------------------------------------------
  737. void get_result(void)
  738. {
  739.   void enter_beam(int cp);     // Show beam entering
  740.   void exit_beam(int dir);     // Show beam exiting
  741.  
  742.   switch(dir) {
  743.     case DOWN:
  744.       enter_beam(cp);
  745.       exit_beam(DOWN);
  746.       break;
  747.     case LEFT:
  748.       enter_beam(cp);
  749.       exit_beam(LEFT);
  750.       break;
  751.     case UP:
  752.       enter_beam(cp);
  753.       exit_beam(UP);
  754.       break;
  755.     case RIGHT:
  756.       enter_beam(cp);
  757.       exit_beam(RIGHT);
  758.       break;
  759.     }
  760. }
  761.  
  762. // calc_score() -----------------------------------------------------
  763. void calc_score(void)
  764. {
  765.   void put_scores();           // Put scores in "HIGHSCORE.DAT"
  766.   char temp[30];               // Temporary storage
  767.   char ch[2] = {'\0'};         // Temporary storage
  768.   BOOL hs = FALSE;             // High score flag
  769.   int cl = 0;                  // Current letter
  770.  
  771.   for(i = 0; i < 10; i++) {
  772.     if (atoi(hscore[i].score) > score || atoi(hscore[i].score) == 0)
  773.       hs = TRUE;
  774.     }
  775.   if (hs) {
  776.     cleardevice();
  777.     setcolor(14);
  778.     settextstyle(DEFAULT_FONT, HORIZ_DIR, 4);
  779.     outtextxy(70, 5, "New High Score!!");
  780.     settextstyle(DEFAULT_FONT, HORIZ_DIR, 2);
  781.     sprintf(temp, "Score: %d", score);
  782.     outtextxy(250, 50, temp);
  783.     outtextxy(120, 150, "Enter your name:");
  784.     while ((ch[0] = getch()) != 13 && cl < 10) {
  785.       if (isascii(ch[0]) && ch[0] != '\0' && ch[0] != 8 && cl < 10) {
  786.         ch[1] = '\0';
  787.         outtextxy(390 + (cl * 15), 150, ch);
  788.         name[cl++] = ch[0];
  789.         }
  790.       if (ch[0] == 8  && cl > -1) {
  791.         cl--;
  792.         setfillstyle(SOLID_FILL, 0);
  793.         bar(390 + (cl * 15), 150, 405 + (cl * 15), 170);
  794.         name[cl] = '\0';
  795.         }
  796.       }
  797.     name[9] = '\0';
  798.     put_scores();
  799.     }
  800. }
  801.  
  802.  
  803. // get_gun() --------------------------------------------------------
  804. void get_gun(void)
  805. {
  806.   unsigned size;               // Memory needed to store gun images
  807.   setfillstyle(SOLID_FILL, 2);
  808.   size = imagesize(0, 0, 30, 30);  /* get byte size of image */
  809.   for (i = 0; i < 4; i++) {
  810.     cleardevice();
  811.     if ((gun[i] = farmalloc(size)) == NULL) {  // Allocate memory for gun
  812.       closegraph();
  813.       printf("Error: not enough heap space to run mirror.\n");
  814.       exit(1);
  815.       }
  816.     switch (i) {               // Store gun facing up
  817.       case UP:
  818.     bar(5, 5, 15, 20);
  819.     bar(8, 0, 12, 10);
  820.     getimage(0, 0, 30, 30, gun[i]);
  821.     break;
  822.       case DOWN:               // Store gun facing down
  823.     bar(5, 5, 15, 20);
  824.     bar(8, 15, 12, 25);
  825.     getimage(0, 5, 30, 30, gun[i]);
  826.     break;
  827.       case LEFT:               // Store gun facing left
  828.     bar(5, 5, 25, 12);
  829.     bar(0, 7, 15, 10);
  830.     getimage(0, 0, 30, 30, gun[i]);
  831.     break;
  832.       case RIGHT:              // Store gun facing right
  833.     bar(5, 5, 25, 12);
  834.     bar(15, 7, 30, 10);
  835.     getimage(0, 0, 30, 30, gun[i]);
  836.     break;
  837.       }
  838.     }
  839.     cleardevice();
  840. }
  841.  
  842.  
  843. // calc_grid() ------------------------------------------------------
  844. void calc_grid(void)
  845. {
  846.    for (i = 0; i < 10; i++) {  // Calculate coordinates for grid
  847.      Points[i].y = 45;
  848.      Points[i].x = 165 + (i * 35);
  849.  
  850.      Points[i + 10].x = 500;
  851.      Points[i + 10].y = 60 + (i * 25);
  852.  
  853.      Points[i + 20].y = 300;
  854.      Points[i + 20].x = 165 + ((9 - i) * 35);
  855.  
  856.  
  857.      Points[i + 30].x = 145;
  858.      Points[i + 30].y = 60 + ((9 - i) * 25);
  859.      }
  860. }
  861.  
  862.  
  863.  
  864. // draw_grid() ------------------------------------------------------
  865. void draw_grid(void)
  866. {
  867.    rectangle(145, 45, 500, 300);
  868.    setcolor(5);
  869.    for (i = 0; i < 10; i++) {
  870.      for (j = 0; j <= 255; j++)
  871.        line(Points[i].x - 5, Points[i].y + j, Points[i].x + 5, Points[i].y + j);
  872.  
  873.      for (j = 355; j >= 0; j--)
  874.        line(Points[i + 30].x + j, Points[i + 30].y - 4, Points[i + 30].x + j, Points[i + 30].y + 3);
  875.      }
  876. }
  877.  
  878.  
  879. // enter_beam() -----------------------------------------------------
  880. void enter_beam(int cp)
  881. {
  882.   int mx, my, cx, cy;          // Coordinates for beam
  883.   int len;                     // Length of beam
  884.  
  885.   // x = 165 + (cp * 35)
  886.   // y = 60  + (cp * 25)
  887.  
  888.   if (cp >= 0 && cp < 10) {       // Direction of beam travel is DOWN
  889.       cx = 165 + (cp * 35);
  890.       cy = 58  + (-1.5 * 25);
  891.       mx = 0;
  892.       my = 1;
  893.       len = 24;
  894.       }
  895.  
  896.   if (cp >= 10 && cp < 20) {      // Direction of beam travel is  LEFT
  897.       cx = 173 + (10.5 * 35);
  898.       cy = 60  + ((9 - (19 - cp)) * 25);
  899.       mx = -1;
  900.       my = 0;
  901.       len = 39;
  902.       }
  903.  
  904.   if (cp >= 20 && cp < 30) {      //  Direction of beam travel is  UP
  905.       cx = 165 + ((29 - cp) * 35);
  906.       cy = 63  + (10.5 * 25);
  907.       mx = 0;
  908.       my = -1;
  909.       len = 24;
  910.       }
  911.  
  912.   if (cp >= 30 && cp < 40) {      //  Direction of beam travel is  RIGHT
  913.       cx = 158 + (-1.5 * 35);
  914.       cy = 59  + ((39 - cp) * 25);
  915.       mx = 1;
  916.       my = 0;
  917.       len = 39;
  918.       }
  919.  
  920.   for (i = 0; i < len; i++) {
  921.     delay(5);
  922.     putpixel(cx + mx * (i + 1), cy + my * (i + 1), 11);
  923.     }
  924.  
  925.   for (i = 0; i < len; i++) {
  926.     delay(5);
  927.     putpixel((cx += mx), (cy += my), 0);
  928.     }
  929. }
  930.  
  931.  
  932. // exit_beam() ------------------------------------------------------
  933. void exit_beam(int dr)
  934. {
  935. int bx, by, mx = 0, my = 0;    // Coordinates for beam
  936.  
  937. switch (dr) {
  938.   case UP:
  939.    bx = 165 + (x * 35);
  940.    by = 70 + (y * 25);
  941.    my = -1;
  942.   break;
  943.  
  944.   case DOWN:
  945.    bx = 165 + (x * 35);
  946.    by = 50 + (y * 25);
  947.    my = 1;
  948.   break;
  949.  
  950.   case LEFT:
  951.    bx = 180 + (x * 35);
  952.    by = 60 + (y * 25);
  953.    mx = -1;
  954.   break;
  955.  
  956.   case RIGHT:
  957.    bx = 150 + (x * 35);
  958.    by = 60 + (y * 25);
  959.    mx = 1;
  960.   break;
  961.   }
  962.  
  963.   for (i = 0; i < 30; i++) {    // Draw beam
  964.     delay(5);
  965.     putpixel((bx += mx), (by += my), 11);
  966.     }
  967.   for (i = 0; i < 10; i += 2) { // Draw explosion
  968.     putpixel(bx + i, by, 15);
  969.     putpixel(bx - i, by, 15);
  970.     putpixel(bx, by + i, 15);
  971.     putpixel(bx, by - i, 15);
  972.     putpixel(bx + i, by + i, 15);
  973.     putpixel(bx - i, by - i, 15);
  974.     putpixel(bx - i, by + i, 15);
  975.     putpixel(bx + i, by - i, 15);
  976.     }
  977.   setcolor(0);
  978.   bx -= (mx * 30);
  979.   by -= (my * 30);
  980.   for (i = 0; i < 30; i++) {    // Erase beam
  981.     delay(5);
  982.     putpixel((bx += mx), (by += my), 0);
  983.     }
  984.   for (i = 0; i < 10; i += 2) { // Erase explosion
  985.     putpixel(bx + i, by, 0);
  986.     putpixel(bx - i, by, 0);
  987.     putpixel(bx, by + i, 0);
  988.     putpixel(bx, by - i, 0);
  989.     putpixel(bx + i, by + i, 0);
  990.     putpixel(bx - i, by - i, 0);
  991.     putpixel(bx - i, by + i, 0);
  992.     putpixel(bx + i, by - i, 0);
  993.     delay(15);
  994.     }
  995.   delay(100);
  996.   for (i = 0; i < 10; i += 2) { // Draw explosion
  997.     putpixel(bx + i, by, 14);
  998.     putpixel(bx - i, by, 14);
  999.     putpixel(bx, by + i, 14);
  1000.     putpixel(bx, by - i, 14);
  1001.     putpixel(bx + i, by + i, 14);
  1002.     putpixel(bx - i, by - i, 14);
  1003.     putpixel(bx - i, by + i, 14);
  1004.     putpixel(bx + i, by - i, 14);
  1005.     }
  1006.   for (i = 0; i < 10; i += 2) { // Erase explosion
  1007.     putpixel(bx + i, by, 0);
  1008.     putpixel(bx - i, by, 0);
  1009.     putpixel(bx, by + i, 0);
  1010.     putpixel(bx, by - i, 0);
  1011.     putpixel(bx + i, by + i, 0);
  1012.     putpixel(bx - i, by - i, 0);
  1013.     putpixel(bx - i, by + i, 0);
  1014.     putpixel(bx + i, by - i, 0);
  1015.     delay(15);
  1016.     }
  1017. }
  1018.  
  1019.  
  1020.  
  1021. // put_scores() -----------------------------------------------------
  1022. void put_scores(void)
  1023. {
  1024.   FILE *out;                   // Stream to "HIGHSCORE.DAT"
  1025.   struct highscore temp;       // Struct of high score entries
  1026.   out = fopen("HIGHSCOR.DAT", "w");
  1027.  
  1028.   strcpy(hscore[9].name, name);
  1029.   sprintf(hscore[9].score, "%d", score);
  1030.   sprintf(hscore[9].baffle, "%d", nb);
  1031.  
  1032.   for (i = 0; i < 10; i++) {
  1033.     if (hscore[i].score[0] == '\0')
  1034.       strcpy(hscore[i].score, "32000");
  1035.     }
  1036.  
  1037.   for (i = 0; i < 9; i++) {
  1038.     for (j = i + 1; j < 10; j++) {
  1039.       if (hscore[i].score != 0 && hscore[j].score != 0) {
  1040.         if (atoi(hscore[i].score) > atoi(hscore[j].score)) {
  1041.           temp = hscore[i];
  1042.           hscore[i] = hscore[j];
  1043.           hscore[j] = temp;
  1044.           }
  1045.         }
  1046.       }
  1047.     }
  1048.  
  1049.  
  1050.   for (i = 0; i < 10; i++) {   // Send output to file
  1051.     if (strcmp(hscore[i].score, "32000") == 0)
  1052.       hscore[i].score[0] = '\0';
  1053.     fputs(hscore[i].name, out);
  1054.     fputc('\n', out);
  1055.     fputs(hscore[i].score, out);
  1056.     fputc('\n', out);
  1057.     fputs(hscore[i].baffle, out);
  1058.     fputc('\n', out);
  1059.     }
  1060.   fclose(out);
  1061. }
  1062.  
  1063.  
  1064. // new_game() ------------------------------------------------------
  1065. void new_game(void)
  1066. {
  1067.   nb = 0;
  1068.   tg = 0;
  1069.   cg = 0;
  1070.   st = 0;
  1071.   score = 0;
  1072.   cp = 0;
  1073.   sx = 1;
  1074.   sy = 1;
  1075.   for (i = 0; i < 20; i++) {
  1076.     db[i][1] = '\0';
  1077.     db[i][2] = '\0';
  1078.     }
  1079.   for (i = 1; i < 10; i++)
  1080.     name[i] = '\0';
  1081. }
  1082.  
  1083. // put_gun() --------------------------------------------------------
  1084. void put_gun(int pos, int stat)
  1085. {
  1086.   if (pos >= 0 && pos < 10)    // Put gun down
  1087.     putimage(Points[pos].x - 10, Points[pos].y - 45, gun[DOWN], stat);
  1088.  
  1089.   if (pos >= 10 && pos < 20)   // Put gun left
  1090.     putimage(Points[pos].x + 40, Points[pos].y - 9, gun[LEFT], stat);
  1091.  
  1092.   if (pos >= 20 && pos < 30)   // Put gun up
  1093.     putimage(Points[pos].x - 10, Points[pos].y + 25, gun[UP], stat);
  1094.  
  1095.   if (pos >= 30 && pos < 40)   // Put gun right
  1096.     putimage(Points[pos].x - 70, Points[pos].y - 9, gun[RIGHT], stat);
  1097.  
  1098. }
  1099.  
  1100.  
  1101. // put_square() -----------------------------------------------------
  1102. void put_square(int sx, int sy, int clr)
  1103. {
  1104. setcolor(clr);
  1105. tx = 165 + ((sx) * 35);
  1106. ty = 60 + ((sy) * 25);
  1107. rectangle(tx - 5, ty - 5, tx + 5, ty + 5);
  1108. }
  1109.  
  1110.  
  1111. // getcode() --------------------------------------------------------
  1112. int getcode()
  1113. {
  1114.   int ch = 0;                  // Input character
  1115.   if (kbhit()) {
  1116.     if ((ch = getch()) == 0)
  1117.       ch = getch();
  1118.     }
  1119.   return ch;
  1120. }
  1121.