Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- typedef struct {
- char side;
- char inuse;
- char entry;
- char exit;
- } info;
- typedef struct {
- int rows;
- int cols;
- unsigned char *cells;
- info *lab;
- } Map;
- Map *Constructor(int rows, int collumns);
- void Destructor(Map *map);
- int GetSize(FILE *path);
- int CreateMap(Map *map, FILE *file);
- void PrintHelp();
- int CheckValidityMaze(Map *map);
- int StartValidationCheck(Map *map, int Row, int Col);
- int CheckBorderNum1(Map *map, int FirstSideIndex, int SecondSideIndex);
- int CheckBorderNum2(Map *map, int FirstSideIndex, int SecondSideIndex);
- int CheckBorderNum4(Map *map, int FirstSideIndex, int SecondSideIndex);
- int CheckMazeEntry(Map *map, int R, int Collumns);
- void LeftPath(Map *map, int Rows, int Columns, int Inside);
- void RightPath(Map *map, int Rows, int Columns, int Inside);
- int DirectionFirst(Map *map, int *Rows, int *Columns);
- int DirectionSecond(Map *map, int *Rows, int *Columns);
- int DirectionThird(Map *map, int *Rows, int *Columns);
- void DirectionBack(Map *map, int *Rows, int *Columns);
- bool TestInput(char *file);
- int main(int argc, char *argv[])
- {
- if(argc < 2) {
- fprintf(stderr, "Invalid usage, too few arguments\n");
- PrintHelp();
- return 1;
- }
- if(argc == 2) {
- if(strcmp(argv[1], "--help") == 0) {
- PrintHelp();
- return 0;
- }
- }
- else if(strcmp(argv[1], "--test") == 0) {
- TestInput(argv[2]);
- }
- FILE *file = fopen(argv[4], "r");
- if(file == 0) {
- fprintf(stderr, "File opening failure\n");
- return 1;
- }
- int Rows = GetSize(file);
- int Cols = GetSize(file);
- Map *map = Constructor(Rows, Cols);
- int InitializedMap = CreateMap(map, file);
- if(InitializedMap == 1) {
- fprintf(stderr, "Invalid file to work with\n");
- fclose(file);
- Destructor(map);
- return 1;
- }
- if(map->cells == NULL || map->lab == NULL) {
- Destructor(map);
- fprintf(stderr, "Constructor allocation failure\n");
- if(file != 0) {
- fclose(file);
- }
- return 1;
- }
- if(!CheckValidityMaze(map)) {
- fclose(file);
- Destructor(map);
- fprintf(stderr, "Invalid data in file to work with\n");
- return 1;
- }
- int FindedEnter = StartValidationCheck(map, atoi(argv[2]) - 1, atoi(argv[3]) - 1);
- if(FindedEnter == 0) {
- fclose(file);
- Destructor(map);
- fprintf(stderr, "No access found\n");
- return 1;
- }
- if(strcmp(argv[1], "--rpath") == 0) {
- RightPath(map, atoi(argv[2]) - 1, atoi(argv[3]) - 1, FindedEnter);
- }
- else if(strcmp(argv[1], "--lpath") == 0) {
- LeftPath(map, atoi(argv[2]) - 1, atoi(argv[3]) - 1, FindedEnter);
- }
- else {
- fprintf(stderr, "Wrong argument\n");
- PrintHelp();
- }
- if(file != 0) {
- fclose(file);
- }
- Destructor(map);
- return 0;
- }
- bool TestInput(char *path)
- {
- FILE *file = fopen(path, "r");
- if(file == 0) {
- fprintf(stderr, "Failed to open file");
- return false;
- }
- int Rows = GetSize(file);
- int Cols = GetSize(file);
- Map *map = Constructor(Rows, Cols);
- if(map->cells == NULL || map->lab == NULL) {
- Destructor(map);
- fprintf(stderr, "Constructor allocation failure\n");
- if(file != 0) {
- fclose(file);
- }
- return 1;
- }
- int InitializedMap = CreateMap(map, file);
- if(CheckValidityMaze(map) && (InitializedMap == 0)) {
- fclose(file);
- Destructor(map);
- printf("Is valid\n");
- return 0;
- }
- else {
- fclose(file);
- Destructor(map);
- printf("Is not valid\n");
- return 0;
- }
- }
- Map *Constructor(int rows, int collumns)
- {
- Map *map = (Map *)malloc(sizeof(Map));
- if(map == NULL) {
- fprintf(stderr, "Malloc fail");
- exit(1);
- }
- map->rows = rows;
- map->cols = collumns;
- int MemSize = ((rows * collumns) * sizeof(char));
- map->cells = (unsigned char *)malloc(MemSize);
- if(map->cells == NULL) {
- fprintf(stderr, "Map structure allocation fail");
- free(map);
- exit(1);
- }
- for(int i = 0; i < map->rows; i++) {
- for(int j = 0; j < map->rows; j++) {
- map->cells[i * map->cols] = 'O';
- }
- }
- map->lab = (info *)malloc((rows * collumns) * sizeof(info));
- if(map->lab == NULL) {
- fprintf(stderr, "Help structure allocation fail");
- free(map->cells);
- free(map);
- exit(1);
- }
- return map;
- }
- void Destructor(Map *map)
- {
- free(map->cells);
- free(map->lab);
- }
- //function to get both rows and cols, careful to use it reight
- int GetSize(FILE *path)
- {
- char buff[3] = "\0";
- if(fscanf(path, "%s", buff) == 0) {
- return 0;
- }
- if(buff[0] == '\0') {
- return 0;
- }
- return atoi(buff);
- }
- int CreateMap(Map *map, FILE *file)
- {
- char buff[2];
- int counter = 0;
- int scanned = 0;
- int IterNumber = map->rows * map->cols;
- while(1) {
- scanned = fscanf(file, "%s", buff);
- if((buff[0] < '0') || (buff[0] > '7')) {
- return 1;
- }
- if(counter < IterNumber) {
- map->lab[counter].side = map->cells[counter] = buff[0] - '0';
- }
- scanned != -1 ? counter++ : 0;
- if((scanned == -1) && (counter != IterNumber)) {
- return 1;
- }
- if(scanned == -1) {
- break;
- }
- }
- //setting up initial values to main structure for further job
- for(int i = 0; i < map->rows; i++) {
- for(int j = 0; j < map->cols; j++) {
- map->lab[i * map->cols + j].exit = -1;
- map->lab[i * map->cols + j].entry = -1;
- map->lab[i * map->cols + j].inuse = '\0';
- }
- }
- return 0;
- }
- int StartValidationCheck(Map *map, int Row, int Col)
- {
- //top and bottom pages
- if((Row == 0) || (Row == map->rows -1)) {
- if((Col != 0) || (Col == map->cols - 1)) {
- if(!(map->cells[Row * map->cols + Col] & 4)) {
- return 4;
- }
- if(!(map->cells[Row * map->cols + Col] & 2)) {
- return 1;
- }
- }
- else {
- if(!(map->cells[Row * map->cols + Col] & 2)) {
- return 1;
- }
- else if(!(map->cells[Row * map->cols + Col] & 1)) {
- return 2;
- }
- else if(!(map->cells[Row * map->cols + Col] & 4)) {
- return 4;
- }
- }
- }
- //sides
- if((Col == 0) || (Col == map->cols - 1)) {
- if((Row != 0) || (Row == map->rows - 1)) {
- if(!(map->cells[Row * map->cols + Col] & 1)) {
- return 2;
- }
- else if(!(map->cells[Row * map->cols + Col] & 2)) {
- return 1;
- }
- }
- else {
- if(!(map->cells[Row * map->cols + Col] & 1)) {
- return 2;
- }
- else if(!(map->cells[Row * map->cols + Col] & 2)) {
- return 1;
- }
- else if(!(map->cells[Row * map->cols + Col] & 4)) {
- return 4;
- }
- }
- }
- return 0;
- }
- //0 is false, 1 is true
- int IsBorder(Map *map, int Row, int Col, int Border)
- {
- if(map->lab[Row * map->cols + Col].side & Border) {
- return 1;
- }
- return 0;
- }
- void PrintHelp()
- {
- printf("This is how it works:\n");
- printf("Write --help for printing help\n");
- printf("Type --test <filename> for running test to validation");
- printf("Typed --test - if invalid - prints it");
- printf("Type --rpath R C <filename> R - row and C - column for right-hand mode");
- printf("Type -- lpath R C <filename> R - row and C - column for left-hand mode");
- printf("Thanks for using this amazing app :)");
- }
- //0 is false and 1 is true
- int CheckValidityMaze(Map *map)
- {
- //TODO CHECK THIS
- for(int i = 0; i < map->rows; i++) {
- for(int j = 0; j < map->cols; j++) {
- char Temp = map->cells[i * map->cols + j] - '0';
- if(((Temp & 1) && (!CheckBorderNum1(map, i, j))) ||
- ((Temp & 2) && (!CheckBorderNum2(map, i, j))) ||
- ((Temp & 4) && (!CheckBorderNum4(map, i, j)))) {
- return 0;
- }
- }
- }
- return 1;
- }
- //0 is false, 1 is true
- //TODO JMENA SPRÁVNĚ?
- int CheckBorder1(Map *map, int FirstSideIndex, int SecondSideIndex)
- {
- if((SecondSideIndex == 0) || (map->cells[FirstSideIndex * map->cols + SecondSideIndex - 1] & 2)) {
- return 1;
- }
- else {
- return 0;
- }
- }
- //0 is false, 1 is true
- int CheckBorder2(Map *map, int FirstSideIndex, int SecondSideIndex)
- {
- if((SecondSideIndex == map->cols - 1) || (map->cells[FirstSideIndex * map->cols + SecondSideIndex + 1] & 1)) {
- return 1;
- }
- else {
- return 0;
- }
- }
- //0 is false, 1 is true
- int CheckBorder4(Map *map, int FirstSideIndex, int SecondSideIndex)
- {
- if((FirstSideIndex + SecondSideIndex) & 1) {
- if((FirstSideIndex == map->rows - 1) || (map->cells[(FirstSideIndex + 1) * map->cols + SecondSideIndex] & 4)) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- if((FirstSideIndex == 0) || (map ->cells[(FirstSideIndex - 1) * map->cols + SecondSideIndex] & 4)) {
- return 1;
- }
- else {
- return 0;
- }
- }
- }
- //TODO PŘEHODIT
- int CheckMazeEntry(Map *map, int Rows, int Collumns)
- {
- if((Rows == 0) || (Rows == map->rows - 1)) {
- if((Collumns != 0) || (Collumns == map->cols - 1)) {
- if(!(map->cells[Rows * map->cols + Collumns] & 4)) {
- return 4;
- }
- if(!(map->cells[Rows * map->cols + Collumns] & 2)) {
- return 1;
- }
- }
- else {
- if(!(map->cells[Rows * map->cols + Collumns] & 1)) {
- return 2;
- }
- else if(!(map->cells[Rows * map->cols + Collumns] & 4)) {
- return 4;
- }
- else if(!(map->cells[Rows * map->cols + Collumns] & 2)) {
- return 1;
- }
- }
- }
- if((Collumns == 0) || (Collumns == map->cols - 1)) {
- if((Rows != 0) || (Rows == map->rows - 1)) {
- if(!(map->cells[Rows * map->cols + Collumns] & 1)) {
- //why
- return 2;
- }
- else if(!(map->cells[Rows * map->cols + Collumns] & 2)) {
- return 1;
- }
- }
- else {
- if(!(map->cells[Rows * map->cols + Collumns] & 1)) {
- return 2;
- }
- else if(!(map->cells[Rows * map->cols + Collumns] & 2)) {
- return 2;
- }
- else if(!(map->cells[Rows * map->cols + Collumns] & 4)) {
- return 4;
- }
- }
- }
- return 0;
- }
- //returned 2 means success
- int DirectionFirst(Map *map, int *Rows, int *Columns)
- {
- int Point = *Rows * map->cols + *Columns;
- if(!(map->lab[Point].side & 1) && !(map->lab[Point].inuse & 1)
- && (map->lab[Point].entry != 2)) {
- if(*Columns == 0) {
- return 0;
- }
- if(map->lab[Point - 1].exit == -1) {
- map->lab[Point].exit = map->lab[Point - 1].entry = 1;
- map->lab[Point].inuse |= 1;
- *Columns -= -1;
- return 1;
- }
- }
- return 42;
- }
- int DirectionSecond(Map *map, int *Rows, int *Columns)
- {
- int Point = *Rows * map-> cols + *Columns;
- if(!(map->lab[Point].side & 2) && !(map->lab[Point].inuse & 2)
- && (map->lab[Point].entry != 1)) {
- if(*Columns == map->cols - 1) {
- return 0;
- }
- if(map->lab[Point + 1].exit == -1) {
- map->lab[Point].exit = map->lab[Point + 1].entry = 2;
- map->lab[Point].inuse |= 2;
- *Columns += 1;
- return 2;
- }
- }
- return 42;
- }
- int DirectionThird(Map *map, int *Rows, int *Columns)
- {
- int Point = *Rows * map->cols + *Columns;
- if(!(map->lab[Point].side & 4) && !((*Rows + *Columns) & 1) && !(map->lab[Point].inuse & 4)
- && (map->lab[Point].entry != 4)) {
- if(*Rows == 0) {
- return 0;
- }
- if((map->lab[(*Rows - 1) * map->cols + *Columns].exit == -1)) {
- map->lab[Point].exit = map->lab[(*Rows - 1) * map->cols + *Columns].entry = 4;
- map->lab[Point].inuse |= 4;
- *Rows -= 1;
- return 4;
- }
- }
- if(!(map->lab[Point].side & 4) && ((*Rows + *Columns) & 1) && !(map->lab[Point].inuse & 4)
- && map->lab[Point].entry != 4) {
- if(*Rows == map->rows - 1) {
- return 0;
- }
- if((map->lab[(*Rows + 1) * map->cols + *Columns].exit == -1)) {
- map->lab[Point].exit = map->lab[(*Rows + 1) * map->cols + *Columns].entry = 4;
- map->lab[Point].inuse |= 4;
- *Rows += 1;
- return 4;
- }
- }
- return 42;
- }
- void DirectionBack(Map *map, int *Rows, int *Columns)
- {
- int Point = *Rows * map->cols + *Columns;
- switch(map->lab[Point].entry) {
- case 1:
- *Columns += 1;
- break;
- case 2:
- *Columns -= 1;
- break;
- case 4:
- *Rows += ((*Rows + *Columns) & 1) ? 1 : -1;
- break;
- }
- map->lab[Point].entry = map->lab[Point].exit = -1;
- map->lab[Point].inuse = 0;
- }
- void LeftPath(Map *map, int Rows, int Columns, int Inside)
- {
- int Row = Rows;
- int Col = Columns;
- map->lab[Row * map->cols + Col].entry = Inside;
- while(1) {
- printf("%d, %d\n", Row + 1, Col + 1);
- int Point = Row * map->cols + Col;
- int Result = 0;
- switch(map->lab[Point].entry) {
- case 1:
- if((Row + Col) & 1) {
- Result = DirectionThird(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 4) {
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 1) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 1) {
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 4) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- case 2:
- if((Row + Col) & 1) {
- Result = DirectionSecond(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 2) {
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 4) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 4) {
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 2) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- case 4:
- if((Row + Col) & 1) {
- Result = DirectionFirst(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 1) {
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 2) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 2) {
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if(Result == 0) {
- return;
- }
- if(Result == 1) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- }
- }
- void RightPath(Map *map, int Rows, int Columns, int Inside) {
- int Row = Rows;
- int Col = Columns;
- //setting up the access entrance
- map->lab[Row * map->cols + Col].entry = Inside;
- while (1) {
- //printf out the way
- printf("%i, %i\n", Row + 1, Col + 1);
- int Point = Row * map->cols + Col;
- int Result;
- //in every case there is the if to see how the space is oriented, because it is different in every case
- switch (map->lab[Point].entry) {
- case 1:
- if ((Row + Col) & 1) {
- //the way you go dettermined the way you came
- Result = DirectionFirst(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 1) {
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 4) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 4) {
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 1) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- case 2:
- if ((Row + Col) & 1) {
- Result = DirectionThird(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 4) {
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 2) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 2) {
- break;
- }
- Result = DirectionThird(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 4) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- case 4:
- if ((Row + Col) & 1) {
- Result = DirectionSecond(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 2) {
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 1) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- Result = DirectionFirst(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 1) {
- break;
- }
- Result = DirectionSecond(map, &Row, &Col);
- if (Result == 0) {
- return;
- }
- if (Result == 2) {
- break;
- }
- DirectionBack(map, &Row, &Col);
- break;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement