void BFS(int end_row, int end_col) { while(Qhead < Qtail) { /* printQ(); */ Node *current = popQ(); if(current->row == end_row && current->col == end_col) return; int i=0; int array[4] = {NORTH, WEST, EAST, SOUTH}; for(i=0 ; i<4 ; i++){ if(current->linked[array[i]] == 1){ if(array[i]==EAST){ pushQ(current, &maze[current->row][current->col + 1][WEST]); } else if(array[i]==SOUTH){ pushQ(current, &maze[current->row + 1][current->col][NORTH]); } else if(array[i]==WEST){ pushQ(current, &maze[current->row][current->col - 1][EAST]); } else if(array[i]==NORTH) { pushQ(current, &maze[current->row - 1][current->col][SOUTH]); } else fprintf(stderr, "WTF?\n"); } } } /* printf("Q runs out!\n"); */ }
int main(int numargs, char *args[]){ //should have either 4, 5, 6, or 7 arguments //if 7, [1] must be -r, [2,3,4] must be ints, initial and goal are letters //if 6, must not include -r, include all else //if 5 must include -r and not height OR width //if 4, must have int for maxlength and letters for other, and nothing else //height and width are ints between 2 and 5 (Default is 3) //maxlength is non-negative int (can be 0) //INITIAL and GOAL have the necessary number of letters for the size of the tray //letters between only A and L (duplicates ok) int width = 3; //width of the tray, default is 3 int height = 3; //height of the tray, default is 3 int maxlength = -1; //maxlength of the pattern int tilelen; //number of tiles char *temp; bool flag; //true is -r is specified bool used; char *initial; //initial position char *goal; //goal position //if all the command-line args follow the rules for 4 args if((numargs == 4) && checkNum(args[1]) && checkTiles(args[2], args[3])){ maxlength = (int)strtol(args[1], &temp, 10); tilelen = strlen(args[2]); flag = false; //no flag present initial = args[2]; goal = args[3]; } //if all the command-line args follow the rules for 5 args else if((numargs == 5) && checkFlag(args[1]) && checkNum(args[2]) && checkTiles(args[3], args[4])){ maxlength = (int)strtol(args[2], &temp, 10); tilelen = strlen(args[3]); flag = true; //flag present initial = args[3]; goal = args[4]; } //if all the command-line args follow the rules for 6 args else if((numargs == 6) && checkNum(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkTiles(args[4], args[5])){ height = (int)strtol(args[1], &temp, 10); width = (int)strtol(args[2], &temp, 10); maxlength = (int)strtol(args[3], &temp, 10); tilelen = strlen(args[4]); flag = false; //no flag present initial = args[4]; goal = args[5]; } //if all the command-line args follow the rules for 7 args else if((numargs == 7) && checkFlag(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkNum(args[4]) && checkTiles(args[5], args[6])){ height = (int)strtol(args[2], &temp, 10); width = (int)strtol(args[3], &temp, 10); maxlength = (int)strtol(args[4], &temp, 10); tilelen = strlen(args[5]); flag = true; //flag present initial = args[5]; goal = args[6]; } else{//invalid command line args fprintf(stderr, "Invalid command line arguments\n"); exit(1); } if((height >= 2) && (height <= 5) && (width >= 2) && (width <= 5) && (tilelen == height*width)){} else{//if the height and width aren't right, then quit fprintf(stderr, "Invalid command line arguments\n"); exit(1); } Stack q1; //create the two stacks for the queue Stack q2; createS(&q1); createS(&q2); char *nextStr; //holds what is popped off queue 'P' int nextLen; //holds the length of P Trie root; //root of the trie dictionary root.len = -1; root.from = NULL; for(int k = 0; k < 12; k++) root.children[k] = NULL; insert(&root, goal, NULL, 0); //insert root in queue & dictionary pushS(&q1, goal); if(!(strcmp(goal, initial))){ //if goal is initial printf("%s\n", initial); destroyS(&q1); destroyS(&q2); return 0; } while(!(isEmptyS(&q1) && isEmptyS(&q2))){ //while queue not empty popQ(&q1, &q2, &nextStr); nextLen = lenInTrie(&root, nextStr); used = false; if(nextLen < maxlength){ //generate all the possible tiles for(int c = 0; c < width; c++){ //for all column shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < width; sh++){ char *nextTiles = shiftC(nextStr, height, width, c, height - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftC(nextStr, height, width, c, height - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } for(int r = 0; r < height; r++){//for all possible row shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < height; sh++){ char *nextTiles = shiftR(nextStr, height, width, r, width - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftR(nextStr, height, width, r, width - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } } if(!used) free(nextStr); }//end of while queue is not empty destroyS(&q1); destroyS(&q2); return 0; }