简体   繁体   English

指针二进制树迷宫解算器在C

[英]Pointers Binary Tree Maze Solver in C

I need to create a Robot Simulator programmed in C. The Robot has to find the Exit of a 2d labirinth using a Recursive Backtracker algorithm, i understood how does this algorithm work but i don't know how to implement it. 我需要创建一个用C语言编写的机器人模拟器。机器人必须使用递归回溯算法找到2d labirinth的出口,我知道这个算法是如何工作的,但我不知道如何实现它。 I Think i can use a Binary Tree using Pointers but i don't know how to do this, can you try to explain it to me? 我想我可以使用指针使用二叉树,但我不知道如何做到这一点,你能尝试向我解释一下吗?

This is the program that i've created, now the Robot is entering a loop because of the method that changes direction 这是我创建的程序,现在机器人正在进入一个循环,因为改变方向的方法

#ifdef __unix__
#include <unistd.h>
#elif defined _WIN32
#include <windows.h>
#define sleep(x) Sleep(1000 * x)
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void goUp();
void goDown();
void goLeft();
void goRight();

typedef struct robot {
    int direction;
    bool is_moving;
}robot;

typedef struct room {
    robot robot;
    bool is_robot;
    int obstacle;

}room;

room Room[20][20];
int r = 12;
int c = 10;

void generation(room matrix[20][20])
{
    srand(time(NULL));
    int x,i,j;
    x=0;
    for(i=0;i<20;i++)
    {
        for(j=0;j<20;j++)
        {
            matrix[i][j].is_robot=false;
            x=rand()%100+1;
            if(x==1||x==50||x==100)
            {
                matrix[i][j].obstacle=1;
            }
            else
            {
                matrix[i][j].obstacle=0;
            }
        }
    }
}

void print_matrix(room matrix[20][20])
{
    int i,j;

    for(i=0;i<20;i++)
    {
        for(j=0;j<20;j++)
        {
            if(matrix[i][j].obstacle==0)
            {
                if(matrix[i][j].is_robot==true)
                {
                    printf("I");
                }
                else
                {
                    printf(" ");
                }
            }
            else
            {
                if(matrix[i][j].is_robot==true)
                {
                    printf("I");
                }
                else
                {
                    printf("o");
                }
            }
        }
        printf("\n");
    }
}

bool changeDirection(room Room[20][20],int i,int j)
{
    if(Room[i][j].robot.direction == 1)
    {
        if(Room[i-1][j].obstacle == 1 || i-1 ==  0)
        {
            if(Room[i+1][j].obstacle == 1 || i+1 == 19)
            {
                Room[i][j].robot.direction = 2;
                return true;
            }
            else
            {
                Room[i][j].robot.direction = 4;
                return true;
            }

        }
        else
        {
            Room[i][j].robot.direction = 3;
            return true;
        }
    }



    if(Room[i][j].robot.direction == 2)
    {
        if(Room[i-1][j].obstacle == 1 || i-1 ==  0)
        {
            if(Room[i+1][j].obstacle == 1 || i+1 ==  19)
            {
                Room[i][j].robot.direction = 1;
                return true;
            }
            else
            {
                Room[i][j].robot.direction = 4;
                return true;
            }

        }
        else
        {
            Room[i][j].robot.direction = 3;
            return true;
        }
    }


    if(Room[i][j].robot.direction == 3)
    {
        if(Room[i][j+1].obstacle == 1 || j+1 ==  19)
        {
            if(Room[i][j-1].obstacle == 1 || j-1 ==  0)
            {
                Room[i][j].robot.direction = 4;
                return true;
            }
            else
            {
                Room[i][j].robot.direction = 2;
                return true;
            }

        }
        else
        {
            Room[i][j].robot.direction = 1;
            return true;
        }
    }

    if(Room[i][j].robot.direction == 4)
    {
        if(Room[i][j+1].obstacle == 1 || j+1 ==  19)
        {
            if(Room[i][j-1].obstacle == 1 || j-1 ==  0)
            {
                Room[i][j].robot.direction = 3;
                return true;
            }
            else
            {
                Room[i][j].robot.direction = 2;
                return true;
            }

        }
        else
        {
            Room[i][j].robot.direction = 1;
            return true;
        }
    }
}

void goRight()
{
    c=c+1;
    Room[r][c].robot.direction=1;
    Room[r][c].is_robot=true;
    Room[r][c-1].is_robot=false;
}

void goLeft()
{
    c=c-1;
    Room[r][c].robot.direction=2;
    Room[r][c].is_robot=true;
    Room[r][c+1].is_robot=false;
}

void goUp()
{
    r=r-1;
    Room[r][c].robot.direction=3;
    Room[r][c].is_robot=true;
    Room[r+1][c].is_robot=false;
}
void goDown()
{
    r=r+1;
    Room[r][c].robot.direction=4;
    Room[r][c].is_robot=true;
    Room[r-1][c].is_robot=false;
}

int main()
{

    generation(Room);
    Room[r][c].robot.direction = 1;
    Room[r][c].robot.is_moving = true;
    Room[r][c].is_robot = true;

    do
    {
        Room[r][c].robot.is_moving = true;
        if (Room[r][c].robot.direction == 1 && Room[r][c].robot.is_moving == true) // destra
        {
            if(Room[r][c    +1].obstacle == 1 || c+1 == 19)
            {

                changeDirection(Room,r,c);
            }
            else
            {
                goRight();
            }
        }

        if (Room[r][c].robot.direction == 2 && Room[r][c].robot.is_moving == true) // sinistra
        {
            if(Room[r][c   -1].obstacle == 1 || c-1 == 0)
            {
                changeDirection(Room,r,c);
            }
            else
            {
                goLeft();
            }
        }

        if (Room[r][c].robot.direction == 3 && Room[r][c].robot.is_moving == true) // su
        {
            if(Room[r-1][c].obstacle == 1 || r-1 == 0)
            {
                changeDirection(Room,r,c);
            }
            else
            {
                goUp();
            }
        }

        if (Room[r][c].robot.direction == 4 && Room[r][c].robot.is_moving == true) // giu
        {
            if(Room[r+1][c].obstacle == 1 || r+1 == 19)
            {
                changeDirection(Room,r,c);
            }
            else
            {
                goDown();
            }
        }

        print_matrix(Room);
        sleep(0.1);
        system("cls");

    }
    while(1);
    print_matrix(Room);
}

I'm having a hard time understanding how a binary tree would be useful in finding a path in a labyrinth (maybe it's used to represent the labyrinth?) but maybe I'm blind. 我很难理解二叉树如何在迷宫中找到一条路径(也许它用来代表迷宫?)但也许我是盲目的。 I would simply make a 2d int array and let 0 mean the position is blocked (there's a wall there or something) and 1 mean it's open (you can move there). 我只是制作一个2d int数组,让0意味着位置被阻挡(那里有一堵墙或其他东西)和1意味着它是开放的(你可以移动那里)。 The brute force backtrack procedure, going off orthogonal movement (left, right, up, down) would be: 蛮力回溯程序,正常运动(左,右,上,下)将是:

f(x,y){
    // you found the place your want to go to
    if (x,y) is (destinationX,destinationY) 
        return true

    block the position (x,y) // i.e. mark current position as visited

    if there is an open spot at (x,y-1) AND f(x,y-1)
        return true
    if there is an open spot at (x,y+1) AND f(x,y+1)
        return true
    if there is an open spot at (x-1,y) AND f(x-1,y)
        return true
    if there is an open spot at (x+1,y) AND f(x+1,y)
        return true

    return false
}

Suppose you had the labyrinth looking like: 假设你的迷宫看起来像:

"+" is where you start ([1][1])
"-" is your destination ([3][1])
"#" is a blocked region

===========
|#|#|#|#|#|
|#|+| |#|#|
|#|#| |#|#|
|#|-| | |#|
|#|#|#|#|#|
===========

Using the above idea I have: 使用上述想法我有:

#include <stdio.h>
#define width 5
#define height 5

// print maze
void print(char arr[][width]){
    for (int i = 0; i < 2*width+1; i++) printf("=");
    printf("\n");
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            printf("|%c",arr[i][j]);
        }
        printf("|\n");
    }
    for (int i = 0; i < 2*width+1; i++) printf("=");
}


// starting from (x,y) to (destX,destY)
int path(int arr[][width],int x,int y,int destX,int destY,char toDest[][width]){
    if (x==destX && y==destY) {
        toDest[y][x] = '*';
        print(toDest);
        return 1;
    }
    // mark current position as visited
    arr[y][x] = 0;
    toDest[y][x] = '*';

    // left
    if (arr[y][x-1] && path(arr,x-1,y,destX,destY,toDest))
        return 1;

    // right
    if (arr[y][x+1] && path(arr,x+1,y,destX,destY,toDest))
        return 1;

    // up
    if (arr[y-1][x] && path(arr,x,y-1,destX,destY,toDest))
        return 1;

    // down
    if (arr[y+1][x] && path(arr,x,y+1,destX,destY,toDest))
        return 1;

    return 0;
}


int main () {
    // use this to store path
    // and then print it out if found
    char toDest[height][width] = {
            {'#','#','#','#','#'},
            {'#',' ',' ','#','#'},
            {'#','#',' ','#','#'},
            {'#',' ',' ',' ','#'},
            {'#','#','#','#','#'}
    };

    // 0 -> position is blocked
    // 1 -> position is open
    int maze[height][width] = {
            {0,0,0,0,0},
            {0,1,1,0,0},
            {0,0,1,0,0},
            {0,1,1,1,0},
            {0,0,0,0,0}
    };

    path(maze,1,1,1,3,toDest);
}

Output: 输出:

===========
|#|#|#|#|#|
|#|*|*|#|#|
|#|#|*|#|#|
|#|*|*| |#|
|#|#|#|#|#|
===========

In output the path is designated by the * s 在输出中,路径由* s指定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM