home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / GRAPHICS / ssaver.lzh / SRC / saver_maze.c < prev    next >
C/C++ Source or Header  |  1995-10-31  |  18KB  |  719 lines

  1. /* saver_maze.c                                   */
  2.  
  3. #include <stdio.h>
  4. #include <modes.h>
  5. #include <types.h>
  6.  
  7. #include "saver.h"
  8.  
  9. int orgwin, win, twin;
  10.  
  11. int gotosleep = FALSE;
  12. int sigcode = 0;            /* storage to keep received signal(s) */
  13.  
  14. int sighandler();            /* this will use a signal handler function */
  15. extern int errno;
  16.  
  17. void create_maze();
  18. void solve_maze();
  19.  
  20.  
  21. main()
  22. {
  23.     int evID;                    /* event ID */
  24.  
  25.     sigmask(1);                    /* mask signals */
  26.  
  27.     intercept(sighandler);        /* install signal handler */
  28.  
  29.     if ((evID = _ev_link(EV_NAME)) == -1)
  30.         exit(1);
  31.  
  32.     DWSet(STDOUT, 3, 0, 0, 40, 26, 0, 0, 0);
  33.  
  34.     if (_gs_currscr(STDOUT,&orgwin) == -1)
  35.         exit(0);
  36.  
  37.     CurOff(STDOUT);
  38.     BColor(STDOUT, 0);
  39.     _gs_wdev(STDOUT, &win);            /* get our window device number */
  40.     _ss_select(STDOUT, win);            /* now select it! */
  41.  
  42.     /* init your screen here */
  43.     init_saver();
  44.  
  45.     sigmask(0);                    /* unmask signals */
  46.     _ev_set(evID, 0, 0x8000);    /* wake up everybody */
  47.  
  48.     /* we unlink from the event since we are through with it */
  49.     _ev_unlink(evID);
  50.  
  51.     while(!sigcode)
  52.     {
  53.         /* replace the sleep(0); call with your busy function.
  54.          *
  55.          * Make it return if sigcode is non-zero.
  56.          * Also let it sleep a few ticks after every iteration.
  57.          */
  58.         if (gotosleep)
  59.             sleep(0);
  60.         else
  61.             do_maze();
  62.     }
  63.     Reset( STDOUT );
  64. }
  65.  
  66. sighandler(signal)
  67. int signal;
  68. {
  69.     switch (signal)    {
  70.     case SLEEP_SIG:
  71.         gotosleep = TRUE;
  72.         break;
  73.     case WAKE_SIG:
  74.         gotosleep = FALSE;
  75.         break;
  76.     case QUIT_SIG:
  77.     default:
  78.         gotosleep = FALSE;
  79.         sigcode = signal;
  80.         if (_gs_currscr(STDOUT,&twin) == -1)
  81.             exit(0);
  82.         if (twin == win) {
  83.             _ss_select(STDOUT, orgwin);
  84.         }
  85.     }
  86. }
  87.  
  88. #if 0
  89. static int rndval=10000;
  90.  
  91. /* rrand( val ) : return a pseudo-random value between 1 and val.
  92. **               IF val is -1, it is used as a seed.
  93. **               IF val is negative the better the seed.
  94. */
  95. rrand( val )
  96. int val;
  97. {
  98.     int bit0, bit1, bit14, num, i;
  99.  
  100.     /* see if -1 */
  101.     if ( val < 0 ) {
  102.         rndval = -val;
  103.     }
  104.  
  105.     for ( i = 0; i < 10; i++ )
  106.     {
  107.         bit0 = rndval & 1;
  108.         bit1 = (rndval & 2) >> 1;
  109.         bit14 = bit0 ^ bit1;
  110.         rndval >>=1;
  111.         rndval |= (bit14 << 14);
  112.     }
  113.     num = rndval % val;
  114.     return( num ? num : val );
  115. }
  116. #endif
  117. /*                             MAZE.C                             */
  118. /*                                                                */
  119. /* Generates a randomom binary tree maze,  draws it and solves it */
  120. /* graphically. The Solution employs a simple depth first search  */
  121. /* algorithm.                                                     */
  122. /*                                                                */
  123. /* This program was adapted for the HP workstation from one       */
  124. /* provided with the Sun 3 software release version ???.          */
  125. /*                                                                */
  126. /* Converted to OS-9 and the Color Computer 3 by Brian C. White   */
  127. /* (Requires the truely wonderful Kreider C library)              */
  128. /*                                                                */
  129. /* Converted to MM/1 on 09/20/90 Mike Haaland CIS UID# 72300,1433 */
  130. /* (Requires the Haaland CGFX library) <blush>                    */
  131.  
  132. /* This makes the sleep the same length on all OSK machines       */
  133. #define _tsleep(x)       tsleep(0x80000000 + (x))
  134.  
  135. #define BACKPAL         00     /* Background color (black)           */
  136. #define WRNGPAL         02     /* Wrong path color (dark grey)       */
  137. #define PATHPAL         10     /* Correct path color (white)         */
  138. #define MAZEPAL         15     /* Maze wall color (white)            */
  139. #define ENDPAUSE        720    /* Ticks to wait between mazes (4*60) */
  140.  
  141. #define XSQ_SIZE        16
  142. #define YSQ_SIZE        8
  143. #define XPATH_SIZE       8
  144. #define YPATH_SIZE      4
  145. #define XDIFF            8
  146. #define YDIFF            4
  147. #define XOFFSET            4
  148. #define YOFFSET            2
  149. #define XINCR_OFFSET    2
  150. #define YINCR_OFFSET    1
  151. #define X_MAZE_SIZE        39
  152. #define Y_MAZE_SIZE        24
  153.  
  154. #define MAZE_X_LESS_1   (X_MAZE_SIZE - 1)
  155. #define MAZE_Y_LESS_1   (Y_MAZE_SIZE - 1)
  156. #define MOVE_LIST_SIZE  (X_MAZE_SIZE * Y_MAZE_SIZE)
  157.  
  158. #define TOP             (unsigned)0x8880
  159. #define RIGHT           (unsigned)0x4440
  160. #define BOTTOM          (unsigned)0x2220
  161. #define LEFT            (unsigned)0x1110
  162.  
  163. #define WALL_TOP        (unsigned)0x8000
  164. #define WALL_RIGHT      (unsigned)0x4000
  165. #define WALL_BOTTOM     (unsigned)0x2000
  166. #define WALL_LEFT       (unsigned)0x1000
  167.  
  168. #define TOP_IN_DOOR     (unsigned)0x800
  169. #define RIGHT_IN_DOOR   (unsigned)0x400
  170. #define BOT_IN_DOOR     (unsigned)0x200
  171. #define LEFT_IN_DOOR    (unsigned)0x100
  172. #define ANY_IN_DOOR     (unsigned)0xF00
  173.  
  174. #define TOP_OUT_DOOR    (unsigned)0x80
  175. #define RIGHT_OUT_DOOR  (unsigned)0x40
  176. #define BOT_OUT_DOOR    (unsigned)0x20
  177. #define LEFT_OUT_DOOR   (unsigned)0x10
  178.  
  179. #define START_SQUARE    (unsigned)0x2
  180. #define END_SQUARE      (unsigned)0x1
  181.  
  182. #define MAZEGROUND       255    /* 0 */
  183. int PATHGROUND   =       3;     /* 1 */
  184. int WRNGGROUND   =       8;     /* 2 */
  185. #define BACKGROUND       0      /* 3 */
  186.  
  187. #ifndef STDIN
  188. #define STDIN           0
  189. #define STDOUT          1
  190. #define STDERR            2
  191. #endif
  192.  
  193. /*
  194. #include <stdio.h>
  195. */
  196. #include <sgstat.h>
  197.  
  198. #define ON  1
  199. #define OFF 0
  200.  
  201. static struct sgbuf wbuforig, wbuf;
  202.  
  203. static unsigned short maze[X_MAZE_SIZE][Y_MAZE_SIZE];
  204. static struct {
  205.     unsigned char x;
  206.     unsigned char y;
  207.     unsigned char dir;
  208. } move_list[MOVE_LIST_SIZE], save_path[MOVE_LIST_SIZE], path[MOVE_LIST_SIZE];
  209.  
  210. static unsigned int sqnum, cur_sq_x, cur_sq_y, path_length;
  211. static unsigned int start_x, start_y, start_dir, end_x, end_y, end_dir;
  212. static unsigned int outpath, xoffset_count, yoffset_count;
  213.  
  214. init_saver()
  215. {
  216.     xoffset_count = 4;
  217.     yoffset_count = 0;
  218.     outpath = STDOUT;
  219.     
  220.     CurOff  ( outpath );
  221.  
  222.     pausesw ( outpath, OFF );
  223.  
  224.     BColor  ( outpath, BACKGROUND );
  225.     FColor  ( outpath, MAZEGROUND );
  226. }
  227.  
  228. do_maze()
  229. {
  230.     srand(time(0));
  231.     getcolorset();
  232.     Clear ( outpath );
  233.     FColor ( outpath, MAZEGROUND );
  234.     initialize_maze();
  235.     if (! sigcode)
  236.         create_maze();
  237.     if (! sigcode)
  238.         solve_maze();
  239.     if (! sigcode)
  240.         _tsleep ( ENDPAUSE );
  241.     xoffset_count = ( xoffset_count + XINCR_OFFSET ) % XSQ_SIZE ;
  242.     yoffset_count = ( yoffset_count + YINCR_OFFSET ) % YSQ_SIZE ;
  243.     xoffset_count = (xoffset_count) ? xoffset_count : 4;
  244.  
  245. } /*  end of maze() */
  246.  
  247. /* draw the surrounding wall and start/end squares */
  248.  
  249. initialize_maze()
  250. {
  251.     register unsigned int i;
  252.     unsigned int j, wall;
  253.     unsigned int tempx, tempy;
  254.  
  255.     /* initialize all squares */
  256.     FColor ( outpath, MAZEGROUND );
  257.     for ( i=0; i<X_MAZE_SIZE; i++)
  258.     {
  259.         for ( j=0; j<Y_MAZE_SIZE; j++)
  260.         {
  261.             maze[i][j] = 0;
  262.         }
  263.     }
  264.  
  265.     /* top wall */
  266.     for ( i=0; i<X_MAZE_SIZE; i++ )
  267.     {
  268.         maze[i][0] = maze[i][0] | WALL_TOP;
  269.     }
  270.  
  271.     /* right wall */
  272.     for ( j=0; j<Y_MAZE_SIZE; j++ )
  273.     {
  274.         maze[MAZE_X_LESS_1][j] = maze[MAZE_X_LESS_1][j] | WALL_RIGHT;
  275.     }
  276.  
  277.     /* bottom wall */
  278.     for ( i=0; i<X_MAZE_SIZE; i++ )
  279.     {
  280.         maze[i][MAZE_Y_LESS_1] = maze[i][MAZE_Y_LESS_1] | WALL_BOTTOM;
  281.     }
  282.  
  283.     /* left wall */
  284.     for ( j=0; j<Y_MAZE_SIZE; j++ )
  285.     {
  286.         maze[0][j] = maze[0][j] | WALL_LEFT;
  287.     }
  288.  
  289.     /* set start square */
  290.     wall = random(4);
  291.  
  292.     switch (wall) {
  293.     case 0:
  294.         i = random(X_MAZE_SIZE);
  295.         j = 0;
  296.         break;
  297.     case 1:
  298.         i = MAZE_X_LESS_1;
  299.         j = random(Y_MAZE_SIZE);
  300.         break;
  301.     case 2:
  302.         i = random(X_MAZE_SIZE);
  303.         j = MAZE_Y_LESS_1;
  304.         break;
  305.     case 3:
  306.         i = 0;
  307.         j = random(Y_MAZE_SIZE);
  308.         break;
  309.     }
  310.     maze[i][j] = maze[i][j] | START_SQUARE;
  311.     maze[i][j] = maze[i][j] | ( TOP_IN_DOOR >> wall );
  312.     maze[i][j] = maze[i][j] & ~( WALL_TOP >> wall );
  313.     cur_sq_x = i;
  314.     cur_sq_y = j;
  315.     start_x = i;
  316.     start_y = j;
  317.     start_dir = wall;
  318.     sqnum = 0;
  319.  
  320.     /* set end square */
  321.     wall = (wall + 2)%4;
  322.  
  323.     switch (wall) {
  324.     case 0:
  325.         i = random(X_MAZE_SIZE);
  326.         j = 0;
  327.         break;
  328.     case 1:
  329.         i = MAZE_X_LESS_1;
  330.         j = random(Y_MAZE_SIZE);
  331.         break;
  332.     case 2:
  333.         i = random(X_MAZE_SIZE);
  334.         j = MAZE_Y_LESS_1;
  335.         break;
  336.     case 3:
  337.         i = 0;
  338.         j = random(Y_MAZE_SIZE);
  339.         break;
  340.     }
  341.     maze[i][j] = maze[i][j] | END_SQUARE;
  342.     maze[i][j] = maze[i][j] | ( TOP_OUT_DOOR >> wall );
  343.     maze[i][j] = maze[i][j] & ~( WALL_TOP >> wall );
  344.     end_x = i;
  345.     end_y = j;
  346.     end_dir = wall;
  347.  
  348.     /* draw the border */
  349.     for ( i=0; i<X_MAZE_SIZE && !sigcode ; i++)
  350.     {
  351.         if ( maze[i][0] & WALL_TOP )
  352.         {
  353.             tempx = xoffset_count + XSQ_SIZE * i;
  354.             tempy = yoffset_count;
  355.             XDrawLine ( tempx, tempy, tempx + XSQ_SIZE, tempy );
  356.         }
  357.         if ((maze[i][MAZE_Y_LESS_1] & WALL_BOTTOM))
  358.         {
  359.             tempx = xoffset_count + XSQ_SIZE * i;
  360.             tempy = yoffset_count + Y_MAZE_SIZE * YSQ_SIZE;
  361.             XDrawLine ( tempx, tempy, tempx + XSQ_SIZE, tempy );
  362.         }
  363.     }
  364.     for ( j=0; j<Y_MAZE_SIZE && !sigcode; j++)
  365.     {
  366.         if ( maze[MAZE_X_LESS_1][j] & WALL_RIGHT )
  367.         {
  368.             tempx = xoffset_count + X_MAZE_SIZE * XSQ_SIZE;
  369.             tempy = yoffset_count + YSQ_SIZE * j;
  370.             XDrawLine ( tempx, tempy, tempx, tempy + YSQ_SIZE );
  371.         }
  372.         if ( maze[0][j] & WALL_LEFT )
  373.         {
  374.             tempx = xoffset_count;
  375.             tempy = yoffset_count + YSQ_SIZE * j;
  376.             XDrawLine ( tempx, tempy, tempx, tempy + YSQ_SIZE );
  377.         }
  378.     }
  379.     circle_draw_solid ( start_x, start_y, start_dir );
  380.     square_draw_solid ( end_x, end_y, end_dir );
  381. } /* end of initialize_maze() */
  382.  
  383. /* create a maze layout given the intiialized maze */
  384.  
  385. void
  386. create_maze()
  387. {
  388.     register unsigned int i;
  389.     unsigned int newdoor;
  390.  
  391.     if (gotosleep)
  392.         sleep(0);
  393.     FColor ( outpath, MAZEGROUND );
  394.     do {
  395.         move_list[sqnum].x = cur_sq_x;
  396.         move_list[sqnum].y = cur_sq_y;
  397.         move_list[sqnum].dir = newdoor;
  398.  
  399.         /* pick a door */
  400.         while ( ( newdoor = choose_door() ) == -1 )
  401.         {
  402.             /* no more doors ... backup */
  403.             if ( backup() == -1 )
  404.             {
  405.                 /* done ... return */
  406.                 return;
  407.             }
  408.         }
  409.  
  410.         /* mark the out door */
  411.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | ( TOP_OUT_DOOR >> newdoor );
  412.         switch (newdoor) {
  413.         case 0: 
  414.             cur_sq_y--;
  415.             break;
  416.         case 1: 
  417.             cur_sq_x++;
  418.             break;
  419.         case 2: 
  420.             cur_sq_y++;
  421.             break;
  422.         case 3: 
  423.             cur_sq_x--;
  424.             break;
  425.         }
  426.         sqnum++;
  427.  
  428.         /* mark the in door */
  429.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | ( TOP_IN_DOOR >> ((newdoor+2)%4) );
  430.         /* if end square set path length and save path */
  431.         if ( maze[cur_sq_x][cur_sq_y] & END_SQUARE )
  432.         {
  433.             path_length = sqnum;
  434.             for ( i=0; i<path_length; i++)
  435.             {
  436.                 save_path[i].x = move_list[i].x;
  437.                 save_path[i].y = move_list[i].y;
  438.                 save_path[i].dir = move_list[i].dir;
  439.             }
  440.         }
  441.     } while ( ! sigcode);
  442. } /* end of create_maze() */
  443.  
  444. /* pick a new path */
  445.  
  446. choose_door()
  447. {
  448.     unsigned int candidates[3];
  449.     register unsigned int num_candidates;
  450.     num_candidates = 0;
  451.  
  452. topwall:
  453.     /* top wall */
  454.     if ( maze[cur_sq_x][cur_sq_y] & TOP )
  455.         goto rightwall;
  456.     if ( maze[cur_sq_x][cur_sq_y - 1] & ANY_IN_DOOR )
  457.     {
  458.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | WALL_TOP;
  459.         maze[cur_sq_x][cur_sq_y - 1] = maze[cur_sq_x][cur_sq_y - 1] | WALL_BOTTOM;
  460.         draw_wall(cur_sq_x, cur_sq_y, 0 );
  461.         goto rightwall;
  462.     }
  463.     candidates[num_candidates++] = 0;
  464. rightwall:
  465.     /* right wall */
  466.     if ( maze[cur_sq_x][cur_sq_y] & RIGHT )
  467.         goto bottomwall;
  468.     if ( maze[cur_sq_x + 1][cur_sq_y] & ANY_IN_DOOR )
  469.     {
  470.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | WALL_RIGHT;
  471.         maze[cur_sq_x + 1][cur_sq_y] = maze[cur_sq_x + 1][cur_sq_y] | WALL_LEFT;
  472.         draw_wall(cur_sq_x, cur_sq_y, 1 );
  473.         goto bottomwall;
  474.     }
  475.     candidates[num_candidates++] = 1;
  476. bottomwall:
  477.     /* bottom wall */
  478.     if ( maze[cur_sq_x][cur_sq_y] & BOTTOM )
  479.         goto leftwall;
  480.     if ( maze[cur_sq_x][cur_sq_y + 1] & ANY_IN_DOOR )
  481.     {
  482.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | WALL_BOTTOM;
  483.         maze[cur_sq_x][cur_sq_y + 1] = maze[cur_sq_x][cur_sq_y + 1] | WALL_TOP;
  484.         draw_wall(cur_sq_x, cur_sq_y, 2 );
  485.         goto leftwall;
  486.     }
  487.     candidates[num_candidates++] = 2;
  488. leftwall:
  489.     /* left wall */
  490.     if ( maze[cur_sq_x][cur_sq_y] & LEFT )
  491.         goto donewall;
  492.     if ( maze[cur_sq_x - 1][cur_sq_y] & ANY_IN_DOOR )
  493.     {
  494.         maze[cur_sq_x][cur_sq_y] = maze[cur_sq_x][cur_sq_y] | WALL_LEFT;
  495.         maze[cur_sq_x - 1][cur_sq_y] = maze[cur_sq_x - 1][cur_sq_y] | WALL_RIGHT;
  496.         draw_wall(cur_sq_x, cur_sq_y, 3 );
  497.         goto donewall;
  498.     }
  499.     candidates[num_candidates++] = 3;
  500. donewall:
  501.     if (num_candidates == 0)
  502.         return ( -1 );
  503.     if (num_candidates == 1)
  504.         return ( candidates[0] );
  505.     return ( candidates[ random(num_candidates) ] );
  506. } /* end of choose_door() */
  507.  
  508. backup() /* back up a move */
  509. {
  510.     sqnum--;
  511.     cur_sq_x = move_list[sqnum].x;
  512.     cur_sq_y = move_list[sqnum].y;
  513.     return ( sqnum );
  514. } /* end of backup() */
  515.  
  516. /* draw a single wall */
  517.  
  518. draw_wall(i, j, dir )
  519. unsigned int i, j, dir;
  520. {
  521.     unsigned int tempx, tempy;
  522.  
  523.     switch (dir) {
  524.     case 0: /* top */
  525.         tempx = xoffset_count + XSQ_SIZE * i;
  526.         tempy = yoffset_count + YSQ_SIZE * j;
  527.         XDrawLine( tempx, tempy, tempx + XSQ_SIZE, tempy );
  528.         break;
  529.     case 1: /* right */
  530.         tempx = xoffset_count + XSQ_SIZE * (i+1);
  531.         tempy = yoffset_count + YSQ_SIZE * j;
  532.         XDrawLine( tempx, tempy, tempx, tempy + YSQ_SIZE );
  533.         break;
  534.     case 2: /* bottom */
  535.         tempx = xoffset_count + XSQ_SIZE * i;
  536.         tempy = yoffset_count + YSQ_SIZE * (j+1);
  537.         XDrawLine( tempx, tempy, tempx + XSQ_SIZE, tempy );
  538.         break;
  539.     case 3: /* left */
  540.         tempx = xoffset_count + XSQ_SIZE * i;
  541.         tempy = yoffset_count + YSQ_SIZE * j;
  542.         XDrawLine( tempx, tempy, tempx, tempy + YSQ_SIZE );
  543.         break;
  544.     }
  545. } /* end of draw_wall */
  546.  
  547. /* draw a solid circle in a square */
  548.  
  549. circle_draw_solid(i, j, dir )
  550. unsigned int i, j, dir;
  551. {
  552.     unsigned int tempx, tempy;
  553.  
  554.     tempx = xoffset_count + 2 + XSQ_SIZE * i;
  555.     tempy = yoffset_count + 2 + YSQ_SIZE * j;
  556.     XDrawCircle( tempx + (int)(XOFFSET * 1.5 ), tempy + YOFFSET, YPATH_SIZE );
  557. } /* end of circle_draw_solid() */
  558.  
  559. /* draw a solid square in a square */
  560.  
  561. square_draw_solid(i, j, dir )
  562. unsigned int i, j, dir;
  563. {
  564.     unsigned int tempx, tempy;
  565.  
  566.     tempx = xoffset_count + XOFFSET + XSQ_SIZE * i;
  567.     tempy = yoffset_count + YOFFSET + YSQ_SIZE * j;
  568.  
  569.     switch (dir) {
  570.     case 0: /* up */
  571.         XFillRectangle ( tempx, tempy - YDIFF, XPATH_SIZE, YPATH_SIZE + YDIFF);
  572.         break;
  573.     case 1: /* right */
  574.         XFillRectangle ( tempx, tempy, XPATH_SIZE + XDIFF, YPATH_SIZE);
  575.         break;
  576.     case 2: /* down */
  577.         XFillRectangle ( tempx, tempy, XPATH_SIZE, YPATH_SIZE + YDIFF);
  578.         break;
  579.     case 3: /* left */
  580.         XFillRectangle ( tempx - XDIFF, tempy, XPATH_SIZE + XDIFF, YPATH_SIZE);
  581.         break;
  582.     }
  583. } /* end of square_draw_solid() */
  584.  
  585. /* solve it with graphical feedback */
  586.  
  587. void 
  588. solve_maze()
  589. {
  590.     register unsigned int i;
  591.     FColor ( outpath, PATHGROUND );
  592.  
  593.     /* plug up the surrounding wall */
  594.     maze[start_x][start_y] = maze[start_x][start_y] | (WALL_TOP >> start_dir);
  595.     maze[end_x][end_y] = maze[end_x][end_y] |(WALL_TOP >> end_dir);
  596.  
  597.     /* initialize search path */
  598.     i = 0;
  599.     path[i].x = end_x;
  600.     path[i].y = end_y;
  601.     path[i].dir = -1;
  602.  
  603.     /* do it */
  604.     while (! sigcode) {
  605.         if ( ++path[i].dir >= 4 )
  606.         {
  607.             /*
  608.             XSetTile ( display , gc, tile25 );
  609.             XSetFillStyle ( display , gc, FillTiled );
  610.             */
  611.             FColor ( outpath, WRNGGROUND );
  612.             i--;
  613.             square_draw_solid((int)(path[i].x),(int)(path[i].y),(int)(path[i].dir));
  614.             FColor ( outpath, PATHGROUND );
  615.         }
  616.         else if ( !((maze[path[i].x][path[i].y] & (WALL_TOP >> path[i].dir))) &&
  617.             ( (i == 0) || ( (path[i].dir != (path[i-1].dir+2)%4) ) ) )
  618.         {
  619.             enter_square( i );
  620.             i++;
  621.             if ( maze[path[i].x][path[i].y] & START_SQUARE )
  622.             {
  623.                 return;
  624.             }
  625.         }
  626.     }
  627. } /* end of solve_maze() */
  628.  
  629. /* move into a neighboring square */
  630.  
  631. enter_square( n )
  632. unsigned int n;
  633. {
  634.     square_draw_solid( (int)path[n].x, (int)path[n].y, (int)path[n].dir );
  635.     path[n+1].dir = -1;
  636.     switch (path[n].dir) {
  637.     case 0: 
  638.         path[n+1].x = path[n].x;
  639.         path[n+1].y = path[n].y - 1;
  640.         break;
  641.     case 1: 
  642.         path[n+1].x = path[n].x + 1;
  643.         path[n+1].y = path[n].y;
  644.         break;
  645.     case 2: 
  646.         path[n+1].x = path[n].x;
  647.         path[n+1].y = path[n].y + 1;
  648.         break;
  649.     case 3: 
  650.         path[n+1].x = path[n].x - 1;
  651.         path[n+1].y = path[n].y;
  652.         break;
  653.     }
  654. } /* end of enter_square() */
  655.  
  656. XDrawLine ( sx, sy, ex, ey )
  657. unsigned int sx, sy, ex, ey;
  658. {
  659.     if (gotosleep)
  660.         sleep(0);
  661.     SetDPtr ( outpath, sx, sy ); 
  662.     Line ( outpath, ex, ey ); 
  663. }
  664.  
  665. XFillRectangle ( sx, sy, ex, ey )
  666. unsigned int sx, sy, ex, ey;
  667. {
  668.     if (gotosleep)
  669.         sleep(0);
  670.     SetDPtr ( outpath, sx, sy ); 
  671.     RBar ( outpath, ex, ey );
  672. }
  673.  
  674. XDrawCircle ( sx, sy, rad )
  675. unsigned int sx, sy, rad ;
  676. {
  677.     if (gotosleep)
  678.         sleep(0);
  679.     SetDPtr ( outpath, sx, sy ); 
  680.     Circle  ( outpath, rad );
  681.     FFill   ( outpath );
  682. }
  683.  
  684. random ( num )
  685. unsigned int num;
  686. {
  687.     return ( abs(rand (num)%num) );
  688. }
  689.  
  690. getcolorset()
  691. {
  692.     int color;
  693.     
  694.     WRNGGROUND = random(255);
  695.     PATHGROUND = ((color = random(254) + 1) % 16) ? color : color + 1;
  696.        while (PATHGROUND == WRNGGROUND)
  697.            WRNGGROUND = random(255);
  698. }
  699.  
  700.     
  701. GetWOpts()
  702. {
  703.     _gs_opt(0,&wbuforig);
  704. }
  705.  
  706. pausesw(path,sw_pause)
  707. int path, sw_pause;
  708. {
  709.     _gs_opt(path, &wbuf);
  710.     wbuf.sg_pause = (sw_pause) ? ON : OFF;
  711.     _ss_opt (path, &wbuf);
  712. }
  713.  
  714. Reset()
  715. {
  716.     _ss_opt(0, &wbuforig);
  717. }
  718.  
  719.