Mazes [by Desmond Daignault]
Snippet Posted Wednesday, August 12th @ 11:30:45 PM, by George Greer in the Specials dept.
Added Feb 6, 1997. Click the link below to read it or download it.

From: Desmond Daignault <tekdd@dtol.datatimes.com>
Subject: Randomized Mazes

Here is some code to implement random mazes.

mods needed for db.c
---> in the function declaration section add
     int boot_mazes(void);
---> after the index_boot(DB_BOOT_WLD); add
     log("Generating random mazes.");
     boot_mazes();
---> in db.h add
     #define MAZE_PREFIX "world/maz"  /* maze definitions */
---> add to Makefile maze.o to the OBJFILES section.
---> add to Makefile
     for act.wizard.o add maze.h to the dependancy list
     also add
     maze.o: maze.c structs.h db.h utils.h maze.h

$(CC) -c $(CFLAGS) maze.c
---> in interpreter.c add an ACMD section for 'bootmaze'
---> in act.wizard.c add
     void reboot_maze (maze *m, int zone);
     void print_maze (maze *m, int zone);

ACMD(do_bootmaze) {
  char log_file[80];
  char index_file[80];
  maze m;
  FILE* f;
  FILE* index;
  int found=0;
  int zone_num=0;

  one_argument(argument, arg);

  if (!*arg) {
    send_to_char ("You must specify a zone number!\r\n", ch);
    return;
  }

  zone_num = atoi(arg);

  sprintf (log_file, "%s/%s.maz", MAZE_PREFIX, arg);
  sprintf (index_file, "%s/%s", MAZE_PREFIX, INDEX_FILE);
  index=fopen(index_file, "r");
  if (index == NULL) {
    sprintf (buf, "Could not open %s.\r\n", index_file);
    send_to_char(buf, ch);
    return;
  }

  fgets(buf, 80, index);
  while (!feof(index)) {
    buf[strlen(buf)-1] = '\0';
    if (strcmp (buf, log_file + strlen(MAZE_PREFIX) +1) == 0)
      found = 1;
    fgets(buf, 80, index);
  }

  fclose(index);
  if (!found) {
    sprintf (buf, "Sorry, but zone %s is not a maze.\r\n", arg);
    send_to_char(buf, ch);
    return;
  }

  f=fopen(log_file, "w");
  if (f == NULL) {
    sprintf (buf, "Could not open %s.\r\n", log_file);
    send_to_char(buf, ch);
    return;
  }

  sprintf (buf, "%s has rebuilt maze #%s.", GET_NAME(ch), arg);
  mudlog(buf, 'G', COM_QUEST, TRUE);

  create_maze(&m);
  print_maze(&m, f);
  reboot_maze(&m, zone_num);
  send_to_char ("Done!\r\n", ch);
  fclose(f);
}

--> here is maze.c
/*
 *
 * Modified for CircleMud: Desmond Daignault
 * Algorithm taken from: xlockmore maze.c
 * Original author: David Bagley - bagleyd@megahertz.njit.edu
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include "structs.h"
#include "db.h"
#include "utils.h"
#include "maze.h"


void create_rooms (maze* m, char log_filename[80]);
void create_maze (maze* m);
void print_maze (maze* m, FILE* f);
int choose_exit (maze* m);
int place_wall (maze* m);
int backup (maze* m);
int boot_mazes ();
void reboot_maze (maze* m, int zone_num);


void reboot_maze (maze* m, int zone_num) {
  int room_nr=0;
  int zone_number=0;
  int i=0;
  int x=0;
  int y=0;
  extern struct room_data* world;
  extern int top_of_world;
  extern struct zone_data* zone_table;
  extern int top_of_zone_table;
  int start_room = 0;

  for (i=0;i<=top_of_zone_table;i++)
    if (zone_table[i].number == zone_num)
      zone_number = i;

  for (room_nr=0;room_nr<=top_of_world;room_nr++)
    if (world[room_nr].zone == zone_number)
      break;

  start_room = room_nr;

  for (i=0;i<=top_of_world;i++)
    if (world[i].zone == zone_number) {
      /* top wall of maze */
      if ((world[i].number % 100) == 0) {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
       /* bottom wall of maze */
      } else if ((world[i].number % 100) == 90) {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
      /* all others */
      } else {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
      }
    }

  room_nr = start_room;

  for (y=0;y<10;y++)
    for (x=0;x<10;x++) {
      if (m->path[x][y] & DONORTH) {
        if (!world[room_nr].dir_option[0])
          CREATE(world[room_nr].dir_option[0], struct room_direction_data, 1);
        world[room_nr].dir_option[0]->to_room = real_room(world[room_nr].number
 - 10);
        world[room_nr].dir_option[0]->to_room_vnum = world[room_nr].number - 10
;
        world[room_nr].dir_option[0]->key = -1;
        world[room_nr].dir_option[0]->exit_info = 0;
      }
      if (m->path[x][y] & DOEAST) {
        if (!world[room_nr].dir_option[1])
          CREATE(world[room_nr].dir_option[1], struct room_direction_data, 1);
        world[room_nr].dir_option[1]->to_room = real_room(world[room_nr].number
 + 1);
        world[room_nr].dir_option[1]->to_room_vnum = world[room_nr].number + 1;
        world[room_nr].dir_option[1]->key = -1;
        world[room_nr].dir_option[1]->exit_info = 0;
      }
      if (m->path[x][y] & DOSOUTH) {
        if (!world[room_nr].dir_option[2])
          CREATE(world[room_nr].dir_option[2], struct room_direction_data, 1);
        world[room_nr].dir_option[2]->to_room = real_room(world[room_nr].number
 + 10);
        world[room_nr].dir_option[2]->to_room_vnum = world[room_nr].number + 10
;
        world[room_nr].dir_option[2]->key = -1;
        world[room_nr].dir_option[2]->exit_info = 0;
      }
      if (m->path[x][y] & DOWEST) {
        if (!world[room_nr].dir_option[3])
          CREATE(world[room_nr].dir_option[3], struct room_direction_data, 1);
        world[room_nr].dir_option[3]->to_room = real_room(world[room_nr].number
 - 1);
        world[room_nr].dir_option[3]->to_room_vnum = world[room_nr].number - 1;
        world[room_nr].dir_option[3]->key = -1;
        world[room_nr].dir_option[3]->exit_info = 0;
      }
      room_nr++;
    }
}

void create_rooms (maze* m, char log_filename[80]) {
  int room_nr=0;
  int zone_nr=0;
  int zone_number=0;
  int i=0;
  int x=0;
  int y=0;
  struct room_data* new_world;
  extern struct room_data* world;
  extern int top_of_world;
  extern struct zone_data* zone_table;
  extern int top_of_zone_table;
  char buf[80];
  int room_count=0;
  int found = 0;
  int start_room = 0;



  zone_number = atoi(log_filename);

  sprintf (buf, "   Building maze #%d", zone_number);
  log(buf);

  for (i=0;i<=top_of_zone_table;i++) {
    if (((zone_table[i].top - (zone_table[i].top % 100))/100) == zone_number) {
      zone_number = i;
      found = 1;
    }
  }

  if (!found) {
    sprintf (buf, "SYSERR: Could not find zone #%d", zone_number);
    log(buf);
    exit (1);
  }

  for (i=0;i<=top_of_world;i++)
    if (world[i].zone == zone_number)
      room_count++;

  if (room_count < 3) {
    sprintf (buf, "SYSERR: Maze %s only has %d rooms.", log_filename, room_coun
t);
    log(buf);
    exit(1);
  }

  if (room_count < 100) {
    CREATE(new_world, struct room_data, ((100-room_count) + top_of_world) + 2);
    /* insert rooms */
    for (room_nr=0;room_nr<=top_of_world;room_nr++)
      if (world[room_nr].zone > zone_number)
        break;

    start_room = world[room_nr-room_count].number;

    room_nr--;

    /* copy all rooms before last room */
    for (i=0;i<room_nr;i++)
      new_world[i] = world[i];

    zone_nr = atoi(log_filename);

    /* these are the new rooms */
    for (i=0;i<(100-room_count);i++) {
      new_world[i+room_nr].zone = new_world[i+room_nr-1].zone;
      new_world[i+room_nr].number = start_room+room_count+i-1;
      new_world[i+room_nr].name = strdup(new_world[i+room_nr-1].name);
      new_world[i+room_nr].description = strdup(new_world[i+room_nr-1].descript
ion);
      new_world[i+room_nr].room_flags = new_world[i+room_nr-1].room_flags;
      new_world[i+room_nr].sector_type = new_world[i+room_nr-1].sector_type;
      new_world[i+room_nr].func = NULL;
      new_world[i+room_nr].contents = NULL;
      new_world[i+room_nr].people = NULL;
      new_world[i+room_nr].light = 0;
      new_world[i+room_nr].ex_description = NULL;

      for (x=0;x<NUM_OF_DIRS;x++)
        new_world[i+room_nr].dir_option[x] = NULL;
    }

    /* copy the rest of the rooms */
    for (i=room_nr;i<=top_of_world;i++)
      new_world[i+(100-room_count)] = world[i];

    top_of_world += (100-room_count);
    free(world);
    world=new_world;
  }

  for (room_nr=0;room_nr<=top_of_world;room_nr++)
    if (world[room_nr].zone == zone_number)
      break;

  for (i=0;i<=top_of_world;i++)
    if (world[i].zone == zone_number) {
      /* top wall of maze */
      if ((world[i].number % 100) == 0) {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
       /* bottom wall of maze */
      } else if ((world[i].number % 100) == 90) {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
      /* all others */
      } else {
        for (x=0;x<9;x++) {
          if (x==0) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
          } else if (x==9) {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          } else {
            if (world[i].dir_option[0]) {
              if (world[i].dir_option[0]->general_description)
                free (world[i].dir_option[0]->general_description);
              if (world[i].dir_option[0]->keyword)
                free (world[i].dir_option[0]->keyword);
              free (world[i].dir_option[0]);
              world[i].dir_option[0] = NULL;
            }
            if (world[i].dir_option[1]) {
              if (world[i].dir_option[1]->general_description)
                free (world[i].dir_option[1]->general_description);
              if (world[i].dir_option[1]->keyword)
                free (world[i].dir_option[1]->keyword);
              free (world[i].dir_option[1]);
              world[i].dir_option[1] = NULL;
            }
            if (world[i].dir_option[2]) {
              if (world[i].dir_option[2]->general_description)
                free (world[i].dir_option[2]->general_description);
              if (world[i].dir_option[2]->keyword)
                free (world[i].dir_option[2]->keyword);
              free (world[i].dir_option[2]);
              world[i].dir_option[2] = NULL;
            }
            if (world[i].dir_option[3]) {
              if (world[i].dir_option[3]->general_description)
                free (world[i].dir_option[3]->general_description);
              if (world[i].dir_option[3]->keyword)
                free (world[i].dir_option[3]->keyword);
              free (world[i].dir_option[3]);
              world[i].dir_option[3] = NULL;
            }
          }
        }
      }
    }

  for (i=0;i<100;i++)
    world[room_nr+i].number=start_room+i;

  for (y=0;y<10;y++)
    for (x=0;x<10;x++) {
      if (m->path[x][y] & DONORTH) {
        if (!world[room_nr].dir_option[0])
          CREATE(world[room_nr].dir_option[0], struct room_direction_data, 1);
        world[room_nr].dir_option[0]->to_room = world[room_nr].number - 10;
        world[room_nr].dir_option[0]->key = -1;
        world[room_nr].dir_option[0]->exit_info = 0;
      }
      if (m->path[x][y] & DOEAST) {
        if (!world[room_nr].dir_option[1])
          CREATE(world[room_nr].dir_option[1], struct room_direction_data, 1);
        world[room_nr].dir_option[1]->to_room = world[room_nr].number + 1;
        world[room_nr].dir_option[1]->key = -1;
        world[room_nr].dir_option[1]->exit_info = 0;
      }
      if (m->path[x][y] & DOSOUTH) {
        if (!world[room_nr].dir_option[2])
          CREATE(world[room_nr].dir_option[2], struct room_direction_data, 1);
        world[room_nr].dir_option[2]->to_room = world[room_nr].number + 10;
        world[room_nr].dir_option[2]->key = -1;
        world[room_nr].dir_option[2]->exit_info = 0;
      }
      if (m->path[x][y] & DOWEST) {
        if (!world[room_nr].dir_option[3])
          CREATE(world[room_nr].dir_option[3], struct room_direction_data, 1);
        world[room_nr].dir_option[3]->to_room = world[room_nr].number - 1;
        world[room_nr].dir_option[3]->key = -1;
        world[room_nr].dir_option[3]->exit_info = 0;
      }
      room_nr++;
    }
}

void create_maze (maze* m) {
int i;
int j;
struct timeval t;
int c_time;

m->x=0;
m->y=0;
m->lastdir = 0;
m->step=0;

gettimeofday(&t,0);
c_time = t.tv_sec;
srand (c_time);
for (i=0;i<1000;i++) {
  rand();
}

for (i=0;i<10;i++)
  for (j=0;j<10;j++)
    m->path[i][j]=0;

for (i=0;i<100;i++) {
  m->saved_path[i].x = 0;
  m->saved_path[i].y = 0;
  m->solve_path[i].x = 0;
  m->solve_path[i].y = 0;
}

/* top wall */
for (j=0;j<10;j++)
  m->path[j][0] |= WNORTH;

/* bottom wall */
for (j=0;j<10;j++)
  m->path[j][9] |= WSOUTH;

/* left wall */
for (i=0;i<10;i++)
  m->path[0][i] |= WWEST;

/* right wall */
for (i=0;i<10;i++)
  m->path[9][i] |= WEAST;

for (;;) {
  m->saved_path[m->step].x=m->x;
  m->saved_path[m->step].y=m->y;

  while ((m->lastdir = choose_exit(m)) == -1)
    if (backup(m) == -1) return;

  switch (m->lastdir) {
    case 0:
      m->path[m->x][m->y] |= DONORTH;
      m->y--;
      m->path[m->x][m->y] |= DOSOUTH;
    break;
    case 1:
      m->path[m->x][m->y] |= DOEAST;
      m->x++;
      m->path[m->x][m->y] |= DOWEST;
    break;
    case 2:
      m->path[m->x][m->y] |= DOSOUTH;
      m->y++;
      m->path[m->x][m->y] |= DONORTH;
    break;
    case 3:
      m->path[m->x][m->y] |= DOWEST;
      m->x--;
      m->path[m->x][m->y] |= DOEAST;
    break;
  }
m->step++;
if (m->x == 9 && m->y == 9) {
  int z;
  for (z=0;z<m->step;z++) {
    m->solve_path[z].x=m->saved_path[z].x;
    m->solve_path[z].y=m->saved_path[z].y;
  }
m->solve_path[m->step].x = 9;
m->solve_path[m->step].y = 9;
}
}
}

int backup(maze* m) {
m->step--;
if (m->step >= 0) {
  m->x=m->saved_path[m->step].x;
  m->y=m->saved_path[m->step].y;
}
return (m->step);
}

int choose_exit(maze* m) {
int choice[3];
int num_choice=0;

if (!(m->path[m->x][m->y] & WNORTH) &&
    !(m->path[m->x][m->y] & DONORTH))
  if (m->path[m->x][m->y-1] & DOANY) {
    m->path[m->x][m->y] |= WNORTH;
    m->path[m->x][m->y-1] |= WSOUTH;
  } else
    choice[num_choice++] = 0;

if (!(m->path[m->x][m->y] & WEAST) &&
    !(m->path[m->x][m->y] & DOEAST))
  if (m->path[m->x+1][m->y] & DOANY) {
    m->path[m->x][m->y] |= WEAST;
    m->path[m->x+1][m->y] |= WWEST;
  } else
    choice[num_choice++] = 1;
if (!(m->path[m->x][m->y] & WSOUTH) &&
    !(m->path[m->x][m->y] & DOSOUTH))
  if (m->path[m->x][m->y+1] & DOANY) {
    m->path[m->x][m->y] |= WSOUTH;
    m->path[m->x][m->y+1] |= WNORTH;
  } else
    choice[num_choice++] = 2;
if (!(m->path[m->x][m->y] & WWEST) &&
    !(m->path[m->x][m->y] & DOWEST))
  if (m->path[m->x-1][m->y] & DOANY) {
    m->path[m->x][m->y] |= WWEST;
    m->path[m->x-1][m->y] |= WEAST;
  } else
    choice[num_choice++] = 3;

if (num_choice == 0)
  return -1;
else if (num_choice == 1)
  return choice[0];

return (choice[rand()%num_choice]);
}

void print_maze(maze* m, FILE* f) {
int x;
int y;
int i;

for (y=0;y<10;y++) {
  for (x=0;x<10;x++) {
    if (m->path[x][y] & WNORTH)
      m->path[x][y] ^= WNORTH;
    if (m->path[x][y] & WEAST)
      m->path[x][y] ^= WEAST;
    if (m->path[x][y] & WSOUTH)
      m->path[x][y] ^= WSOUTH;
    if (m->path[x][y] & WWEST)
      m->path[x][y] ^= WWEST;
    fprintf (f, "%d\t", m->path[x][y]);
  }
  fprintf (f, "\n");
}

fprintf (f, "\nDOW = %d\n", (DOWEST));
fprintf (f, "DOS = %d\n", (DOSOUTH));
fprintf (f, "DOSW = %d\n", (DOSOUTH | DOWEST));
fprintf (f, "DOE = %d\n", (DOEAST));
fprintf (f, "DOEW = %d\n", (DOWEST | DOEAST));
fprintf (f, "DOES = %d\n", (DOSOUTH | DOEAST));
fprintf (f, "DOESW = %d\n", (DOEAST | DOWEST | DOSOUTH));
fprintf (f, "DON = %d\n", (DONORTH));
fprintf (f, "DONW = %d\n", (DONORTH | DOWEST));
fprintf (f, "DONS = %d\n", (DONORTH | DOSOUTH));
fprintf (f, "DONSW = %d\n", (DONORTH | DOWEST | DOSOUTH));
fprintf (f, "DONE = %d\n", (DONORTH | DOEAST));
fprintf (f, "DONEW = %d\n", (DONORTH | DOEAST | DOWEST));
fprintf (f, "DONES = %d\n", (DONORTH | DOEAST | DOSOUTH));
fprintf (f, "DONESW = %d\n\n", (DOANY));

for (i=0;i<100;i++)
  if (m->solve_path[i].x != 9 || m->solve_path[i].y != 9) {
    if (i == 0)
      fprintf (f, "%d) Start\n", i);
    if ((m->solve_path[i].x == m->solve_path[i-1].x) &&
        (m->solve_path[i].y < m->solve_path[i-1].y))
      fprintf (f, "%d) North\n", i);
    if ((m->solve_path[i].x > m->solve_path[i-1].x) &&
        (m->solve_path[i].y == m->solve_path[i-1].y))
      fprintf (f, "%d) East\n", i);
    if ((m->solve_path[i].x == m->solve_path[i-1].x) &&
        (m->solve_path[i].y > m->solve_path[i-1].y))
      fprintf (f, "%d) South\n", i);
    if ((m->solve_path[i].x < m->solve_path[i-1].x) &&
        (m->solve_path[i].y == m->solve_path[i-1].y))
      fprintf (f, "%d) West\n", i);
  }
  else
    break;

if ((m->solve_path[i].x == m->solve_path[i-1].x) &&
    (m->solve_path[i].y < m->solve_path[i-1].y))
  fprintf (f, "%d) North\n", i);
if ((m->solve_path[i].x > m->solve_path[i-1].x) &&
    (m->solve_path[i].y == m->solve_path[i-1].y))
  fprintf (f, "%d) East\n", i);
if ((m->solve_path[i].x == m->solve_path[i-1].x) &&
    (m->solve_path[i].y > m->solve_path[i-1].y))
  fprintf (f, "%d) South\n", i);
if ((m->solve_path[i].x < m->solve_path[i-1].x) &&
    (m->solve_path[i].y == m->solve_path[i-1].y))
  fprintf (f, "%d) West\n", i);
}

int boot_mazes (void) {
FILE* index=NULL;
FILE* f=NULL;
char index_filename[80];
char log_filename[80];
char temp[80];
maze m;

sprintf (index_filename, "%s/%s", MAZE_PREFIX, INDEX_FILE);

index = fopen(index_filename, "r");
if (index == NULL) {
  log ("SYSERR: unable to read maze index.");
  exit (1);
}

fgets(temp, 80, index);
while (!feof(index)) {

if (temp[0] == '$') {
  fclose(index);
  if (f)
    fclose(f);
  return 0;
}

temp[strlen(temp)-1]= '\0';
sprintf (log_filename, "%s/%s", MAZE_PREFIX, temp);

f=fopen(log_filename, "w");
if (f == NULL) {
  sprintf (temp, "SYSERR: unable to create maze log %s.", log_filename);
  log(temp);
  exit (1);
}

create_maze (&m);
print_maze (&m, f);
create_rooms(&m, temp);
fclose (f);
fgets(temp, 80, index);
sleep(1);
}

fclose (index);
return 0;
}

---> and maze.h
#define WNORTH 0x80
#define WEAST 0x40
#define WSOUTH 0x20
#define WWEST 0x10
#define DONORTH 0x8
#define DOEAST 0x4
#define DOSOUTH 0x2
#define DOWEST 0x1
#define DOANY 0xF

typedef struct {
  int x;
  int y;
} path;

typedef struct {
  int path[10][10];
  path saved_path[100];
  path solve_path[100];
  int x;
  int y;
  int lastdir;
  int step;
} maze;

--> prerequisites.

The code requires that at least 3 rooms exist in the .wld file room 0,
room 1, and room 99. (I did this cuz me was lazy). If you want to go ahead
and build more than those 3 feel free... You don't need to specify any
exits except the entrance and exit to the maze. (if i remember correctly
you can put them in room 0 and room 99.) It will copy room number 1 to
fill in any room slots until the zone has 100 rooms. You will also need to
make a new directory under the lib/world directory (named whatever you set
MAZE_PREFIX to in db.h). And the only file that needs to be in the
directory is an index file that contains the zone numbers to be
randomized. The code will generate a flat file that is representative of
the maze at the moment of creation called <zonenumber>.maz in the maze
directory.

This code is offered as is... so use it at your own risk. If you make any
enhancements (like allowing a range of rooms to be randomized), I would
appreciate being sent a copy of the changes.

Dez.


<< Mail autoreception [by Ryan Linn] | Reply | View as text | Flattened | More Mazes [by Doppleganger Software] >>

 


Related Links
  CircleMUD
download
Related Articles
More by greerga
 
 

CircleMUD Snippets
 
Note: Not all of these snippets will work perfectly with your version of code, so be prepared to fix one or two bugs that may arise, and please let me know what you needed to do to fix it. Sending a corrected version is always welcome.
Finally, if you wish to use any of the snippets from this page, you are more than welcome, just mention the authors in your credits. If you wish to release any of these snippets to the public on another site, contact me FIRST.