home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Desktop Works 1995 - 1996
/
desktopworks1995-1996.iso
/
scrnsave
/
win_maze
/
sqrmaze.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-01
|
25KB
|
630 lines
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dc.h>
#include "oracle.h"
#include "cell.h"
#include "sqrmaze.h"
#ifndef TRUE
#define TRUE -1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef cell *cell_ptr;
sqrmaze::sqrmaze(int row_count,int column_count,int thickness_of_wall,
char *seed,TFrameWindow *win_ptr)
// Contruct a maze having "row_count" rows and "column_count" columns of
// rooms. The walls should be "thickness_of_wall" (bricks) thick. A different
// (8 character of less) "seed" generally yields a different maze.
{
struct
{
int row_num;
int column_num;
} delta [4];
int mud_filled_room_found;
struct
{
int row_num;
int column_num;
} next;
char wall [24] [4];
char wall_to_check;
char wall_num;
char way_out;
// Allocate a two dimensional array of rooms.
window_ptr=win_ptr;
num_rows=row_count;
num_columns=column_count;
if (memory_allocated=((room=new cell_ptr[num_rows]) != NULL))
{
int row_num=0;
while ((memory_allocated) && (row_num < num_rows))
if (memory_allocated=((room[row_num]=new cell [num_columns]) != NULL))
row_num++;
if (! memory_allocated)
{
while (row_num)
delete [] room[--row_num];
delete [] room;
window_ptr->MessageBox("Cannot allocate maze!",
window_ptr->GetApplication()->GetName(),
MB_OK | MB_ICONEXCLAMATION);
}
}
if (memory_allocated)
{
wall_thickness=thickness_of_wall;
// Set up the directions by which a room can be exited.
delta[0].row_num=-1; // north
delta[0].column_num=0;
delta[1].row_num=0; // west
delta[1].column_num=-1;
delta[2].row_num=1; // south
delta[2].column_num=0;
delta[3].row_num=0; // east
delta[3].column_num=1;
int order_num=0;
// Set up the 4! orders in which the wall of a room can be accessed.
for (int wall_num_1=0; wall_num_1 < 4; wall_num_1++)
for (int wall_num_2=0; wall_num_2 < 4; wall_num_2++)
if (wall_num_2 != wall_num_1)
for (int wall_num_3=0; wall_num_3 < 4; wall_num_3++)
if ((wall_num_3 != wall_num_2)
&& (wall_num_3 != wall_num_1))
for (int wall_num_4=0; wall_num_4 < 4; wall_num_4++)
if ((wall_num_4 != wall_num_3)
&& (wall_num_4 != wall_num_2)
&& (wall_num_4 != wall_num_1))
{
wall[order_num][wall_num_4]='\0';
wall[order_num][wall_num_3]='\1';
wall[order_num][wall_num_2]='\2';
wall[order_num][wall_num_1]='\3';
order_num++;
}
order_selector=new oracle(&seed[0],order_num);
row_selector=new oracle(&seed[0],num_rows);
column_selector=new oracle(&seed[0],num_columns);
int finished=FALSE;
// Generate mazes until you have one that is hard to solve.
do
{
// Pick a starting room.
first.row_num=row_selector->random_number();
first.column_num=column_selector->random_number();
current.row_num=first.row_num;
current.column_num=first.column_num;
// Excavate the starting room.
room[current.row_num][current.column_num].mark_floor(' ');
// Pick the order in which the walls of the starting room will be
// considered.
room[current.row_num][current.column_num].set_order(
order_selector->random_number());
// Excavate rooms until there are no more to excavate.
do
{
mud_filled_room_found=FALSE;
// Find an adjacent room (not yet considered) that needs
// excavating.
do
{
wall_num=room[current.row_num][
current.column_num].next_wall_num();
if (wall_num < '\4')
{
wall_to_check=wall[room[current.row_num][
current.column_num].order_to_check()][wall_num];
if (room[current.row_num][
current.column_num].wall_up(wall_to_check))
{
next.row_num=current.row_num
+delta[wall_to_check].row_num;
if ((next.row_num >= 0)
&& (next.row_num < num_rows))
{
next.column_num=current.column_num
+delta[wall_to_check].column_num;
if ((next.column_num >= 0)
&& (next.column_num < num_columns))
{
if (room[next.row_num][
next.column_num].mark()
== 'M')
mud_filled_room_found=TRUE;
}
}
}
}
}
while ((wall_num < '\4')
&& (! mud_filled_room_found));
if (mud_filled_room_found)
// an adjacent room needs excavating
{
// Exit the current room, knocking down a wall.
room[current.row_num][
current.column_num].knock_down_wall(wall_to_check);
way_out=char(((int) wall_to_check+2)%4);
// Enter the adjacent room, knocking down a wall.
room[next.row_num][next.column_num].knock_down_wall(
way_out);
// Record how to return to the previous room.
room[next.row_num][next.column_num].set_way_out(
way_out);
current.row_num=next.row_num;
current.column_num=next.column_num;
// Excavate the room.
room[current.row_num][current.column_num].mark_floor(
' ');
// Select the order in which the walls of the room will
// be considered.
room[current.row_num][current.column_num].set_order(
order_selector->random_number());
}
else
// no adjacent room needs excavating
{
if ((first.row_num != current.row_num)
|| (first.column_num != current.column_num))
// not in starting room
{
// Go back to the room from which you entered
// the current room.
next.row_num=current.row_num+delta[
room[current.row_num][
current.column_num].way_back()].row_num;
next.column_num=current.column_num+delta[
room[current.row_num][
current.column_num].way_back()].column_num;