数据结构C语言迷宫课设

源代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <ctime>
#include <string.h>
 

//宏定义
#define UP 8
#define RIGHT 6
#define DOWN 5
#define LEFT 4
#define TRUE 1
#define cell_empty(a) (!(a)->up && !(a)->right && !(a)->down && !(a)->left)
//下一个元素没有被访问,且验证前一个被访问过

//全局变量
int width, height;

typedef struct {
    unsigned int up      : 1;
    unsigned int right   : 1;
    unsigned int down    : 1;
    unsigned int left    : 1;
    unsigned int path    : 1;
    unsigned int visited : 1;
} cell_t;
typedef cell_t *maze_t;

//函数声明
void MazeOptions ();	//主菜单选项
void SubOptions ();		//次菜单选项
void CheckOptionM ();	//检查主菜单输入选项合法性
void CheckOptionS ();	//检查次菜单输入选项合法性
void ContinueMaze ();	//按任意键继续

void CreateMaze (maze_t maze, int width, int height);	//创建迷宫
void SolveMaze (maze_t maze, int width, int height);	//解迷宫
void PrintMaze (maze_t maze, int width, int height);	//显示迷宫
void RandomGenMaze ();	//自动生成
void ManualGenMaze ();	//手动生成

void PrintTitle();		//显示标题印象
void PrintMainMenu ();	//显示主菜单印象
void PrintSubMenu();	//显示次菜单印象
void PrintAboutMaze ();	//显示关于印象

//void PrintMGMenu ();	//显示手动生成迷宫提示
//void PrintAGMenu ();	//显示自动生成迷宫提示

int main ()
{   
	PrintTitle();
	MazeOptions ();
	return 1;
}//主函数

void MazeOptions ()
{
    char strm[256];
    PrintMainMenu();
    printf ("\n  Which option do you want to choose? (Enter '1' or '2' or '3' or '4')");
    scanf("%s", strm);
    
	if(strlen(strm)>1)
    {
		CheckOptionM ();
		return;
    }
    
	switch (strm[0])
    {
		
		case '1':  ManualGenMaze (); 
			break;
		case '2':  RandomGenMaze ();
			break;
		case '3':  PrintAboutMaze ();
			break;
		case '4':  exit (EXIT_SUCCESS); 
			break;
		default :  CheckOptionM ();
			break;
    }
}//主菜单选项

void SubOptions ()
{   
	char strs[256];
    PrintSubMenu ();
    printf ("\n   Which option do you want to choose? (Enter '1' or '2' or '3'or '4')");
    scanf("%s", strs);
   
	if(strlen(strs)>1)
    {
		CheckOptionS ();
		return;
    }
 	
	switch (strs[0])
	{
		case '1':  MazeOptions ();
			break;
		case '2':  RandomGenMaze (); 
			break;
		case '3':  ManualGenMaze (); 
			break;
		case '4':  exit (EXIT_SUCCESS); 
			break;
		default : CheckOptionS ();
	}
}//次菜单选项

void CheckOptionM ()
{
    printf ("\n     Error! Illegal option number! Did you input a wrong integer number?\n");
    ContinueMaze ();
    MazeOptions ();
}//检查主菜单输入选项合法性


void CheckOptionS ()
{
    printf ("\n     Error! Illegal option number! Did you input a wrong integer number?\n");
    ContinueMaze ();
    SubOptions ();
}//检查次菜单输入选项合法性

void ContinueMaze ()
{
	printf ("\n Press any key to continue...");
	getch();
}//按任意键继续

void CreateMaze (maze_t maze, int width, int height)   //创建迷宫
{
    maze_t mp, maze_top;
    char paths [4];
    int visits,directions;
    
	visits = width * height - 1;
    mp = maze;
    maze_top = mp + (width * height) - 1;
    
	while (visits) 
	{
        directions = 0;
        if ((mp - width) >= maze && cell_empty (mp - width))
            paths [directions++] = UP;
        if (mp < maze_top && ((mp - maze + 1) % width) && cell_empty (mp + 1))
            paths [directions++] = RIGHT;
        if ((mp + width) <= maze_top && cell_empty (mp + width))
            paths [directions++] = DOWN;
        if (mp > maze && ((mp - maze) % width) && cell_empty (mp - 1))
            paths [directions++] = LEFT;
        
		if (directions) 
		{
            visits--;
            directions = ((unsigned) rand () % directions);
            switch (paths [directions]) 
			{
                case UP:
                    mp->up = TRUE;
                    (mp -= width)->down = TRUE;
                    break;
                case RIGHT:
                    mp->right = TRUE;
                    (++mp)->left = TRUE;
                    break;
                case DOWN:
                    mp->down = TRUE;
                    (mp += width)->up = TRUE;
                    break;
                case LEFT:
                    mp->left = TRUE;
                    (--mp)->right = TRUE;
                    break;
                default:
                    break;
            }
        }
		else 
		{
            do 
			{
                if (++mp > maze_top)
                    mp = maze;
            } while (cell_empty (mp));
        }
    }
}//创建迷宫

void SolveMaze (maze_t maze, int width, int height)  //解迷宫
{
    maze_t *stack, mp = maze;
    int sp = 0;
    stack = (maze_t *) calloc (width * height, sizeof (maze_t));
    if (stack == NULL) 
	{
        (void) fprintf (stderr, "Cannot allocate memory!\n");
        exit (EXIT_FAILURE);
    }
    (stack [sp++] = mp)->visited = TRUE;
    while (mp != (maze + (width * height) - 1)) 
	{
        if (mp->up && !(mp - width)->visited)
            stack [sp++] = mp - width;
        if (mp->right && !(mp + 1)->visited)
            stack [sp++] = mp + 1;
        if (mp->down && !(mp + width)->visited)
            stack [sp++] = mp + width;
        if (mp->left && !(mp - 1)->visited)
            stack [sp++] = mp - 1;
        if (stack [sp - 1] == mp)
            --sp;
        (mp = stack [sp - 1])->visited = TRUE;
    }
    while (sp--)
        if (stack [sp]->visited)
            stack [sp]->path = TRUE;
    free (stack);
}//解迷宫

void PrintMaze (maze_t maze, int width, int height)  //显示迷宫
{
    int w, h;
    char *line, *lp;
    line = (char *) calloc ((width + 1) * 2 * 2, sizeof (char));
    if (line == NULL) 
	{
        (void) fprintf (stderr, "Cannot allocate memory!\n");
        exit (EXIT_FAILURE);
    }
    maze->up = TRUE;
    (maze + (width * height) - 1)->down = TRUE;
   
	for (lp = line, w = 0; w < width; w++) 
	{
        strcpy(lp,"■"),lp+=2;
        if ((maze + w)->up)
            if((maze + w)->path) strcpy(lp,"◎"),lp+=2;
            else strcpy(lp,"  "),lp+=2;
        else
            strcpy(lp,"■"),lp+=2;
    }
    strcpy(lp,"■"),lp+=2;
    (void) puts (line);
   
	for (h = 0; h < height; h++) 
	{
        for (lp = line, w = 0; w < width; w++) 
		{
            if ((maze + w)->left)
				if((maze + w)->path && (maze + w - 1)->path)
					strcpy(lp,"◎"),lp+=2;
				else strcpy(lp,"  "),lp+=2;
            else
                strcpy(lp,"■"),lp+=2;
			if((maze + w)->path) 
				strcpy(lp,"◎"),lp+=2;
			else strcpy(lp,"  "),lp+=2;
        }
        strcpy(lp,"■"),lp+=2;
        (void) puts (line);
        
		for (lp = line, w = 0; w < width; w++) 
		{
            strcpy(lp,"■"),lp+=2;
            if ((maze + w)->down)
                if((maze + w)->path && (h == height - 1 
					||(maze + w + width)->path)) 
					strcpy(lp,"◎"),lp+=2;
				else strcpy(lp,"  "),lp+=2;
            else
                strcpy(lp,"■"),lp+=2;
        }
        
		strcpy(lp,"■"),lp+=2;
        (void) puts (line);
        maze += width;
    }
    free (line);
}//显示迷宫

void RandomGenMaze ()  //自动生成
{             
	maze_t maze;   
	//PrintAGMenu ();
	srand((unsigned)time(0));
	width = rand()%19;		//randomly generate weight, from 0-19
	height = rand()%19;		//randomly generate height, from 0-19
    if (width <= 0 || height <= 0) 
	{
         RandomGenMaze ();	//if '0' is generate out redo RandomGenMaze founction
    }
    
	maze = (maze_t) calloc (width * height, sizeof (cell_t));
    if (maze == NULL) 
	{
        (void) fprintf (stderr, "Cannot allocate memory!\n");
        exit (EXIT_FAILURE);
    }	//check value validity and allocate meomory
	
	printf ("The randomly generated maze looks as below:\n('■'=block)\n\n");
    CreateMaze (maze, width, height);
    PrintMaze (maze, width, height);
    (void) putchar ('\n');
    
	printf ("And follow the dot-line you'll find the solution:\n('■'=block, '◎'=path-print)\n\n");
    SolveMaze (maze, width, height);
    PrintMaze (maze, width, height);

	free(maze);
    printf ("══════════════════════════════════════  \n");
	ContinueMaze ();
	SubOptions ();
}//自动生成

void ManualGenMaze()  //手动生成
{              
	maze_t maze;  
	//PrintMGMenu ();

	printf (" Now you can input its width value('18' is recommended):");
	scanf ("%d", &width);
	if (!width || width <= 0) // 大于100 出现死循环
	{   	
		printf(" Error, illegel width value, press any key to back.");
	    getch();
		ManualGenMaze(); //MazeOptions();  应该可以用while 语句
	}

	printf (" And its height value('18' is recommended):");
	scanf ("%d", &height);

	if (!height|| height <= 0)
	{
		printf(" Error, illegel height value, press any key to back.");
	    getch();
		MazeOptions();
	}
    maze = (maze_t) calloc (width * height, sizeof (cell_t));

    if (maze == NULL) 
	{
        (void) fprintf (stderr, "Cannot allocate memory!\n");
        exit (EXIT_FAILURE);
    }	//check value validity and allocate meomory
	
	printf ("\n The randomly generated maze which was declared manually looks as below:\n ('■'=block)\n\n");
    CreateMaze (maze, width, height);
    PrintMaze (maze, width, height);

    (void) putchar ('\n');
	printf (" And follow the dot-line you'll find the solution:\n ('■'=block, '◎'=path-print)\n\n");
    SolveMaze (maze, width, height);
    PrintMaze (maze, width, height);

	free(maze);//print maze
	printf ("══════════════════════════════════════  \n");
    ContinueMaze ();
    SubOptions ();
}//手动生成

void PrintTitle()
{
	printf("* * * * * * * * * * * * * * * * * * * * * * * *");
	printf("\n-----------------------------------------------\n");
	printf("\n*                  迷宫游戏                  *\n");
	printf("\n-----------------------------------------------\n");
	printf("* * * * * * * * * * * * * * * * * * * * * * * *");

}
//显示标题印象

 
void  PrintMainMenu()
{
	printf("\n\n* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("   --------------主菜单-------------- \n");
	printf("  1 ------- manually generate maze------\n");
	printf("  2 ------- randomly generate a mase by computer-------\n");
	printf("  3 ------- about---------\n");
	printf("  4 ------- exit ---------\n");
	printf("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
}//显示主菜单印象

void PrintSubMenu()
{
	printf("\n\n* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("  1 ------- 回主菜单------\n");
	printf("  2 ------- RandomGenMaze -------\n");
	printf("  3 ------- ManualGenMaze ---------\n");
	printf("  4 ------- exit ---------\n");
	printf("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
}//显示次菜单印象

void PrintAboutMaze ()
{
	printf(" \n   游戏说明 暂时没写 \n");
	ContinueMaze ();
    SubOptions ();
}//显示关于印象




在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值