home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / educaton / maze2a.arc / MAZE.C next >
Text File  |  1988-11-10  |  39KB  |  1,108 lines

  1. /*
  2.      This program builds a maze on your CRT.  After the maze is built,
  3. you may use the cursor keys to solve it.  Press "Q" to quit or press "S"
  4. to have the computer solve the maze.  If the computer solves the maze,
  5. you must press some key to exit.  A different random number seed will
  6. produce a different maze.  Each maze has exactly one solution that does
  7. not involve backtracking (passing through a doorway more than once).
  8.  
  9.      Written by James L. Dean.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <conio.h>
  15. #include <graphics.h>
  16. #include <dos.h>
  17. #include <stdlib.h>
  18. #include <alloc.h>
  19.  
  20. #define TRUE 1
  21. #define FALSE 0
  22.  
  23. typedef struct stack_1_rec
  24.                  {
  25.                    unsigned char      index_1;
  26.                    struct stack_1_rec *next_ptr;
  27.                  } *stack_1_rec_ptr;
  28.  
  29. typedef struct stack_2_rec
  30.                  {
  31.                    unsigned char      index_1;
  32.                    unsigned char      index_2;
  33.                    struct stack_2_rec *next_ptr;
  34.                  } *stack_2_rec_ptr;
  35.  
  36. static void generate_maze(int *,int *,int *,int *,int *,int *,int *,
  37.              int *,int *,int *,int *,int *,int *,int *,int *);
  38. static void initialize(int *,int *,int *,int *,int *,int *,int *,int *,
  39.              int *,int *,int *,int *,int *,int *,int *,int *);
  40. static void let_user_try_to_solve(int *,int *,int *,int *,int *,int *,
  41.              int *,int *,int *,int *,int *);
  42.        void main(void);
  43. static void optionally_have_computer_solve(int *,int *,int *,int *,
  44.              int *,int *,int *,int *,int *);
  45. static void remove_rejected_attempts(int *,int *,int *,int *,
  46.              stack_1_rec_ptr *,stack_1_rec_ptr *,int *,int *,int *,
  47.              int *,int *);
  48.  
  49. void main()
  50.   {
  51.     int delta_x [4] [24];
  52.     int delta_y [4] [24];
  53.     int erase;
  54.     int fatal_error;
  55.     int key_pressed;
  56.     int magnitude_delta_x;
  57.     int magnitude_delta_y;
  58.     int num_columns;
  59.     int num_rows;
  60.     int passage;
  61.     int path;
  62.     int r_n [8];
  63.     int twice_magnitude_delta_x;
  64.     int twice_magnitude_delta_y;
  65.     int wall;
  66.     int x_max;
  67.     int y_max;
  68.  
  69.     fatal_error=FALSE;
  70.  /*    See BGIOBJ in the Turbo C 2.0 User Guide for instructions
  71.     on modifying GRAPHICS.LIB to include Turbo BGI files */
  72.     registerfarbgidriver(CGA_driver_far);
  73.     registerfarbgidriver(EGAVGA_driver_far);
  74.     registerfarbgidriver(Herc_driver_far);
  75.     registerfarbgidriver(ATT_driver_far);
  76.     registerfarbgidriver(PC3270_driver_far);
  77.     registerfarbgidriver(IBM8514_driver_far);
  78.     initialize(&delta_x[0][0],&delta_y[0][0],&erase,&fatal_error,
  79.      &magnitude_delta_x,&magnitude_delta_y,&num_columns,&num_rows,
  80.      &passage,&path,&r_n[0],&twice_magnitude_delta_x,
  81.      &twice_magnitude_delta_y,&wall,&x_max,&y_max);
  82.     if (! fatal_error)
  83.       generate_maze(&delta_x[0][0],&delta_y[0][0],&magnitude_delta_x,
  84.        &magnitude_delta_y,&num_columns,&num_rows,&passage,&path,
  85.        &r_n[0],&twice_magnitude_delta_x,&twice_magnitude_delta_y,
  86.        &wall,&x_max,&y_max,&fatal_error);
  87.     if (! fatal_error)
  88.       let_user_try_to_solve(&delta_x[0][0],&delta_y[0][0],&erase,
  89.        &key_pressed,&magnitude_delta_x,&magnitude_delta_y,&passage,
  90.        &path,&wall,&y_max,&fatal_error);
  91.     if (! fatal_error)
  92.       optionally_have_computer_solve(&delta_x[0][0],&delta_y[0][0],
  93.        &key_pressed,&magnitude_delta_x,&magnitude_delta_y,&passage,
  94.        &path,&y_max,&fatal_error);
  95.     if (! fatal_error)
  96.       closegraph();
  97.     return;
  98.   }
  99.  
  100. static void initialize(delta_x,delta_y,erase,fatal_error,
  101.  magnitude_delta_x,magnitude_delta_y,num_columns,num_rows,passage,path,
  102.  r_n,twice_magnitude_delta_x,twice_magnitude_delta_y,wall,x_max,y_max)
  103.   int *delta_x;
  104.   int *delta_y;
  105.   int *erase;
  106.   int *fatal_error;
  107.   int *magnitude_delta_x;
  108.   int *magnitude_delta_y;
  109.   int *num_columns;
  110.   int *num_rows;
  111.   int *passage;
  112.   int *path;
  113.   int *r_n;
  114.   int *twice_magnitude_delta_x;
  115.   int *twice_magnitude_delta_y;
  116.   int *wall;
  117.   int *x_max;
  118.   int *y_max;
  119.     {
  120.       int  delta_index_1a;
  121.       int  delta_index_1b;
  122.       int  delta_index_1c;
  123.       int  delta_index_1d;
  124.       int  delta_index_2;
  125.       int  ErrorCode;
  126.       int  GraphDriver;
  127.       int  GraphMode;
  128.       int  max_num_columns;
  129.       int  max_num_rows;
  130.       int  max_x;
  131.       int  max_y;
  132.       int  r_n_index_1;
  133.       int  r_n_index_2;
  134.       char seed [256];
  135.       int  tem_int;
  136.  
  137.       detectgraph(&GraphDriver,&GraphMode);
  138.       ErrorCode=graphresult();
  139.       if (ErrorCode != 0)
  140.         {
  141.           *fatal_error=TRUE;
  142.           printf("Fatal error:  %s\n",grapherrormsg(ErrorCode));
  143.         }
  144.       if (! *fatal_error)
  145.         {
  146.           switch (GraphDriver)
  147.             {
  148.               case CGA:
  149.               case MCGA:
  150.               case ATT400:
  151.                 {
  152.                   GraphMode=0;
  153.                   *erase=2;
  154.                   *wall=1;
  155.                   *passage=0;
  156.                   *path=3;
  157.                   break;
  158.                 }
  159.               case EGA:
  160.                 {
  161.                   GraphMode=EGAHI;
  162.                   *erase=4;
  163.                   *wall=9;
  164.                   *passage=0;
  165.                   *path=2;
  166.                   break;
  167.                 }
  168.               case EGA64:
  169.                 {
  170.                   GraphMode=EGA64HI;
  171.                   *erase=2;
  172.                   *wall=1;
  173.                   *passage=0;
  174.                   *path=3;
  175.                   break;
  176.                 }
  177.               case VGA:
  178.                 {
  179.                   GraphMode=VGAHI;
  180.                   *erase=4;
  181.                   *wall=9;
  182.                   *passage=0;
  183.                   *path=2;
  184.                   break;
  185.                 }
  186.               case IBM8514:
  187.                 {
  188.                   GraphMode=IBM8514HI;
  189.                   *erase=4;
  190.                   *wall=9;
  191.                   *passage=0;
  192.                   *path=2;
  193.                   break;
  194.                 }
  195.               default:
  196.                 {
  197.                   GraphMode=0;
  198.                   *erase=0;
  199.                   *wall=1;
  200.                   *passage=0;
  201.                   *path=1;
  202.                   break;
  203.                 }
  204.             }
  205.           initgraph(&GraphDriver,&GraphMode,"");
  206.           ErrorCode=graphresult();
  207.           if (ErrorCode == 0)
  208.             {
  209.               max_x=getmaxx();
  210.               max_y=getmaxy();
  211.               max_num_columns=max_x/2;
  212.               max_num_rows=max_y/2;
  213.               closegraph();
  214.             }
  215.           else
  216.             {
  217.               GraphDriver=DETECT;
  218.               initgraph(&GraphDriver,&GraphMode,"");
  219.               ErrorCode=graphresult();
  220.               if (ErrorCode == 0)
  221.                 {
  222.                   max_x=getmaxx();
  223.                   max_y=getmaxy();
  224.                   max_num_columns=max_x/2;
  225.                   max_num_rows=max_y/2;
  226.                   *erase=0;
  227.                   *wall=1;
  228.                   *passage=0;
  229.                   *path=1;
  230.                   closegraph();
  231.                 }
  232.               else
  233.                 {
  234.                   *fatal_error=TRUE;
  235.                   printf("Fatal error:  %s\n",grapherrormsg(ErrorCode));
  236.                 }
  237.             }
  238.         }
  239.       if (! *fatal_error)
  240.         {
  241.           printf("                                 Maze Generator\n");
  242.           printf("\n");
  243.           printf("\n");
  244.           printf("\n");
  245.           printf(
  246. "     This program will generate a maze.  After the maze is generated, you");
  247.           printf("\n");
  248.           printf(
  249. "may use the cursor keys to solve it.  Press Q to quit or S to have the");
  250.           printf("\n");
  251.           printf(
  252. "computer solve the maze.  If the computer solves the maze, you must press");
  253.           printf("\n");
  254.           printf(
  255. "some key to exit.\n");
  256.           printf("\n");
  257.           do
  258.             {
  259.               printf("     Number of columns (2 to ");
  260.               printf("%d",max_num_columns);
  261.               printf(")? ");
  262.               fflush(stdin);
  263.               scanf("%d",num_columns);
  264.               if ((*num_columns < 2)
  265.               ||  (*num_columns > max_num_columns))
  266.                 {
  267.                   printf(
  268.                    "? The number of columns must be between 2 and ");
  269.                   printf("%d",max_num_columns);
  270.                   printf(", inclusively\n");
  271.                 }
  272.             }
  273.           while ((*num_columns < 2)
  274.           ||     (*num_columns > max_num_columns));
  275.           printf("\n");
  276.           do
  277.             {
  278.               printf("     Number of rows (2 to ");
  279.               printf("%d",max_num_rows);
  280.               printf(")? ");
  281.               fflush(stdin);
  282.               scanf("%d",num_rows);
  283.               if ((*num_rows < 2) || (*num_rows > max_num_rows))
  284.                 {
  285.                   printf(
  286.                    "? The number of rows must be between 2 and ");
  287.                   printf("%d",max_num_rows);
  288.                   printf(", inclusively\n");
  289.                 }
  290.             }
  291.           while ((*num_rows < 2) || (*num_rows > max_num_rows));
  292.           printf("\n");
  293.           printf("     Random number seed? ");
  294.           fflush(stdin);
  295.           gets(&seed[0]);
  296.           for (r_n_index_1=0;
  297.            ((r_n_index_1 < 8) && (seed[r_n_index_1] != (char) 0));
  298.            r_n_index_1++)
  299.             {
  300.               tem_int=(int) seed[r_n_index_1];
  301.               while (tem_int >= 29) tem_int-=29;
  302.               *(r_n+r_n_index_1)=tem_int;
  303.             }
  304.           r_n_index_2=7;
  305.           while (r_n_index_1 > 0)
  306.             {
  307.               r_n_index_1--;
  308.               *(r_n+r_n_index_2)=*(r_n+r_n_index_1);
  309.               r_n_index_2--;
  310.             }
  311.           while (r_n_index_2 >= 0)
  312.             {
  313.               *(r_n+r_n_index_2)=19;
  314.               r_n_index_2--;
  315.             }
  316.           initgraph(&GraphDriver,&GraphMode,"");
  317.           *magnitude_delta_x=max_x/(*num_columns)/2;
  318.           *twice_magnitude_delta_x
  319.            =(*magnitude_delta_x)+(*magnitude_delta_x);
  320.           *magnitude_delta_y=max_y/(*num_rows)/2;
  321.           *twice_magnitude_delta_y
  322.            =(*magnitude_delta_y)+(*magnitude_delta_y);
  323.           *x_max=*twice_magnitude_delta_x*(*num_columns);
  324.           *y_max=*twice_magnitude_delta_y*(*num_rows);
  325.           *delta_x=(*magnitude_delta_x);
  326.           *(delta_y+24)=(*magnitude_delta_y);
  327.           *(delta_x+48)=-(*magnitude_delta_x);
  328.           *(delta_y+72)=-(*magnitude_delta_y);
  329.           *delta_y=0;
  330.           *(delta_x+24)=0;
  331.           *(delta_y+48)=0;
  332.           *(delta_x+72)=0;
  333.           delta_index_2=-1;
  334.           for (delta_index_1a=0; delta_index_1a < 4; delta_index_1a++)
  335.             for (delta_index_1b=0; delta_index_1b < 4; delta_index_1b++)
  336.               if (delta_index_1a != delta_index_1b)
  337.                 for (delta_index_1c=0; delta_index_1c < 4;
  338.                  delta_index_1c++)
  339.                   if ((delta_index_1a != delta_index_1c)
  340.                   &&  (delta_index_1b != delta_index_1c))
  341.                     for (delta_index_1d=0; delta_index_1d < 4;
  342.                      delta_index_1d++)
  343.                       if ((delta_index_1a != delta_index_1d)
  344.                       &&  (delta_index_1b != delta_index_1d)
  345.                       &&  (delta_index_1c != delta_index_1d))
  346.                         {
  347.                           delta_index_2=delta_index_2+1;
  348.                           *(delta_x+(24*delta_index_1a+delta_index_2))
  349.                            =*delta_x;
  350.                           *(delta_y+(24*delta_index_1a+delta_index_2))
  351.                            =*delta_y;
  352.                           *(delta_x+(24*delta_index_1b+delta_index_2))
  353.                            =*(delta_x+24);
  354.                           *(delta_y+(24*delta_index_1b+delta_index_2))
  355.                            =*(delta_y+24);
  356.                           *(delta_x+(24*delta_index_1c+delta_index_2))
  357.                            =*(delta_x+48);
  358.                           *(delta_y+(24*delta_index_1c+delta_index_2))
  359.                            =*(delta_y+48);
  360.                           *(delta_x+(24*delta_index_1d+delta_index_2))
  361.                            =*(delta_x+72);
  362.                           *(delta_y+(24*delta_index_1d+delta_index_2))
  363.                            =*(delta_y+72);
  364.                         }
  365.         }
  366.       return;
  367.     }
  368.  
  369. static void generate_maze(delta_x,delta_y,magnitude_delta_x,
  370.  magnitude_delta_y,num_columns,num_rows,passage,path,r_n,
  371.  twice_magnitude_delta_x,twice_magnitude_delta_y,wall,x_max,y_max,
  372.  fatal_error)
  373.   int *delta_x;
  374.   int *delta_y;
  375.   int *magnitude_delta_x;
  376.   int *magnitude_delta_y;
  377.   int *num_columns;
  378.   int *num_rows;
  379.   int *passage;
  380.   int *path;
  381.   int *r_n;
  382.   int *twice_magnitude_delta_x;
  383.   int *twice_magnitude_delta_y;
  384.   int *wall;
  385.   int *x_max;
  386.   int *y_max;
  387.   int *fatal_error;
  388.     {
  389.       int             finished;
  390.       int             delta_index_1;
  391.       int             delta_index_2;
  392.       int             digit;
  393.       int             digit_num;
  394.       int             recurse;
  395.       int             r_n_index_1;
  396.       int             r_n_index_2;
  397.       stack_2_rec_ptr stack_head;
  398.       stack_2_rec_ptr stack_ptr;
  399.       int             sum;
  400.       int             tem_int;
  401.       int             x;
  402.       int             x_next;
  403.       int             x_out;
  404.       int             y;
  405.       int             y_next;
  406.       int             y_out;
  407.  
  408.       setcolor(*path);
  409.       setfillstyle((unsigned int) SOLID_FILL,(unsigned int) *path);
  410.       bar(0,0,*x_max,*y_max);
  411.       if (*path != *wall)
  412.         {
  413.           setcolor((unsigned int) *wall);
  414.           x_out=0;
  415.           while (x_out <= *x_max)
  416.             {
  417.               line(x_out,0,x_out,*y_max);
  418.               x_out+=(*twice_magnitude_delta_x);
  419.             }
  420.           y_out=0;
  421.           while (y_out <= *y_max)
  422.             {
  423.               line(0,y_out,*x_max,y_out);
  424.               y_out+=(*twice_magnitude_delta_y);
  425.             }
  426.         }
  427.       sum=0;
  428.       for (digit_num=1; digit_num <= 3; digit_num++)
  429.         {
  430.           digit=*r_n;
  431.           r_n_index_1=0;
  432.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  433.             {
  434.               tem_int=*(r_n+r_n_index_2);
  435.               *(r_n+r_n_index_1)=tem_int;
  436.               r_n_index_1++;
  437.               digit+=tem_int;
  438.               if (digit >= 29)
  439.                 digit-=29;
  440.             }
  441.           *(r_n+7)=digit;
  442.           sum=29*sum+digit;
  443.         }
  444.       x=(2*(sum%(*num_columns))+1)*(*magnitude_delta_x);
  445.       sum=0;
  446.       for (digit_num=1; digit_num <= 3; digit_num++)
  447.         {
  448.           digit=*r_n;
  449.           r_n_index_1=0;
  450.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  451.             {
  452.               tem_int=*(r_n+r_n_index_2);
  453.               *(r_n+r_n_index_1)=tem_int;
  454.               r_n_index_1++;
  455.               digit+=tem_int;
  456.               if (digit >= 29)
  457.                 digit-=29;
  458.             }
  459.           *(r_n+7)=digit;
  460.           sum=29*sum+digit;
  461.         }
  462.       y=(2*(sum%(*num_rows))+1)*(*magnitude_delta_y);
  463.       setcolor((unsigned int) *passage);
  464.       setfillstyle((unsigned int) SOLID_FILL,(unsigned int) *passage);
  465.       finished=FALSE;
  466.       recurse=TRUE;
  467.       stack_head=NULL;
  468.       while ((! finished) && (! *fatal_error))
  469.         {
  470.           if (recurse)
  471.             {
  472.               bar(x-(*magnitude_delta_x)+1,y-(*magnitude_delta_y)+1,
  473.                x+(*magnitude_delta_x)-1,y+(*magnitude_delta_y)-1);
  474.               delta_index_1=0;
  475.               do
  476.                 {
  477.                   delta_index_2=*r_n;
  478.                   r_n_index_1=0;
  479.                   for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  480.                     {
  481.                       tem_int=*(r_n+r_n_index_2);
  482.                       *(r_n+r_n_index_1)=tem_int;
  483.                       r_n_index_1++;
  484.                       delta_index_2+=tem_int;
  485.                       if (delta_index_2 >= 29)
  486.                         delta_index_2-=29;
  487.                     }
  488.                   *(r_n+7)=delta_index_2;
  489.                 }
  490.               while (delta_index_2 >= 24);
  491.               recurse=FALSE;
  492.             }
  493.             while ((delta_index_1 < 4)
  494.             &&     (! recurse)
  495.             &&     (! *fatal_error))
  496.               {
  497.                 x_next=x+2*(*(delta_x+(24*delta_index_1+delta_index_2)));
  498.                 if ((x_next <= 0) || (x_next >= *x_max))
  499.                   delta_index_1++;
  500.                 else
  501.                   {
  502.                     y_next
  503.                      =y+2*(*(delta_y+(24*delta_index_1+delta_index_2)));
  504.                     if ((y_next <= 0) || (y_next >= *y_max))
  505.                       delta_index_1++;
  506.                     else
  507.                       if (getpixel(x_next,y_next)
  508.                        == (unsigned int)*path)
  509.                         {
  510.                           if (x == x_next)
  511.                             {
  512.                               y_out=(y+y_next)/2;
  513.                               line(x-(*magnitude_delta_x)+1,y_out,
  514.                                x+(*magnitude_delta_x)-1,y_out);
  515.                             }
  516.                           else
  517.                             {
  518.                               x_out=(x+x_next)/2;
  519.                               line(x_out,y-(*magnitude_delta_y)+1,
  520.                                x_out,y+(*magnitude_delta_y)-1);
  521.                             }
  522.                           x=x_next;
  523.                           y=y_next;
  524.                           if ((stack_ptr=(struct stack_2_rec *) malloc(
  525.                            (unsigned) sizeof(struct stack_2_rec)))
  526.                            == NULL)
  527.                             {
  528.                               *fatal_error=TRUE;
  529.                               closegraph();
  530.                               printf("? out of memory\n");
  531.                             }
  532.                           else
  533.                             {
  534.                               stack_ptr->next_ptr=stack_head;
  535.                               stack_head=stack_ptr;
  536.                               stack_head->index_1
  537.                                =(unsigned char) delta_index_1;
  538.                               stack_head->index_2
  539.                                =(unsigned char) delta_index_2;
  540.                               recurse=TRUE;
  541.                             }
  542.                         }
  543.                       else
  544.                         delta_index_1++;
  545.                   }
  546.               }
  547.             if ((! recurse) && (! *fatal_error))
  548.               {
  549.                 delta_index_1=(int) stack_head->index_1;
  550.                 delta_index_2=(int) stack_head->index_2;
  551.                 stack_ptr=stack_head;
  552.                 stack_head=stack_head->next_ptr;
  553.                 free((char *) stack_ptr);
  554.                 if (stack_head == NULL)
  555.                   finished=TRUE;
  556.                 else
  557.                   {
  558.                     x-=
  559.                      (2*(*(delta_x+(24*delta_index_1+delta_index_2))));
  560.                     y-=
  561.                      (2*(*(delta_y+(24*delta_index_1+delta_index_2))));
  562.                   }
  563.               }
  564.         }
  565.       if (! *fatal_error)
  566.         {
  567.           line(1,0,(*twice_magnitude_delta_x)-1,0);
  568.           line(*x_max-(*twice_magnitude_delta_x)+1,*y_max,
  569.            *x_max,*y_max);
  570.           sound(1000);
  571.           delay(333);
  572.           nosound();
  573.         }
  574.       return;
  575.     }
  576.  
  577. static void remove_rejected_attempts(delta_x,delta_y,erase,passage,
  578.  stack_head,stack_ptr,x,x_next,y,y_next,fatal_error)
  579.   int             *delta_x;
  580.   int             *delta_y;
  581.   int             *erase;
  582.   int             *passage;
  583.   stack_1_rec_ptr *stack_head;
  584.   stack_1_rec_ptr *stack_ptr;
  585.   int             *x;
  586.   int             *x_next;
  587.   int             *y;
  588.   int             *y_next;
  589.   int             *fatal_error;
  590.     {
  591.       int             delta_index_1;
  592.       int             finished;
  593.       int             recurse;
  594.       stack_1_rec_ptr stack_start;
  595.  
  596.       stack_start=*stack_head;
  597.       if (*erase != *passage)
  598.         {
  599.           recurse=TRUE;
  600.           finished=FALSE;
  601.           while ((! finished) && (! *fatal_error))
  602.             {
  603.               if (recurse)
  604.                 {
  605.                   delta_index_1=0;
  606.                   recurse=FALSE;
  607.                 }
  608.               while ((delta_index_1 <= 3)
  609.               &&     (! recurse))
  610.                 if (*stack_head == NULL)
  611.                   {
  612.                     *x_next=(*x)+(*(delta_x+(24*delta_index_1)));
  613.                     *y_next=(*y)+(*(delta_y+(24*delta_index_1)));
  614.                     if (getpixel(*x_next,*y_next)
  615.                      == (unsigned int) *erase)
  616.                       {
  617.                         *x_next+=(*(delta_x+(24*delta_index_1)));
  618.                         *y_next+=(*(delta_y+(24*delta_index_1)));
  619.                         *x=(*x_next);
  620.                         *y=(*y_next);
  621.                         if ((*stack_ptr=(struct stack_1_rec *) malloc(
  622.                          (unsigned) sizeof(struct stack_1_rec)))
  623.                          == NULL)
  624.                           {
  625.                             *fatal_error=TRUE;
  626.                             closegraph();
  627.                             printf("? out of memory\n");
  628.                           }
  629.                         else
  630.                           {
  631.                             (*stack_ptr)->next_ptr=*stack_head;
  632.                             *stack_head=(*stack_ptr);
  633.                             (*stack_head)->index_1
  634.                              =(unsigned char) delta_index_1;
  635.                             recurse=TRUE;
  636.                           }
  637.                       }
  638.                     else
  639.                       delta_index_1++;
  640.                   }
  641.                 else
  642.                   if ((delta_index_1 + 2) % 4
  643.                    == (int) (*stack_head)->index_1)
  644.                     delta_index_1++;
  645.                   else
  646.                     {
  647.                       *x_next=(*x)+(*(delta_x+(24*delta_index_1)));
  648.                       *y_next=(*y)+(*(delta_y+(24*delta_index_1)));
  649.                       if (getpixel(*x_next,*y_next)
  650.                        == (unsigned int) *erase)
  651.                         {
  652.                           *x_next+=(*(delta_x+(24*delta_index_1)));
  653.                           *y_next+=(*(delta_y+(24*delta_index_1)));
  654.                           *x=(*x_next);
  655.                           *y=(*y_next);
  656.                           if ((*stack_ptr=(struct stack_1_rec *) malloc(
  657.                            (unsigned) sizeof(struct stack_1_rec)))
  658.                            == NULL)
  659.                             {
  660.                               *fatal_error=TRUE;
  661.                               closegraph();
  662.                               printf("? out of memory\n");
  663.                             }
  664.                           else
  665.                             {
  666.                               (*stack_ptr)->next_ptr=(*stack_head);
  667.                               *stack_head=(*stack_ptr);
  668.                               (*stack_head)->index_1
  669.                                =(unsigned char) delta_index_1;
  670.                               recurse=TRUE;
  671.                             }
  672.                         }
  673.                       else
  674.                         delta_index_1++;
  675.                     }
  676.               if ((delta_index_1 > 3) && (! *fatal_error))
  677.                 {
  678.                   if (stack_start == *stack_head)
  679.                     finished=TRUE;
  680.                   else
  681.                     {
  682.                       setcolor((unsigned int) *passage);
  683.                       *x_next=(*x);
  684.                       *y_next=(*y);
  685.                       delta_index_1=(int) ((*stack_head)->index_1);
  686.                       *stack_ptr=(*stack_head);
  687.                       (*stack_head)=(*stack_head)->next_ptr;
  688.                       free((char *) *stack_ptr);
  689.                       *x-=(2*(*(delta_x+(24*delta_index_1))));
  690.                       *y-=(2*(*(delta_y+(24*delta_index_1))));
  691.                       line(*x,*y,*x_next,*y_next);
  692.                       delta_index_1++;
  693.                     }
  694.                 }
  695.             }
  696.         }
  697.       return;
  698.     }
  699.  
  700. static void let_user_try_to_solve(delta_x,delta_y,erase,key_pressed,
  701.  magnitude_delta_x,magnitude_delta_y,passage,path,wall,y_max,
  702.  fatal_error)
  703.   int *delta_x;
  704.   int *delta_y;
  705.   int *erase;
  706.   int *key_pressed;
  707.   int *magnitude_delta_x;
  708.   int *magnitude_delta_y;
  709.   int *passage;
  710.   int *path;
  711.   int *wall;
  712.   int *y_max;
  713.   int *fatal_error;
  714.     {
  715.       int             color;
  716.       int             delta_index_1;
  717.       int             frequency;
  718.       int             passage_found;
  719.       stack_1_rec_ptr stack_head;
  720.       stack_1_rec_ptr stack_ptr;
  721.       int             x;
  722.       int             x_next;
  723.       int             y;
  724.       int             y_next;
  725.  
  726.       stack_head=NULL;
  727.       x=*magnitude_delta_x;
  728.       y=*magnitude_delta_y;
  729.       y_next=0;
  730.       setcolor((unsigned int) *path);
  731.       line(x,0,x,y);
  732.       do
  733.         {
  734.           do
  735.             {
  736.               passage_found=TRUE;
  737.               *key_pressed=getch();
  738.               if ((*key_pressed != (int) 'Q')
  739.               &&  (*key_pressed != (int) 'q')
  740.               &&  (*key_pressed != (int) 'S')
  741.               &&  (*key_pressed != (int) 's'))
  742.                 {
  743.                   if (*key_pressed == 0)
  744.                     {
  745.                       *key_pressed=getch();
  746.                       switch (*key_pressed)
  747.                         {
  748.                           case 72:
  749.                              delta_index_1=3;
  750.                              break;
  751.                           case 77:
  752.                              delta_index_1=0;
  753.                              break;
  754.                           case 80:
  755.                              delta_index_1=1;
  756.                              break;
  757.                           case 75:
  758.                              delta_index_1=2;
  759.                              break;
  760.                           default:
  761.                             {
  762.                               passage_found=FALSE;
  763.                               sound(120);
  764.                               delay(278);
  765.                               nosound();
  766.                               *key_pressed=(int) ' ';
  767.                               break;
  768.                             }
  769.                         }
  770.                     }
  771.                   else
  772.                     {
  773.                       switch (*key_pressed)
  774.                         {
  775.                           case 56:
  776.                             delta_index_1=3;
  777.                             break;
  778.                           case 54:
  779.                             delta_index_1=0;
  780.                             break;
  781.                           case 50:
  782.                             delta_index_1=1;
  783.                             break;
  784.                           case 52:
  785.                             delta_index_1=2;
  786.                             break;
  787.                           default:
  788.                             {
  789.                               passage_found=FALSE;
  790.                               sound(120);
  791.                               delay(278);
  792.                               nosound();
  793.                               break;
  794.                             }
  795.                         }
  796.                     }
  797.                   if (passage_found)
  798.                     {
  799.                       x_next=x+(*(delta_x+(24*delta_index_1)));
  800.                       y_next=y+(*(delta_y+(24*delta_index_1)));
  801.                       color=(int) getpixel(x_next,y_next);
  802.                       if (color == *wall)
  803.                         if (color == *path)
  804.                           if (stack_head == NULL)
  805.                             {
  806.                               passage_found=FALSE;
  807.                               sound(120);
  808.                               delay(278);
  809.                               nosound();
  810.                             }
  811.                           else
  812.                             {
  813.                               if
  814.                                ((((int) (stack_head->index_1)) + 2) % 4
  815.                                != delta_index_1)
  816.                                 {
  817.                                   passage_found=FALSE;
  818.                                   sound(120);
  819.                                   delay(278);
  820.                                   nosound();
  821.                                 }
  822.                             }
  823.                         else
  824.                           {
  825.                             passage_found=FALSE;
  826.                             sound(120);
  827.                             delay(278);
  828.                             nosound();
  829.                           }
  830.                       else
  831.                         {
  832.                           if (y_next == 0)
  833.                             {
  834.                               passage_found=FALSE;
  835.                               sound(120);
  836.                               delay(278);
  837.                               nosound();
  838.                             }
  839.                         }
  840.                     }
  841.                 }
  842.             }
  843.           while ((! passage_found)
  844.           &&     (*key_pressed != (int) 'Q')
  845.           &&     (*key_pressed != (int) 'q')
  846.           &&     (*key_pressed != (int) 'S')
  847.           &&     (*key_pressed != (int) 's'));
  848.           if ((*key_pressed != (int) 'Q')
  849.           &&  (*key_pressed != (int) 'q')
  850.           &&  (*key_pressed != (int) 'S')
  851.           &&  (*key_pressed != (int) 's'))
  852.             {
  853.               if (stack_head == NULL)
  854.                 {
  855.                   if ((stack_ptr=(struct stack_1_rec *) malloc(
  856.                    (unsigned) sizeof(struct stack_1_rec))) == NULL)
  857.                     {
  858.                       *fatal_error=TRUE;
  859.                       closegraph();
  860.                       printf("? out of memory\n");
  861.                     }
  862.                   else
  863.                     {
  864.                       stack_ptr->next_ptr=stack_head;
  865.                       stack_head=stack_ptr;
  866.                       stack_head->index_1=(unsigned char) delta_index_1;
  867.                     }
  868.                 }
  869.               else
  870.                 if ((((int) (stack_head->index_1)) +2) % 4
  871.                  == delta_index_1)
  872.                   {
  873.                     stack_ptr=stack_head;
  874.                     stack_head=stack_head->next_ptr;
  875.                     free((char *) stack_ptr);
  876.                   }
  877.                 else
  878.                   {
  879.                     if ((stack_ptr=(struct stack_1_rec *) malloc(
  880.                      (unsigned) sizeof(struct stack_1_rec))) == NULL)
  881.                       {
  882.                         *fatal_error=TRUE;
  883.                         closegraph();
  884.                         printf("? out of memory\n");
  885.                       }
  886.                     else
  887.                       {
  888.                         stack_ptr->next_ptr=stack_head;
  889.                         stack_head=stack_ptr;
  890.                         stack_head->index_1
  891.                          =(unsigned char) delta_index_1;
  892.                       }
  893.                   }
  894.               if (! *fatal_error)
  895.                 {
  896.                   x_next+=(*(delta_x+(24*delta_index_1)));
  897.                   y_next+=(*(delta_y+(24*delta_index_1)));
  898.                   if (y_next <= *y_max)
  899.                     {
  900.                       if (color == *path)
  901.                         setcolor((unsigned int) *erase);
  902.                       else
  903.                         setcolor((unsigned int) *path);
  904.                       line(x,y,x_next,y_next);
  905.                     }
  906.                   else
  907.                     {
  908.                       setcolor((unsigned int) *path);
  909.                       line(x,y,x_next,*y_max);
  910.                     }
  911.                   x=x_next;
  912.                   y=y_next;
  913.                 }
  914.             }
  915.         }
  916.       while ((y_next <= *y_max)
  917.       &&     (*key_pressed != (int) 'Q')
  918.       &&     (*key_pressed != (int) 'q')
  919.       &&     (*key_pressed != (int) 'S')
  920.       &&     (*key_pressed != (int) 's')
  921.       &&     (! *fatal_error));
  922.       if (! *fatal_error)
  923.         {
  924.           if (y_next > *y_max)
  925.             {
  926.               frequency=10;
  927.               for (delta_index_1=1; delta_index_1 <= 100;
  928.                delta_index_1++)
  929.                 {
  930.                   sound(frequency);
  931.                   delay(56);
  932.                   nosound();
  933.                   frequency+=10;
  934.                 };
  935.               do
  936.                 {
  937.                   *key_pressed=getch();
  938.                   if ((*key_pressed != (int) 'Q')
  939.                   &&  (*key_pressed != (int) 'q')
  940.                   &&  (*key_pressed != (int) 'S')
  941.                   &&  (*key_pressed != (int) 's'))
  942.                     {
  943.                       sound(120);
  944.                       delay(278);
  945.                       nosound();
  946.                     }
  947.                   if (*key_pressed == 0)
  948.                     {
  949.                       *key_pressed=getch();
  950.                       *key_pressed=(int) ' ';
  951.                     }
  952.                 }
  953.               while ((*key_pressed != (int) 'Q')
  954.               &&     (*key_pressed != (int) 'q')
  955.               &&     (*key_pressed != (int) 'S')
  956.               &&     (*key_pressed != (int) 's'));
  957.             }
  958.           if ((*key_pressed == (int) 'S')
  959.           ||  (*key_pressed == (int) 's'))
  960.             {
  961.               while ((stack_head != NULL) && (! *fatal_error))
  962.                 {
  963.                   remove_rejected_attempts(delta_x,delta_y,erase,
  964.                    passage,&stack_head,&stack_ptr,&x,&x_next,&y,
  965.                    &y_next,fatal_error);
  966.                   if (! *fatal_error)
  967.                     {
  968.                       delta_index_1=(int) (stack_head->index_1);
  969.                       x_next=x-2*(*(delta_x+(24*delta_index_1)));
  970.                       y_next=y-2*(*(delta_y+(24*delta_index_1)));
  971.                       setcolor((unsigned int) *passage);
  972.                       if (y <= *y_max)
  973.                         line(x,y,x_next,y_next);
  974.                       else
  975.                         line(x,*y_max,x_next,y_next);
  976.                       x=x_next;
  977.                       y=y_next;
  978.                       stack_ptr=stack_head;
  979.                       stack_head=stack_head->next_ptr;
  980.                       free((char *) stack_ptr);
  981.                     }
  982.                 }
  983.               if (! *fatal_error)
  984.                 remove_rejected_attempts(delta_x,delta_y,erase,passage,
  985.                  &stack_head,&stack_ptr,&x,&x_next,&y,&y_next,
  986.                  fatal_error);
  987.             }
  988.           else
  989.             while (stack_head != NULL)
  990.               {
  991.                 stack_ptr=stack_head;
  992.                 stack_head=stack_head->next_ptr;
  993.                 free((char *) stack_ptr);
  994.               }
  995.         }
  996.       return;
  997.     }
  998.  
  999. static void optionally_have_computer_solve(delta_x,delta_y,key_pressed,
  1000.  magnitude_delta_x,magnitude_delta_y,passage,path,y_max,fatal_error)
  1001.   int *delta_x;
  1002.   int *delta_y;
  1003.   int *key_pressed;
  1004.   int *magnitude_delta_x;
  1005.   int *magnitude_delta_y;
  1006.   int *passage;
  1007.   int *path;
  1008.   int *y_max;
  1009.   int *fatal_error;
  1010.     {
  1011.       int             finished;
  1012.       unsigned char   delta_index_1;
  1013.       int             recurse;
  1014.       stack_1_rec_ptr stack_head;
  1015.       stack_1_rec_ptr stack_ptr;
  1016.       int             x;
  1017.       int             x_next;
  1018.       int             y;
  1019.       int             y_next;
  1020.  
  1021.       if ((*key_pressed == 'S')
  1022.       ||  (*key_pressed == 's'))
  1023.         {
  1024.           x=*magnitude_delta_x;
  1025.           y=*magnitude_delta_y;
  1026.           y_next=y+(*magnitude_delta_y);
  1027.           setcolor((unsigned int) *path);
  1028.           line(x,0,x,y);
  1029.           finished=FALSE;
  1030.           recurse=TRUE;
  1031.           stack_head=NULL;
  1032.           while ((! finished) && (! *fatal_error))
  1033.             {
  1034.               if (recurse)
  1035.                 {
  1036.                   delta_index_1=0;
  1037.                   recurse=FALSE;
  1038.                 };
  1039.               while ((delta_index_1 < 4)
  1040.               &&     (! finished)
  1041.               &&     (! recurse)
  1042.               &&     (! *fatal_error))
  1043.                 {
  1044.                   x_next=x+(*(delta_x+(24*delta_index_1)));
  1045.                   y_next=y+(*(delta_y+(24*delta_index_1)));
  1046.                   if (getpixel(x_next,y_next)
  1047.                    == (unsigned int) *passage)
  1048.                     {
  1049.                       x_next+=(*(delta_x+(24*delta_index_1)));
  1050.                       y_next+=(*(delta_y+(24*delta_index_1)));
  1051.                       if (y_next <= *y_max)
  1052.                         {
  1053.                           setcolor((unsigned int) *path);
  1054.                           line(x,y,x_next,y_next);
  1055.                           x=x_next;
  1056.                           y=y_next;
  1057.                           if ((stack_ptr=(struct stack_1_rec *) malloc(
  1058.                            (unsigned) sizeof(struct stack_1_rec)))
  1059.                            == NULL)
  1060.                             {
  1061.                               *fatal_error=TRUE;
  1062.                               closegraph();
  1063.                               printf("? out of memory\n");
  1064.                             }
  1065.                           else
  1066.                             {
  1067.                               stack_ptr->next_ptr=stack_head;
  1068.                               stack_head=stack_ptr;
  1069.                               stack_head->index_1
  1070.                                =(unsigned char) delta_index_1;
  1071.                               recurse=TRUE;
  1072.                             }
  1073.                         }
  1074.                       else
  1075.                         finished=TRUE;
  1076.                     }
  1077.                   else
  1078.                     delta_index_1++;
  1079.                 };
  1080.               if ((delta_index_1 >= 4) && (! *fatal_error))
  1081.                 {
  1082.                   setcolor((unsigned int) *passage);
  1083.                   x_next=x;
  1084.                   y_next=y;
  1085.                   delta_index_1=stack_head->index_1;
  1086.                   stack_ptr=stack_head;
  1087.                   stack_head=stack_head->next_ptr;
  1088.                   free((char *) stack_ptr);
  1089.                   x-=(2*(*(delta_x+(24*delta_index_1))));
  1090.                   y-=(2*(*(delta_y+(24*delta_index_1))));
  1091.                   line(x,y,x_next,y_next);
  1092.                   delta_index_1++;
  1093.                 }
  1094.             };
  1095.           if (! *fatal_error)
  1096.             {
  1097.               line(x,y,x,*y_max);
  1098.               sound(1000);
  1099.               delay(333);
  1100.               nosound();
  1101.               *key_pressed=getch();
  1102.               if (*key_pressed == 0)
  1103.                 *key_pressed=getch();
  1104.             }
  1105.         }
  1106.       return;
  1107.     }
  1108.