home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / pmmaze.zip / MAZE.C < prev    next >
Text File  |  1989-02-08  |  39KB  |  1,070 lines

  1. #define INCL_PM
  2. #include <os2.h>
  3. #include <stdlib.h>
  4. #include <malloc.h>
  5. #include "maze.h"
  6.  
  7.  
  8. // Added these #defines for the four colored items, replacing the literal
  9. // values which I found in the code.  (NjB 2/8/89)
  10.  
  11. #define    WALLCOLOR        CLR_PALEGRAY
  12. #define    FLOORCOLOR        CLR_BLACK
  13. #define    GOODPATHCOLOR    CLR_GREEN
  14. #define    BADPATHCOLOR    CLR_RED
  15.  
  16. typedef struct row_rec
  17.                  {
  18.                    char           *row_ptr;
  19.                    struct row_rec *predecessor_ptr;
  20.                    struct row_rec *successor_ptr;
  21.                  } *row_rec_ptr;
  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      clear_paths(row_rec_ptr *,int *);
  37. MRESULT EXPENTRY ClientWndProc(HWND,USHORT,MPARAM,MPARAM);
  38. static void      create_maze(int *,int *,row_rec_ptr *,row_rec_ptr *,
  39.                   int *);
  40. static void      destroy_maze(row_rec_ptr *,row_rec_ptr *);
  41. MRESULT EXPENTRY HelpProc(HWND,USHORT,MPARAM,MPARAM);
  42. int cdecl        main(void);
  43. static void      optionally_have_computer_solve(row_rec_ptr *,
  44.                   row_rec_ptr *,int *,int *,int *,int *);
  45. static void      paint_maze(row_rec_ptr *,int *,int *,int *,int *,int *,
  46.                   int *,int *,HPS,int *);
  47. static void      size_maze(int *,int *,row_rec_ptr *,row_rec_ptr *,
  48.                   int *,int *,int *,int *,int *,int *,int *,int *,int *,
  49.                   int *,int *,int *);
  50.  
  51. int cdecl main(void)
  52.   {
  53.     ULONG       ctldata;
  54.     HAB         hAB;
  55.     HMQ         hmq;
  56.     HWND        hwndClient;
  57.     HWND        hwndFrame;
  58.     QMSG        qmsg;
  59.     static CHAR szClientClass [] = "Maze";
  60.  
  61.     hAB=WinInitialize(NULL);
  62.     hmq=WinCreateMsgQueue(hAB,0);
  63.     WinRegisterClass(hAB,(PCH) szClientClass,(PFNWP) ClientWndProc,
  64.      CS_SYNCPAINT|CS_SIZEREDRAW,0);
  65.     ctldata=FCF_STANDARD & ~FCF_ACCELTABLE & ~FCF_ICON;
  66.     hwndFrame=WinCreateStdWindow(HWND_DESKTOP,
  67.      WS_VISIBLE,&ctldata,
  68.      (PCH) szClientClass,NULL,0L,(HMODULE) NULL,ID_MAINMENU,
  69.      (HWND FAR *) &hwndClient);
  70.     WinShowWindow(hwndFrame,TRUE);
  71.     while (WinGetMsg(hAB,(PQMSG) &qmsg,(HWND) NULL,0,0))
  72.      WinDispatchMsg(hAB,(PQMSG) &qmsg);
  73.     WinDestroyWindow(hwndFrame);
  74.     WinDestroyMsgQueue(hmq);
  75.     WinTerminate(hAB);
  76.     return(0);
  77.   }
  78.  
  79. MRESULT EXPENTRY ClientWndProc(HWND hwnd,USHORT msg,MPARAM mp1,
  80.  MPARAM mp2)
  81.   {
  82.     static row_rec_ptr current_ptr;
  83.            int         delta_index_1;
  84.     static int         delta_x [4] [24];
  85.     static int         delta_y [4] [24];
  86.     static int         fatal_error;
  87.            USHORT      frequency;
  88.            HPS         hPS;
  89.            HWND        hwndMenu;
  90.     static int         magnitude_delta_x;
  91.     static int         magnitude_delta_y;
  92.     static int         max_x;
  93.     static int         max_y;
  94.            row_rec_ptr next_ptr;
  95.     static int         num_columns;
  96.     static int         num_rows;
  97.            int         passage_found;
  98.     static POINTL      position;
  99.     static row_rec_ptr row_head;
  100.     static row_rec_ptr row_tail;
  101.     static int         r_n [8];
  102.     static int         solved;
  103.     static int         twice_magnitude_delta_x;
  104.     static int         twice_magnitude_delta_y;
  105.     static int         x;
  106.     static int         x_max;
  107.     static int         y_max;
  108.            int         x_next;
  109.  
  110.     switch (msg)
  111.       {
  112.         case WM_CREATE:
  113.           solved=TRUE;
  114.           max_x=0;
  115.           max_y=0;
  116.           create_maze(&delta_x[0][0],&delta_y[0][0],
  117.            &row_head,&row_tail,&fatal_error);
  118.           break;
  119.         case WM_CHAR:
  120.           if ((! solved) && (! fatal_error)
  121.           &&  (max_x >= 20) && (max_y >= 20)
  122.           &&  (! ((ULONG) KC_KEYUP & (ULONG) mp1)))
  123.             {
  124.               passage_found=TRUE;
  125.               if ((ULONG) KC_CHAR & (ULONG) mp1)
  126.                 switch (SHORT1FROMMP(mp2))
  127.                   {
  128.                     case '8':
  129.                       delta_index_1=1;
  130.                       break;
  131.                     case '4':
  132.                       delta_index_1=2;
  133.                       break;
  134.                     case '6':
  135.                       delta_index_1=0;
  136.                       break;
  137.                     case '2':
  138.                       delta_index_1=3;
  139.                       break;
  140.                     default:
  141.                       passage_found=FALSE;
  142.                       break;
  143.                   }
  144.               else
  145.                 {
  146.                   if ((ULONG) KC_VIRTUALKEY & (ULONG) mp1)
  147.                     switch (SHORT2FROMMP(mp2))
  148.                       {
  149.                         case VK_UP:
  150.                           delta_index_1=1;
  151.                           break;
  152.                         case VK_LEFT:
  153.                           delta_index_1=2;
  154.                           break;
  155.                         case VK_RIGHT:
  156.                           delta_index_1=0;
  157.                           break;
  158.                         case VK_DOWN:
  159.                           delta_index_1=3;
  160.                           break;
  161.                           break;
  162.                         default:
  163.                           passage_found=FALSE;
  164.                           break;
  165.                       }
  166.                 }
  167.               if (passage_found)
  168.                 {
  169.                   switch (delta_y[delta_index_1][0])
  170.                     {
  171.                       case -1:
  172.                         x_next=x;
  173.                         next_ptr=current_ptr->predecessor_ptr;
  174.                         break;
  175.                       case 1:
  176.                         x_next=x;
  177.                         next_ptr=current_ptr->successor_ptr;
  178.                         break;
  179.                       default:
  180.                         x_next=x+delta_x[delta_index_1][0];
  181.                         next_ptr=current_ptr;
  182.                         break;
  183.                     }
  184.                   if (*((next_ptr->row_ptr)+x_next) == 'W')
  185.                     passage_found=FALSE;
  186.                   else
  187.                     if (next_ptr->predecessor_ptr == NULL)
  188.                       passage_found=FALSE;
  189.                     else
  190.                       {
  191.                         hPS=WinGetPS(hwnd);
  192.                         GpiMove(hPS,&position);
  193.                         if (*((next_ptr->row_ptr)+x_next) == 'S')
  194.                           {
  195.                             GpiSetColor(hPS,BADPATHCOLOR);
  196.                             *((current_ptr->row_ptr)+x)='A';
  197.                             *((next_ptr->row_ptr)+x_next)='A';
  198.                           }
  199.                         else
  200.                           {
  201.                             GpiSetColor(hPS,GOODPATHCOLOR);
  202.                             *((next_ptr->row_ptr)+x_next)='S';
  203.                           }
  204.                         switch (delta_y[delta_index_1][0])
  205.                           {
  206.                             case -1:
  207.                               next_ptr=next_ptr->predecessor_ptr;
  208.                               position.y-=twice_magnitude_delta_y;
  209.                               break;
  210.                             case 1:
  211.                               next_ptr=next_ptr->successor_ptr;
  212.                               if (next_ptr == NULL)
  213.                                 position.y+=magnitude_delta_y;
  214.                               else
  215.                                 position.y+=twice_magnitude_delta_y;
  216.                               break;
  217.                             default:
  218.                               x_next+=delta_x[delta_index_1][0];
  219.                               position.x+=(twice_magnitude_delta_x
  220.                                *delta_x[delta_index_1][0]);
  221.                               break;
  222.                           }
  223.                         GpiLine(hPS,&position);
  224.                         WinReleasePS(hPS);
  225.                         current_ptr=next_ptr;
  226.                         x=x_next;
  227.                         if (current_ptr == NULL)
  228.                           {
  229.                             solved=TRUE;
  230.                             frequency=10;
  231.                             for (delta_index_1=1; delta_index_1 <= 100;
  232.                              delta_index_1++)
  233.                               {
  234.                                 DosBeep(frequency,56);
  235.                                 frequency+=10;
  236.                               }
  237.                           }
  238.                         else
  239.                           *((current_ptr->row_ptr)+x)='S';
  240.                       }
  241.                 }
  242.               if ((! passage_found)
  243.               &&  (SHORT2FROMMP(mp2) != VK_NUMLOCK))
  244.                 DosBeep(120,333);
  245.             }
  246.           return((MRESULT) 1);
  247.           break;
  248.         case WM_COMMAND:
  249.           hwndMenu=WinWindowFromID(WinQueryWindow(hwnd,QW_PARENT,FALSE),
  250.            FID_MENU);
  251.           switch (COMMANDMSG(&msg)->cmd)
  252.             {
  253.               case IDM_CLEAR:
  254.                 if (! fatal_error)
  255.                   {
  256.                     clear_paths(&row_head,&num_columns);
  257.                     position.x=magnitude_delta_x;
  258.                     position.y=magnitude_delta_y;
  259.                     current_ptr=row_head->successor_ptr;
  260.                     x=1;
  261.                     solved=FALSE;
  262.                   }
  263.                 WinInvalidateRect(hwnd,NULL,FALSE);
  264.                 break;
  265.               case IDM_NEW:
  266.                 if ((max_x >= 20) && (max_y >= 20))
  267.                   {
  268.                     size_maze(&delta_x[0][0],&delta_y[0][0],&row_head,
  269.                      &row_tail,&magnitude_delta_x,&magnitude_delta_y,
  270.                      &max_x,&max_y,&num_columns,&num_rows,&r_n[0],
  271.                      &twice_magnitude_delta_x,&twice_magnitude_delta_y,
  272.                      &x_max,&y_max,&fatal_error);
  273.                     if (! fatal_error)
  274.                       {
  275.                         position.x=magnitude_delta_x;
  276.                         position.y=magnitude_delta_y;
  277.                         current_ptr=row_head->successor_ptr;
  278.                         x=1;
  279.                       }
  280.                   }
  281.                 solved=FALSE;
  282.                 WinInvalidateRect(hwnd,NULL,FALSE);
  283.                 break;
  284.               case IDM_SOLVE:
  285.                 if ((! fatal_error) && (max_x >= 20) && (max_y >= 20))
  286.                   {
  287.                     clear_paths(&row_head,&num_columns);
  288.                     optionally_have_computer_solve(&row_head,&row_tail,
  289.                      &delta_x[0][0],&delta_y[0][0],&num_columns,
  290.                      &fatal_error);
  291.                     solved=TRUE;
  292.                   }
  293.                 WinInvalidateRect(hwnd,NULL,FALSE);
  294.                 break;
  295.               case IDM_HELP:
  296.                 WinDlgBox(HWND_DESKTOP,hwnd,HelpProc,NULL,IDD_HELPBOX,
  297.                  NULL);
  298.                 break;
  299.               default:
  300.                 break;
  301.             }
  302.           break;
  303.         case WM_SIZE:
  304.           solved=FALSE;
  305.           max_x=SHORT1FROMMP(mp2)-1;
  306.           max_y=SHORT2FROMMP(mp2)-1;
  307.           if ((max_x >= 20) && (max_y >= 20))
  308.             {
  309.               size_maze(&delta_x[0][0],&delta_y[0][0],&row_head,
  310.                &row_tail,&magnitude_delta_x,&magnitude_delta_y,
  311.                &max_x,&max_y,&num_columns,&num_rows,&r_n[0],
  312.                &twice_magnitude_delta_x,&twice_magnitude_delta_y,
  313.                &x_max,&y_max,&fatal_error);
  314.               if (! fatal_error)
  315.                 {
  316.                   position.x=magnitude_delta_x;
  317.                   position.y=magnitude_delta_y;
  318.                   current_ptr=row_head->successor_ptr;
  319.                   x=1;
  320.                 }
  321.               solved=FALSE;
  322.             }
  323.           break;
  324.         case WM_ERASEBACKGROUND:
  325.           return(TRUE);
  326.           break;
  327.         case WM_PAINT:
  328.           hPS=WinBeginPaint(hwnd,(HPS) NULL,(PWRECT) NULL);
  329.           if ((max_x >= 20) && (max_y >= 20))
  330.             paint_maze(&row_head,&num_columns,&magnitude_delta_x,
  331.              &magnitude_delta_y,&twice_magnitude_delta_x,
  332.              &twice_magnitude_delta_y,&x_max,&y_max,hPS,&fatal_error);
  333.           WinEndPaint(hPS);
  334.           break;
  335.         case WM_DESTROY:
  336.           destroy_maze(&row_head,&row_tail);
  337.           break;
  338.         default:
  339.           return(WinDefWindowProc(hwnd,msg,mp1,mp2));
  340.           break;
  341.       }
  342.     return(0L);
  343.   }
  344.  
  345. MRESULT EXPENTRY HelpProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2)
  346.   {
  347.     switch (msg)
  348.       {
  349.         case WM_COMMAND:
  350.           switch (COMMANDMSG(&msg)->cmd)
  351.             {
  352.               case DID_OK:
  353.               case DID_CANCEL:
  354.                 WinDismissDlg(hwnd,TRUE);
  355.                 break;
  356.               default:
  357.                 break;
  358.             }
  359.           break;
  360.         default:
  361.           return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  362.       }
  363.     return(0);
  364.   }
  365.  
  366. static void create_maze(delta_x,delta_y,row_head,row_tail,fatal_error)
  367.   int         *delta_x;
  368.   int         *delta_y;
  369.   row_rec_ptr *row_head;
  370.   row_rec_ptr *row_tail;
  371.   int         *fatal_error;
  372.     {
  373.       int      delta_index_1a;
  374.       int      delta_index_1b;
  375.       int      delta_index_1c;
  376.       int      delta_index_1d;
  377.       int      delta_index_2;
  378.  
  379.       *fatal_error=FALSE;
  380.       *delta_x=1;
  381.       *(delta_y+24)=1;
  382.       *(delta_x+48)=-1;
  383.       *(delta_y+72)=-1;
  384.       *delta_y=0;
  385.       *(delta_x+24)=0;
  386.       *(delta_y+48)=0;
  387.       *(delta_x+72)=0;
  388.       delta_index_2=-1;
  389.       for (delta_index_1a=0; delta_index_1a < 4; delta_index_1a++)
  390.         for (delta_index_1b=0; delta_index_1b < 4; delta_index_1b++)
  391.           if (delta_index_1a != delta_index_1b)
  392.             for (delta_index_1c=0; delta_index_1c < 4;
  393.              delta_index_1c++)
  394.               if ((delta_index_1a != delta_index_1c)
  395.               &&  (delta_index_1b != delta_index_1c))
  396.                 for (delta_index_1d=0; delta_index_1d < 4;
  397.                  delta_index_1d++)
  398.                   if ((delta_index_1a != delta_index_1d)
  399.                   &&  (delta_index_1b != delta_index_1d)
  400.                   &&  (delta_index_1c != delta_index_1d))
  401.                     {
  402.                       delta_index_2=delta_index_2+1;
  403.                       *(delta_x+(24*delta_index_1a+delta_index_2))
  404.                        =*delta_x;
  405.                       *(delta_y+(24*delta_index_1a+delta_index_2))
  406.                        =*delta_y;
  407.                       *(delta_x+(24*delta_index_1b+delta_index_2))
  408.                        =*(delta_x+24);
  409.                       *(delta_y+(24*delta_index_1b+delta_index_2))
  410.                        =*(delta_y+24);
  411.                       *(delta_x+(24*delta_index_1c+delta_index_2))
  412.                        =*(delta_x+48);
  413.                       *(delta_y+(24*delta_index_1c+delta_index_2))
  414.                        =*(delta_y+48);
  415.                       *(delta_x+(24*delta_index_1d+delta_index_2))
  416.                        =*(delta_x+72);
  417.                       *(delta_y+(24*delta_index_1d+delta_index_2))
  418.                        =*(delta_y+72);
  419.                     }
  420.       *row_head=NULL;
  421.       *row_tail=NULL;
  422.       return;
  423.     }
  424.  
  425. static void size_maze(delta_x,delta_y,row_head,row_tail,
  426.  magnitude_delta_x,magnitude_delta_y,max_x,max_y,num_columns,num_rows,
  427.  r_n,twice_magnitude_delta_x,twice_magnitude_delta_y,x_max,y_max,
  428.  fatal_error)
  429.   int         *delta_x;
  430.   int         *delta_y;
  431.   row_rec_ptr *row_head;
  432.   row_rec_ptr *row_tail;
  433.   int         *magnitude_delta_x;
  434.   int         *magnitude_delta_y;
  435.   int         *max_x;
  436.   int         *max_y;
  437.   int         *num_columns;
  438.   int         *num_rows;
  439.   int         *r_n;
  440.   int         *twice_magnitude_delta_x;
  441.   int         *twice_magnitude_delta_y;
  442.   int         *x_max;
  443.   int         *y_max;
  444.   int         *fatal_error;
  445.     {
  446.       int             column_num;
  447.       char            *column_ptr;
  448.       row_rec_ptr     current_ptr;
  449.       int             finished;
  450.       int             delta_index_1;
  451.       int             delta_index_2;
  452.       int             digit;
  453.       int             digit_num;
  454.       row_rec_ptr     next_ptr;
  455.       row_rec_ptr     previous_ptr;
  456.       int             recurse;
  457.       int             r_n_index_1;
  458.       int             r_n_index_2;
  459.       int             row_num;
  460.       DATETIME        seed;
  461.       stack_2_rec_ptr stack_head;
  462.       stack_2_rec_ptr stack_ptr;
  463.       int             sum;
  464.       int             tem_int;
  465.       int             x;
  466.       int             x_next;
  467.       int             x_out;
  468.       int             y;
  469.       int             y_out;
  470.  
  471.       DosGetDateTime(&seed);
  472.       *r_n=seed.year%29;
  473.       *(r_n+1)=seed.month;
  474.       *(r_n+2)=seed.day%29;
  475.       *(r_n+3)=seed.hours;
  476.       *(r_n+4)=seed.minutes%29;
  477.       *(r_n+5)=seed.seconds%29;
  478.       *(r_n+6)=seed.hundredths%29;
  479.       *(r_n+7)=0;
  480.       *num_columns=(*max_x)/10;
  481.       *num_rows=(*max_y)/10;
  482.       *magnitude_delta_x=(*max_x)/(*num_columns)/2;
  483.       *twice_magnitude_delta_x
  484.        =(*magnitude_delta_x)+(*magnitude_delta_x);
  485.       *magnitude_delta_y=(*max_y)/(*num_rows)/2;
  486.       *twice_magnitude_delta_y
  487.        =(*magnitude_delta_y)+(*magnitude_delta_y);
  488.       *x_max=*twice_magnitude_delta_x*(*num_columns);
  489.       *y_max=*twice_magnitude_delta_y*(*num_rows);
  490.       while (*row_head != NULL)
  491.         {
  492.           free((*row_head)->row_ptr);
  493.           previous_ptr=*row_head;
  494.           *row_head=(*row_head)->successor_ptr;
  495.           free((char *) previous_ptr);
  496.         }
  497.       if ((*row_head=(struct row_rec *)
  498.        malloc((unsigned) sizeof(struct row_rec))) == NULL)
  499.         *fatal_error=TRUE;
  500.       else
  501.         {
  502.           (*row_head)->predecessor_ptr=NULL;
  503.           (*row_head)->successor_ptr=NULL;
  504.           *row_tail=*row_head;
  505.           if (((*row_head)->row_ptr=
  506.            malloc((unsigned) 2*(*num_columns)+1)) == NULL)
  507.             *fatal_error=TRUE;
  508.           else
  509.             {
  510.               column_ptr=(*row_head)->row_ptr;
  511.               for (column_num=0; column_num < 2*(*num_columns)+1;
  512.                column_num++)
  513.                 {
  514.                   *column_ptr='W';
  515.                   column_ptr++;
  516.                 }
  517.             }
  518.         }
  519.       row_num=1;
  520.       while ((row_num <= *num_rows) && (! *fatal_error))
  521.         {
  522.           if ((current_ptr=(struct row_rec *)
  523.            malloc((unsigned) sizeof(struct row_rec))) == NULL)
  524.             *fatal_error=TRUE;
  525.           else
  526.             {
  527.               (*row_tail)->successor_ptr=current_ptr;
  528.               current_ptr->predecessor_ptr=*row_tail;
  529.               current_ptr->successor_ptr=NULL;
  530.               *row_tail=current_ptr;
  531.               if ((current_ptr->row_ptr=
  532.                malloc((unsigned) 2*(*num_columns)+1)) == NULL)
  533.                 *fatal_error=TRUE;
  534.               else
  535.                 {
  536.                   column_ptr=current_ptr->row_ptr;
  537.                   for (column_num=0; column_num < 2*(*num_columns)+1;
  538.                    column_num++)
  539.                     {
  540.                       *column_ptr='W';
  541.                       column_ptr++;
  542.                     }
  543.                 }
  544.             }
  545.           if ((current_ptr=(struct row_rec *)
  546.            malloc((unsigned) sizeof(struct row_rec))) == NULL)
  547.             *fatal_error=TRUE;
  548.           else
  549.             {
  550.               (*row_tail)->successor_ptr=current_ptr;
  551.               current_ptr->predecessor_ptr=*row_tail;
  552.               current_ptr->successor_ptr=NULL;
  553.               *row_tail=current_ptr;
  554.               if ((current_ptr->row_ptr=
  555.                malloc((unsigned) 2*(*num_columns)+1)) == NULL)
  556.                 *fatal_error=TRUE;
  557.               else
  558.                 {
  559.                   column_ptr=current_ptr->row_ptr;
  560.                   for (column_num=0; column_num < 2*(*num_columns)+1;
  561.                    column_num++)
  562.                     {
  563.                       *column_ptr='W';
  564.                       column_ptr++;
  565.                     }
  566.                 }
  567.             }
  568.           row_num++;
  569.         }
  570.       sum=0;
  571.       for (digit_num=1; digit_num <= 3; digit_num++)
  572.         {
  573.           digit=*r_n;
  574.           r_n_index_1=0;
  575.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  576.             {
  577.               tem_int=*(r_n+r_n_index_2);
  578.               *(r_n+r_n_index_1)=tem_int;
  579.               r_n_index_1++;
  580.               digit+=tem_int;
  581.               if (digit >= 29)
  582.                 digit-=29;
  583.             }
  584.           *(r_n+7)=digit;
  585.           sum=29*sum+digit;
  586.         }
  587.       x=2*(sum%(*num_columns))+1;
  588.       sum=0;
  589.       for (digit_num=1; digit_num <= 3; digit_num++)
  590.         {
  591.           digit=*r_n;
  592.           r_n_index_1=0;
  593.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  594.             {
  595.               tem_int=*(r_n+r_n_index_2);
  596.               *(r_n+r_n_index_1)=tem_int;
  597.               r_n_index_1++;
  598.               digit+=tem_int;
  599.               if (digit >= 29)
  600.                 digit-=29;
  601.             }
  602.           *(r_n+7)=digit;
  603.           sum=29*sum+digit;
  604.         }
  605.       y=2*(sum%(*num_rows))+1;
  606.       current_ptr=*row_head;
  607.       for (y_out=0; y_out < y; y_out++)
  608.         current_ptr=current_ptr->successor_ptr;
  609.       finished=FALSE;
  610.       recurse=TRUE;
  611.       stack_head=NULL;
  612.       while ((! finished) && (! *fatal_error))
  613.         {
  614.           if (recurse)
  615.             {
  616.               *((current_ptr->row_ptr)+x)=' ';
  617.               delta_index_1=0;
  618.               do
  619.                 {
  620.                   delta_index_2=*r_n;
  621.                   r_n_index_1=0;
  622.                   for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  623.                     {
  624.                       tem_int=*(r_n+r_n_index_2);
  625.                       *(r_n+r_n_index_1)=tem_int;
  626.                       r_n_index_1++;
  627.                       delta_index_2+=tem_int;
  628.                       if (delta_index_2 >= 29)
  629.                         delta_index_2-=29;
  630.                     }
  631.                   *(r_n+7)=delta_index_2;
  632.                 }
  633.               while (delta_index_2 >= 24);
  634.               recurse=FALSE;
  635.             }
  636.             while ((delta_index_1 < 4)
  637.             &&     (! recurse)
  638.             &&     (! *fatal_error))
  639.               {
  640.                 x_next=x+2*(*(delta_x+(24*delta_index_1+delta_index_2)));
  641.                 if ((x_next <= 0) || (x_next >= 2*(*num_columns)))
  642.                   delta_index_1++;
  643.                 else
  644.                   {
  645.                     switch (*(delta_y+(24*delta_index_1+delta_index_2)))
  646.                       {
  647.                         case -1:
  648.                           next_ptr=(current_ptr->predecessor_ptr)->
  649.                            predecessor_ptr;
  650.                           break;
  651.                         case 1:
  652.                           next_ptr=(current_ptr->successor_ptr)->
  653.                            successor_ptr;
  654.                           break;
  655.                         default:
  656.                           next_ptr=current_ptr;
  657.                           break;
  658.                       }
  659.                     if (next_ptr == NULL)
  660.                       delta_index_1++;
  661.                     else
  662.                       {
  663.                         if (*((next_ptr->row_ptr)+x_next) == 'W')
  664.                           {
  665.                             if (x == x_next)
  666.                               if ((*(delta_y
  667.                                +(24*delta_index_1+delta_index_2)))
  668.                                == 1)
  669.                                 *(((current_ptr->successor_ptr)
  670.                                  ->row_ptr)+x)=' ';
  671.                               else
  672.                                 *(((current_ptr->predecessor_ptr)
  673.                                  ->row_ptr)+x)=' ';
  674.                             else
  675.                               {
  676.                                 x_out=(x+x_next)/2;
  677.                                 *((current_ptr->row_ptr)+x_out)=' ';
  678.                               }
  679.                             x=x_next;
  680.                             current_ptr=next_ptr;
  681.                             if ((stack_ptr=
  682.                              (struct stack_2_rec *) malloc(
  683.                              (unsigned) sizeof(struct stack_2_rec)))
  684.                              == NULL)
  685.                               *fatal_error=TRUE;
  686.                             else
  687.                               {
  688.                                 stack_ptr->next_ptr=stack_head;
  689.                                 stack_head=stack_ptr;
  690.                                 stack_head->index_1
  691.                                  =(unsigned char) delta_index_1;
  692.                                 stack_head->index_2
  693.                                  =(unsigned char) delta_index_2;
  694.                                 recurse=TRUE;
  695.                               }
  696.                           }
  697.                         else
  698.                           delta_index_1++;
  699.                       }
  700.                   }
  701.               }
  702.             if ((! recurse) && (! *fatal_error))
  703.               {
  704.                 delta_index_1=(int) stack_head->index_1;
  705.                 delta_index_2=(int) stack_head->index_2;
  706.                 stack_ptr=stack_head;
  707.                 stack_head=stack_head->next_ptr;
  708.                 free((char *) stack_ptr);
  709.                 if (stack_head == NULL)
  710.                   finished=TRUE;
  711.                 else
  712.                   switch (*(delta_y+(24*delta_index_1+delta_index_2)))
  713.                     {
  714.                       case -1:
  715.                         current_ptr=(current_ptr->successor_ptr)->
  716.                          successor_ptr;
  717.                         break;
  718.                       case 1:
  719.                         current_ptr=(current_ptr->predecessor_ptr)->
  720.                          predecessor_ptr;
  721.                         break;
  722.                       default:
  723.                         x-=
  724.                      (2*(*(delta_x+(24*delta_index_1+delta_index_2))));
  725.                         break;
  726.                     }
  727.               }
  728.         }
  729.       if (! *fatal_error)
  730.         {
  731.           *(((*row_head)->row_ptr)+1)='S';
  732.           *((((*row_head)->successor_ptr)->row_ptr)+1)='S';
  733.           *(((*row_tail)->row_ptr)+(2*(*num_columns)-1))=' ';
  734.         }
  735.       return;
  736.     }
  737.  
  738. static void paint_maze(row_head,num_columns,magnitude_delta_x,
  739.  magnitude_delta_y,twice_magnitude_delta_x,twice_magnitude_delta_y,
  740.  x_max,y_max,hPS,fatal_error)
  741.   row_rec_ptr *row_head;
  742.   int         *num_columns;
  743.   int         *magnitude_delta_x;
  744.   int         *magnitude_delta_y;
  745.   int         *twice_magnitude_delta_x;
  746.   int         *twice_magnitude_delta_y;
  747.   int         *x_max;
  748.   int         *y_max;
  749.   HPS         hPS;
  750.   int         *fatal_error;
  751.     {
  752.       int           column_num;
  753.       row_rec_ptr   current_ptr;
  754.       POINTL        ending_position;
  755.       int           even;
  756.       POINTL        path_position;
  757.       char          *pixel_ptr;
  758.       POINTL        starting_position;
  759.  
  760.       if (* fatal_error)
  761.         {
  762.           GpiSetColor(hPS,BADPATHCOLOR);
  763.           starting_position.x=0;
  764.           starting_position.y=0;
  765.           ending_position.x=*x_max;
  766.           ending_position.y=*y_max;
  767.           GpiMove(hPS,&starting_position);
  768.           GpiBox(hPS,DRO_FILL,&ending_position,(long) 0,(long) 0);
  769.           DosBeep(60,333);
  770.         }
  771.       else
  772.         {
  773.           GpiSetColor(hPS,FLOORCOLOR);
  774.           starting_position.x=0;
  775.           starting_position.y=0;
  776.           ending_position.x=*x_max;
  777.           ending_position.y=*y_max;
  778.           GpiMove(hPS,&starting_position);
  779.           GpiBox(hPS,DRO_FILL,&ending_position,(long) 0,(long) 0);
  780.           current_ptr=*row_head;
  781.           even=TRUE;
  782.           starting_position.y=0;
  783.           while (current_ptr != NULL)
  784.             {
  785.               if (even)
  786.                 {
  787.                   pixel_ptr=(current_ptr->row_ptr)+1;
  788.                   starting_position.x=0;
  789.                   ending_position.y=starting_position.y;
  790.                   for (column_num=1; column_num <= *num_columns;
  791.                    column_num++)
  792.                     {
  793.                       ending_position.x=starting_position.x
  794.                        +(*twice_magnitude_delta_x);
  795.                       switch (*pixel_ptr)
  796.                         {
  797.                           case 'A':
  798.                             GpiSetColor(hPS,BADPATHCOLOR);
  799.                             path_position.x=starting_position.x
  800.                              +(*magnitude_delta_x);
  801.                             if (starting_position.y == 0)
  802.                               path_position.y=0;
  803.                             else
  804.                               path_position.y=starting_position.y
  805.                                -(*magnitude_delta_y);
  806.                             GpiMove(hPS,&path_position);
  807.                             if (current_ptr->successor_ptr == NULL)
  808.                               path_position.y=starting_position.y;
  809.                             else
  810.                               path_position.y=starting_position.y
  811.                                +(*magnitude_delta_y);
  812.                             GpiLine(hPS,&path_position);
  813.                             break;
  814.                           case 'S':
  815.                             GpiSetColor(hPS,GOODPATHCOLOR);
  816.                             path_position.x=starting_position.x
  817.                              +(*magnitude_delta_x);
  818.                             if (starting_position.y == 0)
  819.                               path_position.y=0;
  820.                             else
  821.                               path_position.y=starting_position.y
  822.                                -(*magnitude_delta_y);
  823.                             GpiMove(hPS,&path_position);
  824.                             if (current_ptr->successor_ptr == NULL)
  825.                               path_position.y=starting_position.y;
  826.                             else
  827.                               path_position.y=starting_position.y
  828.                                +(*magnitude_delta_y);
  829.                             GpiLine(hPS,&path_position);
  830.                             break;
  831.                           case 'W':
  832.                             GpiSetColor(hPS,WALLCOLOR);
  833.                             GpiMove(hPS,&starting_position);
  834.                             GpiLine(hPS,&ending_position);
  835.                             break;
  836.                           default:
  837.                             break;
  838.                         }
  839.                       starting_position.x=ending_position.x;
  840.                       pixel_ptr+=2;
  841.                     }
  842.                 }
  843.               else
  844.                 {
  845.                   pixel_ptr=(current_ptr->row_ptr);
  846.                   starting_position.x=0;
  847.                   ending_position.y=starting_position.y
  848.                    +(*twice_magnitude_delta_y);
  849.                   for (column_num=1; column_num <= *num_columns;
  850.                    column_num++)
  851.                     {
  852.                       ending_position.x=starting_position.x;
  853.                       switch (*pixel_ptr)
  854.                         {
  855.                           case 'A':
  856.                             GpiSetColor(hPS,BADPATHCOLOR);
  857.                             path_position.x=starting_position.x
  858.                              -(*magnitude_delta_x);
  859.                             path_position.y=starting_position.y
  860.                              +(*magnitude_delta_y);
  861.                             GpiMove(hPS,&path_position);
  862.                             path_position.x=starting_position.x
  863.                              +(*magnitude_delta_x);
  864.                             GpiLine(hPS,&path_position);
  865.                             break;
  866.                           case 'S':
  867.                             GpiSetColor(hPS,GOODPATHCOLOR);
  868.                             path_position.x=starting_position.x
  869.                              -(*magnitude_delta_x);
  870.                             path_position.y=starting_position.y
  871.                              +(*magnitude_delta_y);
  872.                             GpiMove(hPS,&path_position);
  873.                             path_position.x=starting_position.x
  874.                              +(*magnitude_delta_x);
  875.                             GpiLine(hPS,&path_position);
  876.                             break;
  877.                           case 'W':
  878.                             GpiSetColor(hPS,WALLCOLOR);
  879.                             GpiMove(hPS,&starting_position);
  880.                             GpiLine(hPS,&ending_position);
  881.                             break;
  882.                           default:
  883.                             break;
  884.                         }
  885.                       starting_position.x+=(*twice_magnitude_delta_x);
  886.                       pixel_ptr+=2;
  887.                     }
  888.                   ending_position.x=starting_position.x;
  889.                   GpiSetColor(hPS,WALLCOLOR);
  890.                   GpiMove(hPS,&starting_position);
  891.                   GpiLine(hPS,&ending_position);
  892.                   starting_position.y=ending_position.y;
  893.                 }
  894.               even=! even;
  895.               current_ptr=current_ptr->successor_ptr;
  896.             }
  897.           DosBeep(1000,333);
  898.         }
  899.       return;
  900.     }
  901.  
  902. static void destroy_maze(row_head,row_tail)
  903.   row_rec_ptr *row_head;
  904.   row_rec_ptr *row_tail;
  905.     {
  906.       row_rec_ptr previous_ptr;
  907.  
  908.       while (*row_head != NULL)
  909.         {
  910.           free((*row_head)->row_ptr);
  911.           previous_ptr=*row_head;
  912.           *row_head=(*row_head)->successor_ptr;
  913.           free((char *) previous_ptr);
  914.         }
  915.       *row_tail=NULL;
  916.       return;
  917.     }
  918.  
  919. static void clear_paths(row_head,num_columns)
  920.   row_rec_ptr *row_head;
  921.   int         *num_columns;
  922.     {
  923.       row_rec_ptr current_ptr;
  924.       int         x;
  925.  
  926.       current_ptr=*row_head;
  927.       while (current_ptr != NULL)
  928.         {
  929.           for (x=1; x < 2*(*num_columns); x++)
  930.             if (*((current_ptr->row_ptr)+x) != 'W')
  931.               *((current_ptr->row_ptr)+x)=' ';
  932.           current_ptr=current_ptr->successor_ptr;
  933.         }
  934.       *(((*row_head)->row_ptr)+1)='S';
  935.       *((((*row_head)->successor_ptr)->row_ptr)+1)='S';
  936.       return;
  937.     }
  938.  
  939. static void optionally_have_computer_solve(row_head,row_tail,delta_x,
  940.  delta_y,num_columns,fatal_error)
  941.   row_rec_ptr *row_head;
  942.   row_rec_ptr *row_tail;
  943.   int         *delta_x;
  944.   int         *delta_y;
  945.   int         *num_columns;
  946.   int         *fatal_error;
  947.     {
  948.       row_rec_ptr     current_ptr;
  949.       int             finished;
  950.       unsigned char   delta_index_1;
  951.       row_rec_ptr     next_ptr;
  952.       int             recurse;
  953.       stack_1_rec_ptr stack_head;
  954.       stack_1_rec_ptr stack_ptr;
  955.       int             x;
  956.       int             x_next;
  957.  
  958.       x=1;
  959.       current_ptr=(*row_head)->successor_ptr;
  960.       next_ptr=current_ptr->successor_ptr;
  961.       finished=FALSE;
  962.       recurse=TRUE;
  963.       stack_head=NULL;
  964.       while ((! finished) && (! *fatal_error))
  965.         {
  966.           if (recurse)
  967.             {
  968.               delta_index_1=0;
  969.               recurse=FALSE;
  970.             };
  971.           while ((delta_index_1 < 4)
  972.           &&     (! finished)
  973.           &&     (! recurse)
  974.           &&     (! *fatal_error))
  975.             {
  976.               switch (*(delta_y+(24*delta_index_1)))
  977.                 {
  978.                   case -1:
  979.                     x_next=x;
  980.                     next_ptr=current_ptr->predecessor_ptr;
  981.                     break;
  982.                   case 1:
  983.                     x_next=x;
  984.                     next_ptr=current_ptr->successor_ptr;
  985.                     break;
  986.                   default:
  987.                     next_ptr=current_ptr;
  988.                     x_next=x+(*(delta_x+(24*delta_index_1)));
  989.                     break;
  990.                 }
  991.               if (*((next_ptr->row_ptr)+x_next) == ' ')
  992.                 {
  993.                   *((next_ptr->row_ptr)+x_next)='S';
  994.                   switch (*(delta_y+(24*delta_index_1)))
  995.                     {
  996.                       case -1:
  997.                         next_ptr=next_ptr->predecessor_ptr;
  998.                         break;
  999.                       case 1:
  1000.                         next_ptr=next_ptr->successor_ptr;
  1001.                         break;
  1002.                       default:
  1003.                         x_next+=(*(delta_x+(24*delta_index_1)));
  1004.                         break;
  1005.                     }
  1006.                   if (next_ptr != NULL)
  1007.                     {
  1008.                       *((next_ptr->row_ptr)+x_next)='S';
  1009.                       x=x_next;
  1010.                       current_ptr=next_ptr;
  1011.                       if ((stack_ptr=(struct stack_1_rec *) malloc(
  1012.                        (unsigned) sizeof(struct stack_1_rec)))
  1013.                        == NULL)
  1014.                         *fatal_error=TRUE;
  1015.                       else
  1016.                         {
  1017.                           stack_ptr->next_ptr=stack_head;
  1018.                           stack_head=stack_ptr;
  1019.                           stack_head->index_1
  1020.                            =(unsigned char) delta_index_1;
  1021.                           recurse=TRUE;
  1022.                         }
  1023.                     }
  1024.                   else
  1025.                     finished=TRUE;
  1026.                 }
  1027.               else
  1028.                 delta_index_1++;
  1029.             };
  1030.           if ((delta_index_1 >= 4) && (! *fatal_error))
  1031.             {
  1032.               *((current_ptr->row_ptr)+x)=' ';
  1033.               x_next=x;
  1034.               next_ptr=current_ptr;
  1035.               delta_index_1=stack_head->index_1;
  1036.               stack_ptr=stack_head;
  1037.               stack_head=stack_head->next_ptr;
  1038.               free((char *) stack_ptr);
  1039.               switch (*(delta_y+(24*delta_index_1)))
  1040.                 {
  1041.                   case -1:
  1042.                     current_ptr=current_ptr->successor_ptr;
  1043.                     *((current_ptr->row_ptr)+x)=' ';
  1044.                     current_ptr=current_ptr->successor_ptr;
  1045.                     break;
  1046.                   case 1:
  1047.                     current_ptr=current_ptr->predecessor_ptr;
  1048.                     *((current_ptr->row_ptr)+x)=' ';
  1049.                     current_ptr=current_ptr->predecessor_ptr;
  1050.                     break;
  1051.                   default:
  1052.                     x-=(*(delta_x+(24*delta_index_1)));
  1053.                     *((current_ptr->row_ptr)+x)=' ';
  1054.                     x-=(*(delta_x+(24*delta_index_1)));
  1055.                     break;
  1056.                 }
  1057.               delta_index_1++;
  1058.             }
  1059.         };
  1060.       if (! *fatal_error)
  1061.        *(((*row_tail)->row_ptr)+(2*(*num_columns)-1))='S';
  1062.       while (stack_head != NULL)
  1063.         {
  1064.           stack_ptr=stack_head;
  1065.           stack_head=stack_head->next_ptr;
  1066.           free((char *) stack_ptr);
  1067.         }
  1068.       return;
  1069.     }
  1070.