• [C/C++] 随机迷宫与解法


    来源:http://www.gamedev.net/reference/articles/article1637.asp

    /*
    * MazeGen.c -- Mark Howell -- 8 May 1991
    *
    * Usage: MazeGen [width [height [seed]]]
    */
    #include
    <stdio.h>
    #include
    <stdlib.h>
    #include
    <time.h>

    #define WIDTH 39
    #define HEIGHT 11

    #define UP 0
    #define RIGHT 1
    #define DOWN 2
    #define LEFT 3
    #ifdef TRUE
    #undef TRUE
    #endif /* TRUE */

    #define TRUE 1

    #define cell_empty(a) (!(a)->up && !(a)->right && !(a)->down && !(a)->left)

    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 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);

    int main (int argc, char *argv [])
    {
    int width = WIDTH;
    int height = HEIGHT;
    maze_t maze;

    if (argc >= 2)
    width
    = atoi (argv [1]);

    if (argc >= 3)
    height
    = atoi (argv [2]);

    if (argc >= 4)
    srand (atoi (argv [
    3]));
    else
    srand ((
    int) time ((time_t *) NULL));

    if (width <= 0 || height <= 0) {
    (
    void) fprintf (stderr, "Illegal width or height value!\n");
    exit (EXIT_FAILURE);
    }
    maze
    = (maze_t) calloc (width * height, sizeof (cell_t));
    if (maze == NULL) {
    (
    void) fprintf (stderr, "Cannot allocate memory!\n");
    exit (EXIT_FAILURE);
    }
    CreateMaze (maze, width, height);

    PrintMaze (maze, width, height);

    (
    void) putchar ('\n');

    SolveMaze (maze, width, height);

    PrintMaze (maze, width, height);

    free (maze);
    exit (EXIT_SUCCESS);

    return (0);

    }
    /* main */


    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));
    }
    }
    }
    /* CreateMaze */


    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);

    }
    /* SolveMaze */


    void PrintMaze (maze_t maze, int width, int height)
    {
    int w, h;
    char *line, *lp;

    line
    = (char *) calloc ((width + 1) * 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++) {
    *lp++ = '+';
    if ((maze + w)->up)
    *lp++ = ((maze + w)->path) ? '.' : ' ';
    else
    *lp++ = '-';
    }
    *lp++ = '+';
    (
    void) puts (line);
    for (h = 0; h < height; h++) {
    for (lp = line, w = 0; w < width; w++) {
    if ((maze + w)->left)
    *lp++ = ((maze + w)->path && (maze + w - 1)->path) ? '.' : ' ';
    else
    *lp++ = '|';
    *lp++ = ((maze + w)->path) ? '.' : ' ';
    }
    *lp++ = '|';
    (
    void) puts (line);
    for (lp = line, w = 0; w < width; w++) {
    *lp++ = '+';
    if ((maze + w)->down)
    *lp++ = ((maze + w)->path && (h == height - 1 ||
    (maze
    + w + width)->path)) ? '.' : ' ';
    else

    *lp++ = '-';
    }
    *lp++ = '+';
    (
    void) puts (line);
    maze
    += width;
    }
    free (line);

    }
    /* PrintMaze */
    个性签名:做要做好,做到不三不四不如不做。
  • 相关阅读:
    感动女友的话
    情侣一起玩的游戏
    让妹子被我征服
    调戏妹子 微信聊天
    sqlserver2008 解决 ldf文件过大的方法
    sqlserver 动态表名 动态字段名 执行 动态sql
    sqlserver convert 日期时间 转换格式化
    sqlserver 2008 卸载时提示 “重新启动计算机”失败
    sqlserver mdf ldf文件导入
    myeclipse trial expired[转]
  • 原文地址:https://www.cnblogs.com/hcbin/p/1860778.html
Copyright © 2020-2023  润新知