📄 maze3d.c
字号:
/*
FMAZ20 -- Maze Game
Version 2.0 (10/24/94)
Generate and solve mazes on your VGA (or better) display.
The mazes are displayed in three dimensions.
You will be prompted for the number of columns, the tilt, and a random
number seed.
While the maze is being generated, a spinning cursor is displayed.
After the maze is displayed, you may use the arrow keys to solve it.
Press "Q" to quit or press "S" to have the computer solve the maze.
After the maze is solved, you must press some key to continue.
Each maze has exactly one solution that does not involve backtracking
(passing through a doorway more than once).
This program was written by James L. Dean.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <graphics.h>
#define TRUE -1
#define FALSE 0
/* screen constants */
#define HEIGHT_OF_SCREEN_IN_INCHES 6
#define WIDTH_OF_SCREEN_IN_INCHES 8
/* graphics adapter constants */
#define GRAPHICS_DRIVER VGA /* 640x480x16 VGA */
#define GRAPHICS_MODE VGAHI /* must support red, green, yellow,
and 5 shades of gray */
#define NUM_X_PIXELS 640
#define NUM_Y_PIXELS 480
#define X_PIXEL_MIN 10
#define X_PIXEL_MAX 629
#define Y_PIXEL_MIN 5
#define Y_PIXEL_MAX 474
#define NUM_COLORS 16
#define TOP_WALL_COLOR 12 /* all but last 3 colors are gray */
#define FLOOR_COLOR 9
#define LEFT_WALL_COLOR 6
#define FRONT_WALL_COLOR 3
#define RIGHT_WALL_COLOR 1
#define BACKOUT_COLOR 13
#define ADVANCE_COLOR 14
#define SOLUTION_COLOR 15
/* maze constants */
#define ROOM_HEIGHT_IN_Y_PIXELS 50
#define MIN_WALL_WIDTH_IN_X_PIXELS 3
#define ROOM_WIDTH_TO_WALL_WIDTH_RATIO 2 /* room excludes wall */
typedef struct corner_record
{
int x;
int y;
} corner_rec;
typedef struct stack_rec_record
{
char index_1;
int index_2;
} stack_rec;
static void display_maze(int,int,int,int,char **);
static void display_solution(int,int,int,int,char **);
static void draw_line(int,int,int,int,int,int);
static void generate_maze(int,int,int,int,int,char **,stack_rec *,
char *);
static void get_corners(double);
static void get_cursor(unsigned char *,unsigned char *,
unsigned char *,unsigned char *);
static void get_defaults(char *,int *,double *,char *);
static void hash(int *,int *,int *,int *,int *,int *,int *,int *);
static void increment(int *,int *,int *,int *,int *,int *,int *,
int *);
static void let_user_try_to_solve(int *,int,int,int,int,char **,
char **);
void main(int,char **);
void interrupt new_critical_error_handler(void);
void interrupt (*old_critical_error_handler)(void);
static void output_wall(int,int,int,int,int,int,int,int,int,int,int,
int,int,int,int);
static void put_defaults(char *,int,double,char *);
static void set_cursor_position(unsigned char,unsigned char);
static void set_cursor_size(unsigned char,unsigned char);
static void solve_maze(int,int,int *,int *,char **,stack_rec *);
static void titillate(void);
extern unsigned _stklen=0x8000;
static unsigned char cursor_column;
static unsigned char cursor_row;
static unsigned char cursor_start;
static unsigned char cursor_stop;
static int delta_x [4] [24];
static int delta_y [4] [24];
static int file_opened;
static char titillator [4] = {'|','/','-','\\'};
static int titillator_index;
static int x_corner [2] [2] [2];
static int y_corner [2] [2] [2];
void main(
int argc,
char *argv[])
{
register int color_num;
static char **computer_page;
static int default_num_columns;
static char default_seed [256];
static double default_tilt;
static int ErrorCode;
static int fatal_error;
static int GraphDriver;
static int GraphMode;
static char line [256];
static char *line_ptr;
static int max_num_columns;
static int max_x;
static int max_x_plus_1;
static int max_y;
static int max_y_plus_1;
static int min_num_columns;
static int memory_allocated;
static int num_columns;
static int num_assigned;
static int num_rooms_in_maze;
static int num_rows;
static struct palettetype palette;
static int response;
static char seed [256];
static int seed_index;
static stack_rec *stack;
static double tilt;
static int tint;
static char **user_page;
static int user_still_interested;
static int x;
max_num_columns=((X_PIXEL_MAX-X_PIXEL_MIN)/MIN_WALL_WIDTH_IN_X_PIXELS-1)
/(ROOM_WIDTH_TO_WALL_WIDTH_RATIO+2);
min_num_columns=(2*WIDTH_OF_SCREEN_IN_INCHES)/HEIGHT_OF_SCREEN_IN_INCHES;
if (min_num_columns*HEIGHT_OF_SCREEN_IN_INCHES
< 2*WIDTH_OF_SCREEN_IN_INCHES)
min_num_columns++;
fatal_error=FALSE;
get_defaults(argv[0],&default_num_columns,&default_tilt,
&default_seed[0]);
do
{
clrscr();
printf(
" FMAZ20 -- Maze Game\n\n"
" Version 2.0 (10/24/94)\n\n\n"
" Generate and solve mazes on your VGA (or better) display.\n\n"
" The mazes are displayed in three dimensions.\n\n"
" To get the value surrounded by [], just press Enter.\n\n");
do
{
printf(" Number of columns (%d to %d, or 0 to exit) [%d]? ",
min_num_columns,max_num_columns,default_num_columns);
fflush(stdin);
fgets(&line[0],256,stdin);
line_ptr=&line[0];
while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
line_ptr++;
if ((*line_ptr == '\n') || (*line_ptr == '\0'))
num_columns=default_num_columns;
else
{
num_assigned=sscanf(line_ptr,"%d",&num_columns);
if ((num_assigned == 0) || (num_assigned == EOF))
num_columns=-1;
}
}
while ((num_columns != 0)
&& ((num_columns < min_num_columns)
|| (num_columns > max_num_columns)));
user_still_interested=num_columns;
if (user_still_interested)
{
printf("\n");
num_rows=HEIGHT_OF_SCREEN_IN_INCHES
*num_columns/WIDTH_OF_SCREEN_IN_INCHES;
do
{
printf(" Tilt (30 to 60 degrees) [%lf]? ",default_tilt);
fflush(stdin);
fgets(&line[0],256,stdin);
line_ptr=&line[0];
while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
line_ptr++;
if ((*line_ptr == '\n') || (*line_ptr == '\0'))
tilt=default_tilt;
else
{
num_assigned=sscanf(line_ptr,"%lf",&tilt);
if ((num_assigned == 0) || (num_assigned == EOF))
tilt=(double) 0.0;
}
}
while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
printf("\n Random number seed (8 or fewer digits) [%s]? ",
&default_seed[0]);
fflush(stdin);
fgets(&line[0],256,stdin);
line_ptr=&line[0];
while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
line_ptr++;
if ((*line_ptr != '\n') && (*line_ptr != '\0'))
{
seed_index=0;
while ((seed_index < 8)
&& (*line_ptr)
&& (*line_ptr != '\n'))
default_seed[seed_index++]=*(line_ptr++);
default_seed[seed_index]='\0';
}
strcpy(&seed[0],&default_seed[0]);
default_num_columns=num_columns;
default_tilt=tilt;
num_rooms_in_maze=num_columns*num_rows;
if ((stack
=(stack_rec *) malloc(num_rooms_in_maze*sizeof(stack_rec)))
== NULL)
{
printf(" Fatal error: out of memory.\n");
fatal_error=TRUE;
}
else
{
max_x=2*num_columns;
max_x_plus_1=max_x+1;
max_y=2*num_rows;
max_y_plus_1=max_y+1;
if ((computer_page
=(char **) malloc(max_x_plus_1*sizeof(char *))) == NULL)
{
printf(" Fatal error: out of memory.\n");
fatal_error=TRUE;
}
else
{
memory_allocated=TRUE;
x=0;
while ((memory_allocated) && (x < max_x_plus_1))
if ((computer_page[x]
=(char *) malloc(max_y_plus_1*sizeof(char))) == NULL)
memory_allocated=FALSE;
else
x++;
if (memory_allocated)
{
if ((user_page
=(char **) malloc(max_x_plus_1*sizeof(char *)))
== NULL)
{
printf(" Fatal error: out of memory.\n");
fatal_error=TRUE;
}
else
{
x=0;
while ((memory_allocated) && (x < max_x_plus_1))
if ((user_page[x]
=(char *) malloc(max_y_plus_1*sizeof(char)))
== NULL)
memory_allocated=FALSE;
else
x++;
if (memory_allocated)
{
printf(
"\n While the maze is being generated, a spinning cursor is displayed: ");
generate_maze(num_columns,num_rows,
num_rooms_in_maze,max_x,max_y,computer_page,
stack,&seed[0]);
registerbgidriver(EGAVGA_driver);
/*
See the Borland documentation on the
utilities "BINOBJ" and "TLIB" for
information on how to link "EGAVGA.BGI"
into a program from "GRAPHICS.LIB".
*/
GraphDriver=GRAPHICS_DRIVER;
GraphMode=GRAPHICS_MODE;
initgraph(&GraphDriver,&GraphMode,"");
ErrorCode=graphresult();
if (ErrorCode == 0)
{
getpalette(&palette);
for (color_num=0;
color_num < (NUM_COLORS-3);
color_num++)
{ /* evenly spaced shades of gray */
tint=(63*color_num)/(NUM_COLORS-3);
tint&=0xfc;
setrgbpalette(
palette.colors[color_num],
tint,tint,tint);
}
setrgbpalette(
palette.colors[BACKOUT_COLOR],
0xfc,0xfc,0);
setrgbpalette(
palette.colors[ADVANCE_COLOR],
0,0xfc,0);
setrgbpalette(
palette.colors[SOLUTION_COLOR],
0xfc,0,0);
settextjustify(CENTER_TEXT,BOTTOM_TEXT);
settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
setcolor(NUM_COLORS-4);
outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
"Arrows - Move S - Solve Q - Quit");
get_corners(tilt);
display_maze(num_columns,num_rows,max_x,
max_y,computer_page);
let_user_try_to_solve(&response,num_rows,
num_columns,max_x,max_y,computer_page,
user_page);
if ((response == (int) 's')
|| (response == (int) 'S'))
{
display_solution(num_columns,
num_rows,max_x,max_y,computer_page);
setcolor(NUM_COLORS-4);
outtextxy(NUM_X_PIXELS/2,
NUM_Y_PIXELS-1,
"Press a key to continue.");
response=getch();
if (response == 0)
response=getch();
}
closegraph();
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -