Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Solve The Maze
- // V0.0.2
- //
- // Date: 2018.06.21
- // (Based on: https://symbolsprogrammingblog.wordpress.com/2010/06/20/%D7%9E%D7%A6%D7%99%D7%90%D7%AA-%D7%94%D7%93%D7%A8%D7%9A-%D7%94%D7%A7%D7%A6%D7%A8%D7%94-%D7%91%D7%99%D7%95%D7%AA%D7%A8-%D7%91%D7%9E%D7%91%D7%95%D7%9A/ )
- #include <stdio.h>
- #include <time.h>
- #define HEIGHT 50
- #define WIDTH 9
- #define WALL -1
- #define PATH 0
- #define START 83 // 'S'
- #define END 69 // 'E'
- #define ARROW 176
- #define UP 30
- #define DOWN 40
- #define RIGHT 50
- #define LEFT 60
- #define true 1
- #define false 0
- typedef int Boolean;
- struct Point {
- int Row;
- int Column;
- };
- int SolveMaze(int Maze[HEIGHT][WIDTH]);
- struct Point FindStartingPoint(int Maze[HEIGHT][WIDTH]);
- struct Point FindStartingPathPoint(int Maze[HEIGHT][WIDTH]);
- int SolveMazeREC(int Maze[HEIGHT][WIDTH], int h, int w, Boolean saveChanges);
- void ShowBoard(int Board[HEIGHT][WIDTH]);
- void CopyBoard(int targetBoard[HEIGHT][WIDTH], int sourceBoard[HEIGHT][WIDTH]);
- // This function try to solve the maze with minimum steps.
- //
- // If succeeded - fill the given board with 'ARROW' in the path that is found,
- // and return the number of steps.
- // If failed - return -1
- int SolveMaze(int Maze[HEIGHT][WIDTH])
- {
- int h, w;
- int steps = 2;
- int lowestSteps = -1;
- int lowestStepsSide = DOWN;
- int NewMaze[HEIGHT][WIDTH];
- int tmp;
- struct Point startingPathPoint;
- struct Point startingPoint;
- // Search start position
- startingPathPoint = FindStartingPathPoint(Maze);
- startingPoint = FindStartingPoint(Maze);
- h = startingPathPoint.Row;
- w = startingPathPoint.Column;
- // So the START position will not bother us
- Maze[startingPoint.Row][startingPoint.Column] = ARROW;
- Maze[h][w] = ARROW;
- // UP
- if (Maze[h-1][w] != WALL && Maze[h-1][w] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h-1, w, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = UP;
- }
- }
- // DOWN
- if (Maze[h+1][w] != WALL && Maze[h+1][w] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h+1, w, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = DOWN;
- }
- }
- // RIGHT
- if (Maze[h][w+1] != WALL && Maze[h][w+1] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h, w+1, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = RIGHT;
- }
- }
- // LEFT
- if (Maze[h][w-1] != WALL && Maze[h][w-1] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h, w-1, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = LEFT;
- }
- }
- // (If all directions are blocked, lowestSteps = -1)
- if (lowestSteps == -1)
- {
- // Reset the START position // (We dont realy need this here)
- Maze[startingPoint.Row][startingPoint.Column] = START;
- return -1;
- }
- else
- {
- switch(lowestStepsSide)
- {
- case UP :
- SolveMazeREC(NewMaze, h-1, w, true, Maze);
- break;
- case DOWN :
- SolveMazeREC(NewMaze, h+1, w, true, Maze);
- break;
- case RIGHT :
- SolveMazeREC(NewMaze, h, w+1, true, Maze);
- break;
- case LEFT :
- SolveMazeREC(NewMaze, h, w-1, true, Maze);
- break;
- }
- // Reset the START position
- Maze[startingPoint.Row][startingPoint.Column] = START;
- return steps + lowestSteps;
- }
- }
- struct Point FindStartingPoint(int Maze[HEIGHT][WIDTH])
- {
- int startRow;
- int startColumn;
- struct Point StartingPoint;
- for (startRow = 0; startRow < HEIGHT; startRow++)
- {
- for (startColumn = 0; startColumn < WIDTH; startColumn++)
- {
- if (Maze[startRow][startColumn] == START)
- {
- StartingPoint.Column = startColumn;
- StartingPoint.Row = startRow;
- return StartingPoint;
- }
- }
- }
- printf("Error in FindStartingPoint\n");
- return StartingPoint;
- }
- struct Point FindStartingPathPoint(int Maze[HEIGHT][WIDTH])
- {
- struct Point StartingPathPoint;
- StartingPathPoint = FindStartingPoint(Maze);
- if (Maze[StartingPathPoint.Row + 1][StartingPathPoint.Column] == PATH)
- {
- StartingPathPoint.Row += 1;
- return StartingPathPoint;
- }
- else if (Maze[StartingPathPoint.Row - 1][StartingPathPoint.Column] == PATH)
- {
- StartingPathPoint.Row -= 1;
- return StartingPathPoint;
- }
- else if (Maze[StartingPathPoint.Row][StartingPathPoint.Column + 1] == PATH)
- {
- StartingPathPoint.Column += 1;
- return StartingPathPoint;
- }
- else if (Maze[StartingPathPoint.Row][StartingPathPoint.Column - 1] == PATH)
- {
- StartingPathPoint.Column -= 1;
- return StartingPathPoint;
- }
- else
- {
- printf("Error in FindStartingPathPoint\n");
- return StartingPathPoint;
- }
- }
- int SolveMazeREC(int Maze[HEIGHT][WIDTH], int h, int w, Boolean saveChanges, int MainMaze[HEIGHT][WIDTH])
- {
- int lowestSteps = -1;
- int NewMaze[HEIGHT][WIDTH];
- int lowestStepsSide = DOWN;
- int tmp;
- // -- END
- if (Maze[h][w] == END)
- return 1;
- Maze[h][w] = ARROW;
- if (saveChanges == true)
- {
- MainMaze[h][w] = ARROW;
- }
- // UP
- if (Maze[h-1][w] != WALL && Maze[h-1][w] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h-1, w, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = UP;
- }
- }
- // DOWN
- if (Maze[h+1][w] != WALL && Maze[h+1][w] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h+1, w, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = DOWN;
- }
- }
- // RIGHT
- if (Maze[h][w+1] != WALL && Maze[h][w+1] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h, w+1, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = RIGHT;
- }
- }
- // LEFT
- if (Maze[h][w-1] != WALL && Maze[h][w-1] != ARROW)
- {
- CopyBoard(NewMaze, Maze);
- tmp = SolveMazeREC(NewMaze, h, w-1, false, NULL);
- if (tmp != -1)
- if (tmp < lowestSteps || lowestSteps == -1)
- {
- lowestSteps = tmp;
- lowestStepsSide = LEFT;
- }
- }
- Maze[h][w] = PATH;
- if (saveChanges == true)
- {
- if (lowestSteps != -1)
- {
- switch(lowestStepsSide)
- {
- case UP :
- SolveMazeREC(NewMaze, h-1, w, true, MainMaze);
- break;
- case DOWN :
- SolveMazeREC(NewMaze, h+1, w, true, MainMaze);
- break;
- case RIGHT :
- SolveMazeREC(NewMaze, h, w+1, true, MainMaze);
- break;
- case LEFT :
- SolveMazeREC(NewMaze, h, w-1, true, MainMaze);
- break;
- }
- }
- }
- // (If all directions are blocked, lowestSteps = -1)
- if (lowestSteps == -1)
- {
- return -1;
- }
- else
- {
- return 1 + lowestSteps;
- }
- }
- void ShowBoard(int Board[HEIGHT][WIDTH])
- {
- int row;
- int col;
- printf("Full maze:\n\n\n");
- for (row = 0; row < HEIGHT; row++) // Loop through every row
- {
- for (col = 0; col < WIDTH; col++) // And every column
- {
- switch(Board[row][col])
- {
- case WALL :
- putchar('\xDB');
- break;
- case PATH :
- putchar(' ');
- break;
- case ARROW :
- putchar(ARROW);
- break;
- case START :
- putchar(START);
- break;
- case END :
- putchar(END);
- break;
- default :
- putchar('?');
- break;
- }
- }
- putchar('\n');
- }
- printf("\n\n\n");
- }
- void CopyBoard(int targetBoard[HEIGHT][WIDTH], int sourceBoard[HEIGHT][WIDTH])
- {
- int i, j;
- for (i = 0; i < HEIGHT; i++)
- {
- for (j = 0; j < WIDTH; j++)
- {
- targetBoard[i][j] = sourceBoard[i][j];
- }
- }
- }
- void InitializeTheMaze(int Board[HEIGHT][WIDTH])
- {
- int TmpBoard[HEIGHT][WIDTH] = {
- { WALL , WALL , START, WALL, WALL , WALL , WALL , WALL , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , PATH , WALL , WALL , WALL },
- { WALL , PATH , WALL , PATH, WALL , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , PATH, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , WALL , WALL , WALL , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, PATH , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , WALL , PATH , WALL },
- { WALL , WALL , PATH , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , PATH , WALL , WALL , WALL },
- { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , WALL, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , WALL , PATH , WALL , WALL },
- { WALL , PATH , PATH , PATH, WALL , WALL , PATH , WALL , WALL },
- { WALL , WALL , WALL , PATH, WALL , WALL , PATH , WALL , WALL },
- { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL },
- { WALL , WALL , WALL , PATH, WALL , WALL , PATH , PATH , WALL },
- { WALL , PATH , PATH , PATH, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , WALL, PATH , WALL , PATH , WALL , WALL },
- { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , WALL , PATH , WALL , WALL },
- { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , WALL, WALL , WALL , PATH , WALL , WALL },
- { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL },
- { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL },
- { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL },
- { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL },
- { WALL , PATH , PATH , WALL, WALL , WALL , PATH , PATH , WALL },
- { WALL , END , WALL , WALL, WALL , WALL , WALL , WALL , WALL },
- };
- CopyBoard(Board, TmpBoard);
- }
- int main()
- {
- int Board[HEIGHT][WIDTH];
- int Steps;
- clock_t begin, end;
- double time_spent;
- InitializeTheMaze(Board);
- printf("* Start:\n\n");
- ShowBoard(Board);
- printf("* Program Answer:\n\n");
- begin = clock();
- Steps = SolveMaze(Board);
- end = clock();
- time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
- if (Steps != -1) // Path found
- {
- printf("Number of steps: %d\n-----------------------\n", Steps);
- ShowBoard(Board);
- }
- else
- {
- printf("Maze cannot be solved! :(\n\n");
- }
- printf("Time: %lf Seconds\n", time_spent);
- getchar();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement