home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / maze / makemaze.c < prev    next >
C/C++ Source or Header  |  1994-07-13  |  38KB  |  972 lines

  1. /*
  2.  
  3.         Specify the solution to a maze and obtain the maze.  A CGA (or better)
  4.    graphics adapter is needed.  Mazes up to 39 columns wide may be printed
  5.    on 80 column printers supporting the IBM graphics character set.
  6.  
  7.         Written (in Microsoft C 6.0) by James L. Dean on July 11, 1994.
  8.  
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <graph.h>
  14. #include <conio.h>
  15.  
  16. #define TRUE -1
  17. #define FALSE 0
  18.  
  19. static void generate_maze(int,int,int,int,char **,int *);
  20. static void get_solution(int,int,int,int,char **,int *);
  21. static void initialize(int,int,int *,int *,int *,char ***);
  22.        void main(int,char **);
  23. static void write_hex(FILE **,char *,int *);
  24. static void write_maze(int,int,char **,int,char **,int *);
  25.  
  26. /* Graphics Constants */
  27. #define VIDEOMODE            _HRESBW
  28. #define MAX_X                    639
  29. #define MAX_Y                    199
  30.  
  31. typedef struct stack_node
  32.                  {
  33.                    int               delta_index_1;       
  34.                    int               delta_index_2;
  35.                    struct stack_node *next;
  36.                  } *stack_node_ptr;
  37.  
  38. typedef struct task_node
  39.                  {
  40.                    int               delta_index_1;       
  41.                    int               delta_index_2;
  42.                    int               done;
  43.                    int               recurse;
  44.                    struct stack_node *stack_head;
  45.                    int               x;
  46.                    int               y;
  47.                    struct task_node  *next;
  48.                  } *task_node_ptr;
  49.  
  50. void main(
  51.   int  argc,
  52.   char *argv[])
  53.     {
  54.       static int  aborted;
  55.       static int  fatal_error;
  56.       static int  num_columns;
  57.       static int  num_rows;
  58.       static char **page;
  59.       static int  response;
  60.       static int  x;
  61.   
  62.       fatal_error=FALSE;
  63.       initialize(MAX_X,MAX_Y,&fatal_error,&num_columns,&num_rows,&page);
  64.       if (! fatal_error)
  65.         {
  66.           if (_setvideomode(VIDEOMODE))
  67.             {
  68.               aborted=FALSE;
  69.               get_solution(MAX_X,MAX_Y,num_columns,num_rows,page,&aborted);
  70.               if (! aborted)
  71.                 {
  72.                   generate_maze(MAX_X,MAX_Y,num_columns,num_rows,page,
  73.                    &fatal_error);
  74.                   if (! fatal_error)
  75.                     {
  76.                       response=getch();
  77.                       if (response == 0)
  78.                         getch();
  79.                     }
  80.                 }
  81.               _setvideomode(_DEFAULTMODE);
  82.               if (fatal_error)
  83.                 printf("     Fatal error:  out of memory.\n");
  84.             }
  85.           else
  86.             {
  87.               fatal_error=TRUE;
  88.               printf(
  89.         "     Fatal error:  high resolution CGA graphics are not available.\n");
  90.             }
  91.           if (! fatal_error)
  92.             write_maze(num_columns,num_rows,page,argc,argv,&fatal_error);
  93.           for (x=2*num_columns; x >= 0; x--)
  94.             free((void *) (page[x]));
  95.           free((void *) page);
  96.         }
  97.       return;
  98.     }
  99.  
  100. static void initialize(
  101.   int  max_x,
  102.   int  max_y,
  103.   int  *fatal_error,
  104.   int  *num_columns,
  105.   int  *num_rows,
  106.   char ***page)
  107.     {
  108.       static int max_num_columns;
  109.       static int max_num_rows;
  110.       static int twice_num_columns_plus_1;
  111.       static int twice_num_rows_plus_1;
  112.       static int x;
  113.  
  114.       _clearscreen(_GCLEARSCREEN);
  115.       printf("                                 Design a Maze\n");
  116.       printf("\n");
  117.       printf("\n");
  118.       printf("\n");
  119.       printf(
  120. "     You will be prompted for the number of columns and the number of\n");
  121.       printf(
  122. "rows.  Then you may use the arrow keys to specify the solution to the\n");
  123.       printf(
  124. "maze.  The solution must run from from the upper left hand corner to the\n");
  125.       printf(                    
  126. "lower right hand corner.  You may press Escape to abort specifying the\n");
  127.       printf(
  128. "solution.  After the solution is specified, the maze will be displayed.\n");
  129.       printf(
  130. "Press the space bar to exit; a copy of the maze will be saved as\n");
  131.       printf(
  132. "MAKEMAZE.OUT.\n");
  133.       printf("\n");
  134.       max_num_columns=max_x/2;
  135.       do
  136.         {
  137.           printf("     Number of columns (2 to ");
  138.           printf("%d",max_num_columns);
  139.           printf(")? ");
  140.           fflush(stdin);
  141.           scanf("%d",num_columns);
  142.           if ((*num_columns < 2)
  143.           ||  (*num_columns > max_num_columns))
  144.             {
  145.               printf(
  146.                "? The number of columns must be between 2 and ");
  147.               printf("%d",max_num_columns);
  148.               printf(", inclusively\n");
  149.             }
  150.         }
  151.       while ((*num_columns < 2)
  152.       ||     (*num_columns > max_num_columns));
  153.       printf("\n");
  154.       twice_num_columns_plus_1=2*(*num_columns)+1;
  155.       if ((*page=(char **) malloc(twice_num_columns_plus_1*sizeof(char *)))
  156.        == NULL)
  157.         {
  158.           *fatal_error=TRUE;
  159.           printf("     Fatal error:  out of memory.\n");
  160.         }
  161.       if (! *fatal_error)
  162.         {
  163.           max_num_rows=max_y/2;
  164.           do
  165.             {
  166.               printf("     Number of rows (2 to ");
  167.               printf("%d",max_num_rows);
  168.               printf(")? ");
  169.               fflush(stdin);
  170.               scanf("%d",num_rows);
  171.               if ((*num_rows < 2) || (*num_rows > max_num_rows))
  172.                 {
  173.                   printf(
  174.                    "? The number of rows must be between 2 and ");
  175.                   printf("%d",max_num_rows);
  176.                   printf(", inclusively\n");
  177.                 }
  178.             }
  179.           while ((*num_rows < 2) || (*num_rows > max_num_rows));
  180.           printf("\n");
  181.           twice_num_rows_plus_1=2*(*num_rows)+1;
  182.           for (x=0; ((! *fatal_error) && (x < twice_num_columns_plus_1)); x++)
  183.             if (((*page)[x]=(char *) malloc(twice_num_rows_plus_1*sizeof(char)))
  184.              == NULL)
  185.               {
  186.                 *fatal_error=TRUE;
  187.                 printf("     Fatal error:  out of memory.\n");
  188.                 while (x > 0)
  189.                   free((void *) ((*page)[--x]));
  190.                 free((void *) *page);
  191.               }
  192.         }
  193.       return;
  194.     }
  195.  
  196. static void get_solution(
  197.   int  max_x,
  198.   int  max_y,
  199.   int  num_columns,
  200.   int  num_rows,
  201.   char **page,
  202.   int  *aborted)
  203.     {
  204.       static int delta_index;
  205.       static int delta_x [4];
  206.       static int delta_y [4];
  207.       static int key_pressed;
  208.       static int passage_found;
  209.       static int twice_num_columns;
  210.       static int twice_num_columns_plus_1;
  211.       static int twice_num_rows;
  212.       static int twice_num_rows_plus_1;
  213.       static int x;
  214.       static int x_increment;
  215.       static int x_next;
  216.       static int x_out;
  217.       static int y;
  218.       static int y_increment;
  219.       static int y_next;
  220.       static int y_out;
  221.       
  222.       *aborted=FALSE;
  223.       twice_num_columns=2*num_columns;
  224.       twice_num_columns_plus_1=twice_num_columns+1;
  225.       twice_num_rows=2*num_rows;
  226.       twice_num_rows_plus_1=twice_num_rows+1;
  227.       for (x=0; x < twice_num_columns_plus_1; x++)
  228.         for (y=0; y < twice_num_rows_plus_1; y++)
  229.           page[x][y]=' ';
  230.       _setcolor((short) 1);
  231.       x_increment=max_x/num_columns;
  232.       y_increment=max_y/num_rows;
  233.       x_out=num_columns*x_increment;
  234.       y_out=0;
  235.       for (y=0; y < twice_num_rows_plus_1; y+=2)
  236.         { 
  237.           for (x=0; x < twice_num_columns_plus_1; x++)
  238.             page[x][y]='W';
  239.           _moveto((short) 0,(short) y_out);
  240.           _lineto((short) x_out,(short) y_out);
  241.           y_out+=y_increment;
  242.         }
  243.       y_out=num_rows*y_increment;
  244.       x_out=0;
  245.       for (x=0; x < twice_num_columns_plus_1; x+=2)
  246.         { 
  247.           for (y=0; y < twice_num_rows_plus_1; y++)
  248.             page[x][y]='W';
  249.           _moveto((short) x_out,(short) 0);
  250.           _lineto((short) x_out,(short) y_out);
  251.           x_out+=x_increment;
  252.         }
  253.       _setcolor((short) 0);
  254.       _moveto((short) 1,(short) 0);
  255.       _lineto((short) (x_increment-1),(short) 0);
  256.       page[1][0]='S';
  257.       x_out=num_columns*x_increment-x_increment+1;
  258.       _moveto((short) x_out,(short) y_out);
  259.       x_out=num_columns*x_increment-1;
  260.       _lineto((short) x_out,(short) y_out);
  261.       page[twice_num_columns-1][twice_num_rows]='S';
  262.       delta_x[0]=1;
  263.       delta_y[0]=0;
  264.       delta_x[1]=0;
  265.       delta_y[1]=1;
  266.       delta_x[2]=-1;
  267.       delta_y[2]=0;
  268.       delta_x[3]=0;
  269.       delta_y[3]=-1;
  270.       x=1;
  271.       y=1;
  272.       page[x][y]='S';
  273.       do
  274.         {
  275.           do
  276.             {
  277.               passage_found=TRUE;
  278.               key_pressed=getch();
  279.               if (key_pressed == 0)
  280.                 {
  281.                   key_pressed=getch();
  282.                   switch (key_pressed)
  283.                     {
  284.                       case 72:
  285.                          delta_index=3;
  286.                          break;
  287.                       case 77:
  288.                          delta_index=0;
  289.                          break;
  290.                       case 80:
  291.                          delta_index=1;
  292.                          break;
  293.                       case 75:
  294.                          delta_index=2;
  295.                          break;
  296.                       default:
  297.                          passage_found=FALSE;
  298.                          break;
  299.                     }
  300.                 }
  301.               else
  302.                 {
  303.                   switch (key_pressed)
  304.                     {
  305.                       case 27:
  306.                         passage_found=FALSE;
  307.                         *aborted=TRUE;
  308.                         break;
  309.                       case 56:
  310.                         delta_index=3;
  311.                         break;
  312.                       case 54:
  313.                         delta_index=0;
  314.                         break;
  315.                       case 50:
  316.                         delta_index=1;
  317.                         break;
  318.                       case 52:
  319.                         delta_index=2;
  320.                         break;
  321.                       default:
  322.                         passage_found=FALSE;
  323.                         break;
  324.                     }
  325.                 }
  326.               if (passage_found)
  327.                 {
  328.                   x_next=x+delta_x[delta_index];
  329.                   if (x_next <= 0)
  330.                     passage_found=FALSE;
  331.                   else
  332.                     if (x_next >= twice_num_columns)
  333.                       passage_found=FALSE;
  334.                     else
  335.                       {
  336.                         y_next=y+delta_y[delta_index];
  337.                         if (y_next <= 0)
  338.                           passage_found=FALSE;
  339.                         else
  340.                           if (y_next >= twice_num_rows)
  341.                             passage_found=FALSE;
  342.                           else
  343.                             if (page[x_next][y_next] == 'S')
  344.                               { /* back out part of solution */
  345.                                 _setcolor((short) 1);
  346.                                 page[x][y]=' ';
  347.                                 page[x_next][y_next]='W';
  348.                                 if (x == x_next)
  349.                                   {
  350.                                     y_out=y_increment*y_next/2;
  351.                                     x_out=x_increment*(x-1)/2+1;
  352.                                     _moveto((short) x_out,(short) y_out);
  353.                                     x_out=x_increment*(x+1)/2-1;
  354.                                     _lineto((short) x_out,(short) y_out);
  355.                                   }
  356.                                 else
  357.                                   {
  358.                                     x_out=x_increment*x_next/2;
  359.                                     y_out=y_increment*(y-1)/2+1;
  360.                                     _moveto((short) x_out,(short) y_out);
  361.                                     y_out=y_increment*(y+1)/2-1;
  362.                                     _lineto((short) x_out,(short) y_out);
  363.                                   }
  364.                                 x=x_next+delta_x[delta_index];
  365.                                 y=y_next+delta_y[delta_index];
  366.                               }
  367.                             else
  368.                               if (page[x_next+delta_x[delta_index]][
  369.                                y_next+delta_y[delta_index]] == 'S')
  370.                                 passage_found=FALSE;
  371.                               else
  372.                                 { /* add part of solution */
  373.                                   _setcolor((short) 0);
  374.                                   page[x_next][y_next]='S';
  375.                                   if (x == x_next)
  376.                                     {
  377.                                       y_out=y_increment*y_next/2;
  378.                                       x_out=x_increment*(x-1)/2+1;
  379.                                       _moveto((short) x_out,(short) y_out);
  380.                                       x_out=x_increment*(x+1)/2-1;
  381.                                       _lineto((short) x_out,(short) y_out);
  382.                                     }
  383.                                   else
  384.                                     {
  385.                                       x_out=x_increment*x_next/2;
  386.                                       y_out=y_increment*(y-1)/2+1;
  387.                                       _moveto((short) x_out,(short) y_out);
  388.                                       y_out=y_increment*(y+1)/2-1;
  389.                                       _lineto((short) x_out,(short) y_out);
  390.                                     }
  391.                                   x=x_next+delta_x[delta_index];
  392.                                   y=y_next+delta_y[delta_index];
  393.                                   page[x][y]='S';
  394.                                 }
  395.                       }
  396.                 }
  397.             }
  398.           while ((! passage_found) && (! *aborted));
  399.         }
  400.       while (((x != twice_num_columns-1)
  401.            || (y != twice_num_rows-1))
  402.       &&     (! *aborted));
  403.     }
  404.  
  405. static void generate_maze(
  406.   int  max_x,
  407.   int  max_y,
  408.   int  num_columns,
  409.   int  num_rows,
  410.   char **page,
  411.   int  *fatal_error)
  412.     {
  413.       static int            delta_index;
  414.       static int            delta_index_2a;
  415.       static int            delta_index_2b;
  416.       static int            delta_index_2c;
  417.       static int            delta_index_2d;
  418.       static int            delta_x [24] [4];
  419.       static int            delta_y [24] [4];
  420.       static int            some_task;
  421.       static stack_node_ptr stack_ptr;
  422.       static task_node_ptr  task_head;
  423.       static int            task_possible;
  424.       static task_node_ptr  task_ptr;
  425.       static int            tasks_done;
  426.       static int            twice_num_columns;
  427.       static int            twice_num_columns_plus_1;
  428.       static int            twice_num_rows;
  429.       static int            twice_num_rows_plus_1;
  430.       static int            x;
  431.       static int            x_increment;
  432.       static int            x_next;
  433.       static int            x_out;
  434.       static int            y;
  435.       static int            y_increment;
  436.       static int            y_next;
  437.       static int            y_out;
  438.   
  439.       twice_num_columns=2*num_columns;
  440.       twice_num_columns_plus_1=twice_num_columns+1;
  441.       twice_num_rows=2*num_rows;
  442.       twice_num_rows_plus_1=twice_num_rows+1;
  443.       x_increment=max_x/num_columns;
  444.       y_increment=max_y/num_rows;
  445.       delta_x[0][0]=1;
  446.       delta_y[0][0]=0;
  447.       delta_x[0][1]=0;
  448.       delta_y[0][1]=1;
  449.       delta_x[0][2]=-1;
  450.       delta_y[0][2]=0;
  451.       delta_x[0][3]=0;
  452.       delta_y[0][3]=-1;
  453.       delta_index=0;
  454.       for (delta_index_2a=0; delta_index_2a < 4; delta_index_2a++)
  455.         for (delta_index_2b=0; delta_index_2b < 4; delta_index_2b++)
  456.           if (delta_index_2a != delta_index_2b)
  457.             for (delta_index_2c=0; delta_index_2c < 4;
  458.              delta_index_2c++)
  459.               if ((delta_index_2a != delta_index_2c)
  460.               &&  (delta_index_2b != delta_index_2c))
  461.                 for (delta_index_2d=0; delta_index_2d < 4;
  462.                  delta_index_2d++)
  463.                   if ((delta_index_2a != delta_index_2d)
  464.                   &&  (delta_index_2b != delta_index_2d)
  465.                   &&  (delta_index_2c != delta_index_2d))
  466.                     {
  467.                       delta_x[delta_index][delta_index_2a]
  468.                        =delta_x[0][0];
  469.                       delta_y[delta_index][delta_index_2a]
  470.                        =delta_y[0][0];
  471.                       delta_x[delta_index][delta_index_2b]
  472.                        =delta_x[0][1];
  473.                       delta_y[delta_index][delta_index_2b]
  474.                        =delta_y[0][1];
  475.                       delta_x[delta_index][delta_index_2c]
  476.                        =delta_x[0][2];
  477.                       delta_y[delta_index][delta_index_2c]
  478.                        =delta_y[0][2];
  479.                       delta_x[delta_index][delta_index_2d]
  480.                        =delta_x[0][3];
  481.                       delta_y[delta_index++][delta_index_2d]
  482.                        =delta_y[0][3];
  483.                     }
  484.       task_head=NULL;
  485.       some_task=FALSE;
  486.       task_possible=TRUE;
  487.       while ((! *fatal_error) && (! some_task) && (task_possible))
  488.         {
  489.           task_possible=FALSE;
  490.           y=0;
  491.           for (x=2; ((! *fatal_error) && (x < twice_num_columns)); x+=2)
  492.             if (page[x][1] != 'S')
  493.               {
  494.                 task_possible=TRUE;
  495.                 if ((page[x-1][1] == 'S')
  496.                 ||  (page[x+1][1] == 'S')
  497.                 ||  (rand()%4 == 0))
  498.                   {
  499.                     if ((task_ptr=(struct task_node *)
  500.                      malloc(sizeof(struct task_node)))
  501.                      == NULL)
  502.                       *fatal_error=TRUE;
  503.                     else
  504.                       {
  505.                         task_ptr->delta_index_1=0;
  506.                         task_ptr->delta_index_2=0;
  507.                         task_ptr->done=FALSE;
  508.                         task_ptr->recurse=TRUE;
  509.                         task_ptr->stack_head=NULL;
  510.                         task_ptr->x=x;
  511.                         task_ptr->y=y;
  512.                         task_ptr->next=task_head;
  513.                         task_head=task_ptr;
  514.                         some_task=TRUE;
  515.                       }
  516.                   }
  517.               }
  518.           x=twice_num_columns;
  519.           for (y=2; ((! *fatal_error) && (y < twice_num_rows)); y+=2)
  520.             if (page[x-1][y] != 'S')
  521.               {
  522.                 task_possible=TRUE;
  523.                 if ((page[x-1][y-1] == 'S')
  524.                 ||  (page[x-1][y+1] == 'S')
  525.                 ||  (rand()%4 == 0))
  526.                   {
  527.                     if ((task_ptr=(struct task_node *)
  528.                      malloc(sizeof(struct task_node)))
  529.                      == NULL)
  530.                       *fatal_error=TRUE;
  531.                     else
  532.                       {
  533.                         task_ptr->delta_index_1=0;
  534.                         task_ptr->delta_index_2=0;
  535.                         task_ptr->done=FALSE;
  536.                         task_ptr->recurse=TRUE;
  537.                         task_ptr->stack_head=NULL;
  538.                         task_ptr->x=x;
  539.                         task_ptr->y=y;
  540.                         task_ptr->next=task_head;
  541.                         task_head=task_ptr;
  542.                         some_task=TRUE;
  543.                       }
  544.                   }
  545.               }
  546.         }
  547.       some_task=FALSE;
  548.       task_possible=TRUE;
  549.       while ((! *fatal_error) && (! some_task) && (task_possible))
  550.         {
  551.           task_possible=FALSE;
  552.           x=0;
  553.           for (y=2; ((! *fatal_error) && (y < twice_num_rows)); y+=2)
  554.             if (page[1][y] != 'S')
  555.               {
  556.                 task_possible=TRUE;
  557.                 if ((page[1][y-1] == 'S')
  558.                 ||  (page[1][y+1] == 'S')
  559.                 ||  (rand()%4 == 0))
  560.                   {
  561.                     if ((task_ptr=(struct task_node *)
  562.                      malloc(sizeof(struct task_node)))
  563.                      == NULL)
  564.                       *fatal_error=TRUE;
  565.                     else
  566.                       {
  567.                         task_ptr->delta_index_1=0;
  568.                         task_ptr->delta_index_2=0;
  569.                         task_ptr->done=FALSE;
  570.                         task_ptr->recurse=TRUE;
  571.                         task_ptr->stack_head=NULL;
  572.                         task_ptr->x=x;
  573.                         task_ptr->y=y;
  574.                         task_ptr->next=task_head;
  575.                         task_head=task_ptr;
  576.                         some_task=TRUE;
  577.                       }
  578.                   }
  579.               }
  580.           y=twice_num_rows;
  581.           for (x=2; ((! *fatal_error) && (x < twice_num_columns)); x+=2)
  582.             if (page[x][y-1] != 'S')
  583.               {
  584.                 task_possible=TRUE;
  585.                 if ((page[x-1][y-1] == 'S')
  586.                 ||  (page[x+1][y-1] == 'S')
  587.                 ||  (rand()%4 == 0))
  588.                   {
  589.                     if ((task_ptr=(struct task_node *) 
  590.                      malloc(sizeof(struct task_node)))
  591.                      == NULL)
  592.                       *fatal_error=TRUE;
  593.                     else
  594.                       {
  595.                         task_ptr->delta_index_1=0;
  596.                         task_ptr->delta_index_2=0;
  597.                         task_ptr->done=FALSE;
  598.                         task_ptr->recurse=TRUE;
  599.                         task_ptr->stack_head=NULL;
  600.                         task_ptr->x=x;
  601.                         task_ptr->y=y;
  602.                         task_ptr->next=task_head;
  603.                         task_head=task_ptr;
  604.                         some_task=TRUE;
  605.                       }
  606.                   }
  607.               }
  608.         }
  609.       _clearscreen(_GCLEARSCREEN);
  610.       for (x=0; x < twice_num_columns_plus_1; x++)
  611.         for (y=0; y < twice_num_rows_plus_1; y++)
  612.           if (page[x][y] == 'W')
  613.             page[x][y]=' ';
  614.       _setcolor((short) 1);
  615.       _moveto((short) 0,(short) 0);
  616.       x_out=num_columns*x_increment;
  617.       _lineto((short) x_out,(short) 0);
  618.       y_out=num_rows*y_increment;
  619.       _lineto((short) x_out,(short) y_out);
  620.       _lineto((short) 0,(short) y_out);
  621.       _lineto((short) 0,(short) 0);
  622.       _setcolor((short) 0);
  623.       _moveto((short) 1,(short) 0);
  624.       _lineto((short) (x_increment-1),(short) 0);
  625.       x_out=num_columns*x_increment-x_increment+1;
  626.       _moveto((short) x_out,(short) y_out);
  627.       x_out=num_columns*x_increment-1;
  628.       _lineto((short) x_out,(short) y_out);
  629.       for (x=0; x < twice_num_columns_plus_1; x++)
  630.         {
  631.           page[x][0]='W';
  632.           page[x][twice_num_rows]='W';
  633.         }
  634.       for (y=0; y < twice_num_rows_plus_1; y++)
  635.         {
  636.           page[0][y]='W';
  637.           page[twice_num_columns][y]='W';
  638.         }
  639.       tasks_done=FALSE;
  640.       while ((! *fatal_error) && (! tasks_done))
  641.         {
  642.           tasks_done=TRUE;
  643.           task_ptr=task_head;
  644.           while ((! *fatal_error) && (task_ptr != NULL))
  645.             {
  646.               if (! (task_ptr->done))
  647.                 {
  648.                   if (task_ptr->recurse)
  649.                     {
  650.                       task_ptr->delta_index_1=rand()%24;
  651.                       task_ptr->delta_index_2=0;
  652.                       task_ptr->recurse=FALSE;
  653.                     }
  654.                   while ((task_ptr->delta_index_2 < 4)
  655.                   &&     (! (task_ptr->recurse))
  656.                   &&     (! *fatal_error))
  657.                     {
  658.                       x_next=task_ptr->x
  659.                        +delta_x[task_ptr->delta_index_1][
  660.                        task_ptr->delta_index_2];
  661.                       if ((x_next <= 0) || (x_next >= twice_num_columns))
  662.                         (task_ptr->delta_index_2)++;
  663.                       else
  664.                         {
  665.                           y_next=task_ptr->y
  666.                            +delta_y[task_ptr->delta_index_1][
  667.                            task_ptr->delta_index_2];
  668.                           if ((y_next <= 0) || (y_next >= twice_num_rows))
  669.                             (task_ptr->delta_index_2)++;
  670.                           else
  671.                             if (page[x_next][y_next] == ' ')
  672.                               {
  673.                                 x_next
  674.                                  +=delta_x[task_ptr->delta_index_1][
  675.                                  task_ptr->delta_index_2];
  676.                                 if ((x_next <= 0) 
  677.                                 ||  (x_next >= twice_num_columns))
  678.                                   (task_ptr->delta_index_2)++;
  679.                                 else
  680.                                   {
  681.                                     y_next
  682.                                      +=delta_y[task_ptr->delta_index_1][
  683.                                      task_ptr->delta_index_2];
  684.                                     if ((y_next <= 0)
  685.                                     ||  (y_next >= twice_num_rows))
  686.                                       (task_ptr->delta_index_2)++;
  687.                                     else
  688.                                       if (page[x_next][y_next] == ' ')
  689.                                         {
  690.                                           page[(task_ptr->x+x_next)/2][
  691.                                            (task_ptr->y+y_next)/2]='W';
  692.                                           page[x_next][y_next]='W';
  693.                                           _setcolor((short) 1);
  694.                                           x_out=task_ptr->x*x_increment/2;
  695.                                           y_out=task_ptr->y*y_increment/2;
  696.                                           _moveto((short) x_out,(short) y_out);
  697.                                           x_out=x_next*x_increment/2;
  698.                                           y_out=y_next*y_increment/2;
  699.                                           _lineto((short) x_out,(short) y_out);
  700.                                           task_ptr->x=x_next;
  701.                                           task_ptr->y=y_next;
  702.                                           if ((stack_ptr=(struct stack_node *)
  703.                                            malloc((unsigned)
  704.                                            sizeof(struct stack_node))) == NULL)
  705.                                             *fatal_error=TRUE;
  706.                                           else
  707.                                             {
  708.                                               stack_ptr->next
  709.                                                =task_ptr->stack_head;
  710.                                               task_ptr->stack_head=stack_ptr;
  711.                                               (task_ptr->stack_head)
  712.                                                ->delta_index_1
  713.                                                =task_ptr->delta_index_1;
  714.                                               (task_ptr->stack_head)
  715.                                                ->delta_index_2
  716.                                                =task_ptr->delta_index_2;
  717.                                               task_ptr->recurse=TRUE;
  718.                                             }
  719.                                         }
  720.                                       else
  721.                                         (task_ptr->delta_index_2)++;
  722.                                   }
  723.                               }
  724.                             else
  725.                               (task_ptr->delta_index_2)++;
  726.                         }
  727.                     }
  728.                   if ((! task_ptr->recurse) && (! *fatal_error))
  729.                     {
  730.                       stack_ptr=task_ptr->stack_head;
  731.                       if (stack_ptr == NULL)
  732.                         task_ptr->done=TRUE;
  733.                       else
  734.                         {
  735.                           task_ptr->delta_index_1
  736.                            =(task_ptr->stack_head)->delta_index_1;
  737.                           task_ptr->delta_index_2
  738.                            =(task_ptr->stack_head)->delta_index_2;
  739.                           task_ptr->stack_head=stack_ptr->next;
  740.                           free((void *) stack_ptr);
  741.                           if (task_ptr->stack_head == NULL)
  742.                             task_ptr->done=TRUE;
  743.                           else
  744.                             {
  745.                               task_ptr->x-=2*delta_x[task_ptr->delta_index_1][
  746.                                task_ptr->delta_index_2];
  747.                               task_ptr->y-=2*delta_y[task_ptr->delta_index_1][
  748.                                task_ptr->delta_index_2];
  749.                             }
  750.                         }
  751.                     }
  752.                   tasks_done&=(task_ptr->done);
  753.                 }
  754.               task_ptr=task_ptr->next;
  755.             }
  756.         }
  757.       page[1][0]='S';
  758.       page[twice_num_columns-1][twice_num_rows]='S';
  759.       while (task_head != NULL)
  760.         {
  761.           task_ptr=task_head->next;
  762.           free((void *) task_head);
  763.           task_head=task_ptr;
  764.         }
  765.       return;
  766.     }
  767.  
  768. static void write_hex(
  769.   FILE **maze,
  770.   char *hex,
  771.   int  *fatal_error)
  772.    {
  773.      static int  byte;
  774.      static char byte_in_hex [3];
  775.  
  776.      while ((*hex) && (! *fatal_error))
  777.        {
  778.          byte_in_hex[0]=*hex++;
  779.          if (*hex)
  780.            byte_in_hex[1]=*hex++;
  781.          else
  782.            byte_in_hex[1]='0';
  783.          byte_in_hex[2]='\0';
  784.          sscanf(&byte_in_hex[0],"%x",&byte);
  785.          *fatal_error=(fputc(byte,*maze) != byte);
  786.        }
  787.      return;
  788.    }
  789.  
  790. static void write_maze(
  791.   int  num_columns,
  792.   int  num_rows,
  793.   char **page,
  794.   int  argc,
  795.   char *argv[],
  796.   int  *fatal_error)
  797.     {
  798.              FILE *maze;
  799.       static int  twice_num_columns;
  800.       static int  twice_num_rows;
  801.       static int  x;
  802.       static int  x_minus_1;
  803.       static int  x_plus_1;
  804.       static int  y;
  805.       static int  y_minus_1;
  806.       static int  y_next;
  807.       static int  y_plus_1;
  808.  
  809.       if ((maze=fopen("MAKEMAZE.OUT","w")) == NULL)
  810.         {
  811.           *fatal_error=TRUE;
  812.           printf("     Fatal error:  cannot open MAKEMAZE.OUT for output.\n");
  813.         }
  814.       else
  815.         {
  816.           if (argc >= 2)
  817.             write_hex(&maze,argv[1],fatal_error);
  818.           twice_num_columns=2*num_columns;
  819.           twice_num_rows=2*num_rows;
  820.           if (! *fatal_error)
  821.             *fatal_error=(fputc(0xb3,maze) != 0xb3);
  822.           x=1;
  823.           while ((! *fatal_error) && (x < twice_num_columns))
  824.             {
  825.               if (page[x][0] == 'W')
  826.                 *fatal_error=(fputc(0xc4,maze) != 0xc4);
  827.               else
  828.                 *fatal_error=(fputc((int) ' ',maze) != ((int) ' '));
  829.               x++;
  830.               if ((! *fatal_error) && (x < twice_num_columns))
  831.                 {
  832.                   if (page[x][1] == 'W')
  833.                     *fatal_error=(fputc(0xc2,maze) != 0xc2);
  834.                   else
  835.                     *fatal_error=(fputc(0xc4,maze) != 0xc4);
  836.                   x++;
  837.                 }
  838.             }
  839.           if (! *fatal_error)
  840.             *fatal_error=(fputc(0xbf,maze) != 0xbf);
  841.           if (! *fatal_error)
  842.             *fatal_error=(fputc((int) '\n',maze) != ((int) '\n'));
  843.           y=2;
  844.           while ((! *fatal_error) && (y < twice_num_rows))
  845.             {
  846.               if (page[1][y] == 'W')
  847.                 *fatal_error=(fputc(0xc3,maze) != 0xc3);
  848.               else
  849.                 *fatal_error=(fputc(0xb3,maze) != 0xb3);
  850.               x=1;
  851.               while ((! *fatal_error) && (x < twice_num_columns))
  852.                 {
  853.                   if (page[x][y] == 'W')
  854.                     *fatal_error=(fputc(0xc4,maze) != 0xc4);
  855.                   else
  856.                     *fatal_error=(fputc((int) ' ',maze) != ((int) ' '));
  857.                   x++;
  858.                   if ((! *fatal_error) && (x < twice_num_columns))
  859.                     {
  860.                       x_minus_1=x-1;
  861.                       x_plus_1=x+1;
  862.                       y_minus_1=y-1;
  863.                       y_plus_1=y+1;
  864.                       if (page[x_minus_1][y] == 'W')
  865.                         if (page[x][y_minus_1] == 'W')
  866.                           if (page[x][y_plus_1] == 'W')
  867.                             if (page[x_plus_1][y] == 'W')
  868.                               *fatal_error=(fputc(0xc5,maze) != 0xc5);
  869.                             else
  870.                               *fatal_error=(fputc(0xb4,maze) != 0xb4);
  871.                           else
  872.                             if (page[x_plus_1][y] == 'W')
  873.                               *fatal_error=(fputc(0xc1,maze) != 0xc1);
  874.                             else
  875.                               *fatal_error=(fputc(0xd9,maze) != 0xd9);
  876.                         else
  877.                           if (page[x][y_plus_1] == 'W')
  878.                             if (page[x_plus_1][y] == 'W')
  879.                               *fatal_error=(fputc(0xc2,maze) != 0xc2);
  880.                             else
  881.                               *fatal_error=(fputc(0xbf,maze) != 0xbf);
  882.                           else
  883.                             *fatal_error=(fputc(0xc4,maze) != 0xc4);
  884.                       else
  885.                         if (page[x][y_minus_1] == 'W')
  886.                           if (page[x][y_plus_1] == 'W')
  887.                             if (page[x_plus_1][y] == 'W')
  888.                               *fatal_error=(fputc(0xc3,maze) != 0xc3);
  889.                             else
  890.                               *fatal_error=(fputc(0xb3,maze) != 0xb3);
  891.                           else
  892.                             if (page[x_plus_1][y] == 'W')
  893.                               *fatal_error=(fputc(0xc0,maze) != 0xc0);
  894.                             else
  895.                               {
  896.                                 y_next=y+2;
  897.                                 if (y_next < twice_num_rows)
  898.                                   if ((page[x_minus_1][y_next] != 'W')
  899.                                   &&  (page[x][y_next-1] != 'W')
  900.                                   &&  (page[x_plus_1][y_next] != 'W')
  901.                                   &&  (page[x][y_next+1] == 'W'))
  902.                                    *fatal_error
  903.                                     =(fputc((int) ' ',maze) != ((int) ' '));
  904.                                   else
  905.                                    *fatal_error=(fputc(0xb3,maze) != 0xb3);
  906.                                 else
  907.                                   if (page[x][y_next-1] == 'W')
  908.                                    *fatal_error
  909.                                     =(fputc((int) ' ',maze) != ((int) ' '));
  910.                                   else
  911.                                    *fatal_error=(fputc(0xb3,maze) != 0xb3);
  912.                               }
  913.                         else
  914.                           if (page[x][y_plus_1] == 'W')
  915.                             if (page[x_plus_1][y] == 'W')
  916.                               *fatal_error=(fputc(0xda,maze) != 0xda);
  917.                             else
  918.                               *fatal_error=(fputc(0xb3,maze) != 0xb3); 
  919.                           else
  920.                             if (page[x_plus_1][y] == 'W')
  921.                               *fatal_error=(fputc(0xc4,maze) != 0xc4);
  922.                             else
  923.                               *fatal_error
  924.                                =(fputc((int) ' ',maze) != ((int) ' '));
  925.                       x=x_plus_1;
  926.                     }
  927.                 }
  928.               x_minus_1=twice_num_columns-1;
  929.               if (! *fatal_error)
  930.                 {
  931.                   if (page[x_minus_1][y] == 'W')
  932.                     *fatal_error=(fputc(0xb4,maze) != 0xb4);
  933.                   else
  934.                     *fatal_error=(fputc(0xb3,maze) != 0xb3);
  935.                 }
  936.               y+=2;
  937.               if (! *fatal_error)
  938.                 *fatal_error=(fputc((int) '\n',maze) != ((int) '\n'));
  939.             }
  940.           if (! *fatal_error)
  941.             *fatal_error=(fputc(0xc0,maze) != 0xc0);
  942.           x=1;
  943.           while ((! *fatal_error) && (x < twice_num_columns))
  944.             {
  945.               if (page[x][twice_num_rows] == 'W')
  946.                 *fatal_error=(fputc(0xc4,maze) != 0xc4);
  947.               else
  948.                 *fatal_error=(fputc((int) ' ',maze) != ((int) ' '));
  949.               x++;
  950.               if ((! *fatal_error) && (x < twice_num_columns))
  951.                 {
  952.                   y_minus_1=twice_num_rows-1;
  953.                   if (page[x][y_minus_1] == 'W')
  954.                     *fatal_error=(fputc(0xc1,maze) != 0xc1);
  955.                   else
  956.                     *fatal_error=(fputc(0xc4,maze) != 0xc4);
  957.                   x++;
  958.                 }
  959.             }
  960.           if (! *fatal_error)
  961.             *fatal_error=(fputc(0xb3,maze) != 0xb3);
  962.           if (! *fatal_error)
  963.             *fatal_error=(fputc((int) '\n',maze) != ((int) '\n'));
  964.           if ((! *fatal_error) && (argc >= 3))
  965.             write_hex(&maze,argv[2],fatal_error);
  966.           if (*fatal_error)
  967.             printf("     Fatal error:  failure to write MAKEMAZE.OUT.\n");
  968.           fclose(maze);
  969.         }
  970.       return;
  971.     }
  972.