home *** CD-ROM | disk | FTP | other *** search
/ Desktop Works 1995 - 1996 / desktopworks1995-1996.iso / scrnsave / win_maze / sqrmaze.cpp < prev    next >
C/C++ Source or Header  |  1996-01-01  |  25KB  |  630 lines

  1. #include <owl\owlpch.h>
  2. #include <owl\applicat.h>
  3. #include <owl\framewin.h>
  4. #include <owl\dc.h>
  5. #include "oracle.h"
  6. #include "cell.h"
  7. #include "sqrmaze.h"
  8.  
  9. #ifndef TRUE
  10. #define TRUE -1
  11. #endif
  12. #ifndef FALSE
  13. #define FALSE 0
  14. #endif
  15.  
  16. typedef cell *cell_ptr;
  17.  
  18. sqrmaze::sqrmaze(int row_count,int column_count,int thickness_of_wall,
  19.  char *seed,TFrameWindow *win_ptr)
  20. //      Contruct a maze having "row_count" rows and "column_count" columns of
  21. // rooms.  The walls should be "thickness_of_wall" (bricks) thick.  A different
  22. // (8 character of less) "seed" generally yields a different maze.
  23.   {
  24.     struct
  25.       {
  26.          int row_num;
  27.          int column_num;
  28.       }  delta [4];
  29.     int  mud_filled_room_found;
  30.     struct
  31.       {
  32.          int row_num;
  33.          int column_num;
  34.       }  next;
  35.     char wall [24] [4];
  36.     char wall_to_check;
  37.     char wall_num;
  38.     char way_out;
  39.  
  40.     // Allocate a two dimensional array of rooms.
  41.     window_ptr=win_ptr;
  42.     num_rows=row_count;
  43.     num_columns=column_count;
  44.     if (memory_allocated=((room=new cell_ptr[num_rows]) != NULL))
  45.       {
  46.         int row_num=0;
  47.         while ((memory_allocated) && (row_num < num_rows))
  48.           if (memory_allocated=((room[row_num]=new cell [num_columns]) != NULL))
  49.             row_num++;
  50.         if (! memory_allocated)
  51.           {
  52.             while (row_num)
  53.               delete [] room[--row_num];
  54.             delete [] room;
  55.             window_ptr->MessageBox("Cannot allocate maze!",
  56.              window_ptr->GetApplication()->GetName(),
  57.              MB_OK | MB_ICONEXCLAMATION);
  58.           }
  59.       }
  60.     if (memory_allocated)
  61.       {
  62.          wall_thickness=thickness_of_wall;
  63.          // Set up the directions by which a room can be exited.
  64.          delta[0].row_num=-1;    // north
  65.          delta[0].column_num=0;
  66.          delta[1].row_num=0;     // west
  67.          delta[1].column_num=-1;
  68.          delta[2].row_num=1;     // south
  69.          delta[2].column_num=0;
  70.          delta[3].row_num=0;     // east
  71.          delta[3].column_num=1;
  72.          int order_num=0;
  73.          // Set up the 4! orders in which the wall of a room can be accessed.
  74.          for (int wall_num_1=0; wall_num_1 < 4; wall_num_1++)
  75.            for (int wall_num_2=0; wall_num_2 < 4; wall_num_2++)
  76.              if (wall_num_2 != wall_num_1)
  77.                for (int wall_num_3=0; wall_num_3 < 4; wall_num_3++)
  78.                  if ((wall_num_3 != wall_num_2)
  79.                  &&  (wall_num_3 != wall_num_1))
  80.                    for (int wall_num_4=0; wall_num_4 < 4; wall_num_4++)
  81.                      if ((wall_num_4 != wall_num_3)
  82.                      &&  (wall_num_4 != wall_num_2)
  83.                      &&  (wall_num_4 != wall_num_1))
  84.                        {
  85.                          wall[order_num][wall_num_4]='\0';
  86.                          wall[order_num][wall_num_3]='\1';
  87.                          wall[order_num][wall_num_2]='\2';
  88.                          wall[order_num][wall_num_1]='\3';
  89.                          order_num++;
  90.                        }
  91.          order_selector=new oracle(&seed[0],order_num);
  92.          row_selector=new oracle(&seed[0],num_rows);
  93.          column_selector=new oracle(&seed[0],num_columns); 
  94.          int finished=FALSE;
  95.          // Generate mazes until you have one that is hard to solve.
  96.          do
  97.            {
  98.               // Pick a starting room.
  99.               first.row_num=row_selector->random_number();
  100.               first.column_num=column_selector->random_number();
  101.               current.row_num=first.row_num;
  102.               current.column_num=first.column_num;
  103.               // Excavate the starting room.
  104.               room[current.row_num][current.column_num].mark_floor(' ');
  105.               // Pick the order in which the walls of the starting room will be
  106.               // considered.
  107.               room[current.row_num][current.column_num].set_order(
  108.                order_selector->random_number());
  109.               // Excavate rooms until there are no more to excavate.
  110.               do
  111.                 {
  112.                    mud_filled_room_found=FALSE;
  113.                    // Find an adjacent room (not yet considered) that needs
  114.                    // excavating.
  115.                    do
  116.                      {
  117.                         wall_num=room[current.row_num][
  118.                          current.column_num].next_wall_num();
  119.                         if (wall_num < '\4')
  120.                           {
  121.                              wall_to_check=wall[room[current.row_num][
  122.                               current.column_num].order_to_check()][wall_num];
  123.                              if (room[current.row_num][
  124.                               current.column_num].wall_up(wall_to_check))
  125.                                {
  126.                                   next.row_num=current.row_num
  127.                                    +delta[wall_to_check].row_num;
  128.                                   if ((next.row_num >= 0)
  129.                                   &&  (next.row_num < num_rows))
  130.                                     {
  131.                                       next.column_num=current.column_num
  132.                                        +delta[wall_to_check].column_num;
  133.                                       if ((next.column_num >= 0)
  134.                                       &&  (next.column_num < num_columns))
  135.                                         {
  136.                                            if (room[next.row_num][
  137.                                             next.column_num].mark() 
  138.                                             == 'M')
  139.                                              mud_filled_room_found=TRUE;
  140.                                         }
  141.                                     }
  142.                                }
  143.                           }
  144.                      }
  145.                    while ((wall_num < '\4')
  146.                    &&     (! mud_filled_room_found));
  147.                    if (mud_filled_room_found)
  148.                    // an adjacent room needs excavating
  149.                      {
  150.                         // Exit the current room, knocking down a wall.
  151.                         room[current.row_num][
  152.                          current.column_num].knock_down_wall(wall_to_check);
  153.                         way_out=char(((int) wall_to_check+2)%4);
  154.                         // Enter the adjacent room, knocking down a wall.
  155.                         room[next.row_num][next.column_num].knock_down_wall(
  156.                          way_out);
  157.                         // Record how to return to the previous room.
  158.                         room[next.row_num][next.column_num].set_way_out(
  159.                          way_out);
  160.                         current.row_num=next.row_num;
  161.                         current.column_num=next.column_num;
  162.                         // Excavate the room.
  163.                         room[current.row_num][current.column_num].mark_floor(
  164.                          ' ');
  165.                         // Select the order in which the walls of the room will
  166.                         // be considered.
  167.                         room[current.row_num][current.column_num].set_order(
  168.                          order_selector->random_number());
  169.                      }
  170.                    else
  171.                    // no adjacent room needs excavating
  172.                      {
  173.                         if ((first.row_num != current.row_num)
  174.                         ||  (first.column_num != current.column_num))
  175.                         // not in starting room
  176.                           {
  177.                              // Go back to the room from which you entered
  178.                              // the current room.
  179.                              next.row_num=current.row_num+delta[
  180.                               room[current.row_num][
  181.                               current.column_num].way_back()].row_num;
  182.                              next.column_num=current.column_num+delta[
  183.                               room[current.row_num][
  184.                               current.column_num].way_back()].column_num;
  185.