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"); */
}
Exemplo n.º 2
0
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;
}