#include #include #include #include int left(int [][]); int right(int [][]); int up(int [][]); int down(int [][]); int h1(int [][],int [][]); int h2(int [][],int [][]); void print_state(int [][]); void get_state(int [][]); typedef struct stateT { int MOVES[100]; int A_STAR; int NUMBER_OF_MOVES; struct stateT *NEXT; struct stateT *PREVIOUS; }stateT; stateT * search_h1(int [][],int [][]); stateT * search_h2(int [][],int [][]); int main() { int i; int initial_state[3][3],goal_state[3][3]; stateT * state; printf("Input the initial state\n"); get_state(initial_state); printf("Input the goal state\n"); get_state(goal_state); // print_state(initial_state); // printf("\n"); // print_state(goal_state); // printf("The h1 for the initial state is %d\n",h1(initial_state,goal_state)); // printf("The h2 for the initial state is %d\n",h2(initial_state,goal_state)); // state = search_h1(initial_state,goal_state); state = search_h2(initial_state,goal_state); printf("Took %d moves to move from\n",state->NUMBER_OF_MOVES); printf("Initial State\n"); print_state(initial_state); for(i = 0; iNUMBER_OF_MOVES ; i++) { if(state->MOVES[i]==0) { printf("picking left\n"); left(initial_state); print_state(initial_state); } else if(state->MOVES[i]==1) { printf("picking right\n"); right(initial_state); print_state(initial_state); } else if(state->MOVES[i]==2) { printf("picking up\n"); up(initial_state); print_state(initial_state); } else if(state->MOVES[i]==3) { printf("picking down\n"); down(initial_state); print_state(initial_state); } } return 0; } stateT * search_h1(int initial_state[][3],int goal_state[][3]) { int i,j,random_number,state[3][3]; int h1_left,h1_right,h1_up,h1_down,h1_small; stateT *first_state,*low_a_star_state,*test_state,*add_state; int while_count = 1; first_state = malloc(sizeof(stateT)); first_state->NUMBER_OF_MOVES = 0; first_state->NEXT = NULL; first_state->PREVIOUS = NULL; first_state->MOVES[first_state->NUMBER_OF_MOVES] = -1; first_state->A_STAR = h1(initial_state,goal_state); for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) state[i][j] = initial_state[i][j]; while(h1(state,goal_state) != 0) { for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) state[i][j] = initial_state[i][j]; add_state = NULL; low_a_star_state = first_state; test_state = first_state; while(test_state != NULL) { if(test_state->A_STAR < low_a_star_state->A_STAR) { low_a_star_state = test_state; } test_state = test_state->NEXT; } for(i=0 ; iNUMBER_OF_MOVES ; i++) { if(low_a_star_state->MOVES[i] == 0) left(state); else if(low_a_star_state->MOVES[i] == 1) right(state); else if(low_a_star_state->MOVES[i] == 2) up(state); else down(state); // print_state(state); // printf("\n"); } // printf("%d moves to Ending State %d\n",low_a_star_state->NUMBER_OF_MOVES,while_count); // print_state(state); // printf("\n"); if(left(state)) { if(h1(initial_state,state) != 0) { if(low_a_star_state->NUMBER_OF_MOVES == 0 || low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 1) { h1_left = h1(state,goal_state); add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; for(i=0 ; iNUMBER_OF_MOVES ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 0; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_left; if(h1_left == 0) return add_state; } } right(state); } else h1_left = 9; if(right(state)) { if(h1(initial_state,state) != 0) { h1_right = h1(state,goal_state); if(add_state == NULL) { if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 0) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; for(i=0 ; iNUMBER_OF_MOVES ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 1; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_right; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 0) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 1; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_right; } } if(h1_right == 0) return add_state; } left(state); } else h1_right = 9; if(up(state)) { if(h1(initial_state,state) != 0) { h1_up = h1(state,goal_state); if(add_state == NULL) { if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 3) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; for(i=0 ; iNUMBER_OF_MOVES ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 2; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_up; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 3) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 2; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_up; } } if(h1_up == 0) return add_state; } down(state); } else h1_up = 9; if(down(state)) { if(h1(initial_state,state) != 0) { h1_down = h1(state,goal_state); if(add_state == NULL) { if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 2) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; for(i=0 ; iNUMBER_OF_MOVES ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 3; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_down; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 2) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 3; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h1_down; } } if(h1_down == 0) return add_state; } up(state); } else h1_down = 9; h1_small = 9; if(h1_small > h1_left) h1_small = h1_left; if(h1_small > h1_right) h1_small = h1_right; if(h1_small > h1_up) h1_small = h1_up; if(h1_small > h1_down) h1_small = h1_down; srand(time(0)); random_number = rand(); for(i=0 ; i<4 ; i++) { if((h1_left == h1_small) && ((random_number+i)%4 == 0)) { left(state); // printf("picking left\n"); // sleep(15); break; } if((h1_right == h1_small) && ((random_number+i)%4 == 1)) { right(state); // printf("picking right\n"); // sleep(15); break; } if((h1_up == h1_small) && ((random_number+i)%4 == 2)) { up(state); // printf("picking up\n"); // sleep(15); break; } if((h1_down == h1_small) && ((random_number+i)%4 == 3)) { down(state); // printf("picking down\n"); // sleep(15); break; } } // printf("end of while state\n"); // print_state(state); // sleep(15); while_count++; /* test_state = first_state; while(test_state != NULL) { printf("# moves is %d\n",test_state->NUMBER_OF_MOVES); if(test_state->NEXT == NULL) printf("next is indeed null\n"); if(test_state->PREVIOUS == NULL) printf("PREVIOUS is indeed null\n"); for(i=0 ; iNUMBER_OF_MOVES ; i++) printf("move %d is %d\n",i+1,test_state->MOVES[i]); printf("A* is %d\n\n",test_state->A_STAR); test_state = test_state->NEXT; } // sleep(15); */ } } ///// mine stateT * search_h2(int initial_state[][3],int goal_state[][3]) { int i,j,random_number,state[3][3]; int h2_left,h2_right,h2_up,h2_down,h2_small; stateT *first_state,*low_a_star_state,*test_state,*add_state; int while_count = 1; first_state = malloc(sizeof(stateT)); first_state->NUMBER_OF_MOVES = 0; first_state->NEXT = NULL; first_state->PREVIOUS = NULL; first_state->MOVES[first_state->NUMBER_OF_MOVES] = -1; first_state->A_STAR = h2(initial_state,goal_state); for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) state[i][j] = initial_state[i][j]; while(h2(state,goal_state) != 0) { for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) state[i][j] = initial_state[i][j]; add_state = NULL; low_a_star_state = first_state; test_state = first_state; while(test_state != NULL) { if(test_state->A_STAR < low_a_star_state->A_STAR) { low_a_star_state = test_state; } test_state = test_state->NEXT; } for(i=0 ; iNUMBER_OF_MOVES ; i++) { if(low_a_star_state->MOVES[i] == 0) left(state); else if(low_a_star_state->MOVES[i] == 1) right(state); else if(low_a_star_state->MOVES[i] == 2) up(state); else down(state); } // printf("%d moves to Ending State %d\n",low_a_star_state->NUMBER_OF_MOVES,while_count); // print_state(state); // printf("\n"); if(left(state)) { if(h2(initial_state,state) != 0) { if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 1) { h2_left = h2(state,goal_state); add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; // for(i=0 ; iNUMBER_OF_MOVES ; i++) // add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 0; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_left; if(h2_left == 0) return add_state; } } right(state); } else h2_left = 48; if(right(state)) { if(h2(initial_state,state) != 0) { h2_right = h2(state,goal_state); if(add_state == NULL) { if(low_a_star_state->NUMBER_OF_MOVES == 0 || low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 0) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; // for(i=0 ; iNUMBER_OF_MOVES ; i++) // add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 1; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_right; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 0) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 1; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_right; } } if(h2_right == 0) return add_state; } left(state); } else h2_right = 48; if(up(state)) { if(h2(initial_state,state) != 0) { h2_up = h2(state,goal_state); if(add_state == NULL) { if(low_a_star_state->NUMBER_OF_MOVES == 0 || low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 3) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; // for(i=0 ; iNUMBER_OF_MOVES ; i++) // add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 2; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_up; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 3) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 2; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_up; } } if(h2_up == 0) return add_state; } down(state); } else h2_up = 48; if(down(state)) { if(h2(initial_state,state) != 0) { h2_down = h2(state,goal_state); if(add_state == NULL) { if(low_a_star_state->NUMBER_OF_MOVES == 0 || low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-1] != 2) { add_state = low_a_star_state; // add_state->PREVIOUS = low_a_star_state->PREVIOUS; // add_state->NEXT = low_a_star_state->NEXT; // for(i=0 ; iNUMBER_OF_MOVES ; i++) // add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES + 1; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 3; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_down; } } else { low_a_star_state = add_state; if(low_a_star_state->MOVES[low_a_star_state->NUMBER_OF_MOVES-2] != 2) { add_state = malloc(sizeof(stateT)); // add_state->PREVIOUS = low_a_star_state; add_state->NEXT = low_a_star_state->NEXT; // if(low_a_star_state->NEXT != NULL) // low_a_star_state->NEXT->PREVIOUS = add_state; low_a_star_state->NEXT = add_state; for(i=0 ; iNUMBER_OF_MOVES-1 ; i++) add_state->MOVES[i] = low_a_star_state->MOVES[i]; add_state->NUMBER_OF_MOVES = low_a_star_state->NUMBER_OF_MOVES; add_state->MOVES[add_state->NUMBER_OF_MOVES - 1] = 3; add_state->A_STAR = add_state->NUMBER_OF_MOVES + h2_down; } } if(h2_down == 0) return add_state; } up(state); } else h2_down = 48; h2_small = 48; if(h2_small > h2_left) h2_small = h2_left; if(h2_small > h2_right) h2_small = h2_right; if(h2_small > h2_up) h2_small = h2_up; if(h2_small > h2_down) h2_small = h2_down; srand(time(0)); random_number = rand(); for(i=0 ; i<4 ; i++) { if((h2_left == h2_small) && ((random_number+i)%4 == 0)) { left(state); // sleep(15); break; } if((h2_right == h2_small) && ((random_number+i)%4 == 1)) { right(state); // sleep(15); break; } if((h2_up == h2_small) && ((random_number+i)%4 == 2)) { up(state); // sleep(15); break; } if((h2_down == h2_small) && ((random_number+i)%4 == 3)) { down(state); // sleep(15); break; } } while_count++; /* test_state = first_state; while(test_state != NULL) { printf("# moves is %d\n",test_state->NUMBER_OF_MOVES); if(test_state->NEXT == NULL) printf("next is indeed null\n"); if(test_state->PREVIOUS == NULL) printf("PREVIOUS is indeed null\n"); for(i=0 ; iNUMBER_OF_MOVES ; i++) printf("move %d is %d\n",i+1,test_state->MOVES[i]); printf("A* is %d\n\n",test_state->A_STAR); test_state = test_state->NEXT; } */ } } int left(int state[][3]) { int i,j,temp,zero=0; for(i=0 ; i<3 && !zero ; i++) for(j=0 ; j<3 && !zero ; j++) if(state[i][j] == 0) zero = 1; i--; j--; if(j != 0) { temp = state[i][j-1]; state[i][j-1] = state[i][j]; state[i][j] = temp; return 1; } else return 0; } int right(int state[][3]) { int i,j,temp,zero=0; for(i=0 ; i<3 && !zero ; i++) for(j=0 ; j<3 && !zero ; j++) if(state[i][j] == 0) zero = 1; i--; j--; if(j != 2) { temp = state[i][j+1]; state[i][j+1] = state[i][j]; state[i][j] = temp; return 1; } else return 0; } int up(int state[][3]) { int i,j,temp,zero=0; for(i=0 ; i<3 && !zero ; i++) for(j=0 ; j<3 && !zero ; j++) if(state[i][j] == 0) zero = 1; i--; j--; if(i != 0) { temp = state[i-1][j]; state[i-1][j] = state[i][j]; state[i][j] = temp; return 1; } else return 0; } int down(int state[][3]) { int i,j,temp,zero=0; for(i=0 ; i<3 && !zero ; i++) for(j=0 ; j<3 && !zero ; j++) if(state[i][j] == 0) zero = 1; i--; j--; if(i != 2) { temp = state[i+1][j]; state[i+1][j] = state[i][j]; state[i][j] = temp; return 1; } else return 0; } int h1(int initial_state[][3],int goal_state[][3]) { int i,j; int num_out_of_position=0; for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) if(initial_state[i][j] != 0) if(initial_state[i][j] != goal_state[i][j]) num_out_of_position++; return num_out_of_position; } int h2(int initial_state[][3],int goal_state[][3]) { int i,j,k,l,same; int city_block_distance=0; for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) { same = 0; for(k=0 ; k<3 && !same ; k++) for(l=0 ; l<3 && !same ; l++) if((initial_state[i][j] !=0) && (initial_state[i][j] == goal_state[k][l])) same = 1; if(same) city_block_distance += abs(i-(--k)) + abs(j-(--l)); } return city_block_distance; } void print_state(int state[][3]) { int i,j; for(i=0 ; i<3 ; i++) { for(j=0 ; j<3 ; j++) printf("%d ",state[i][j]); printf("\n"); } } void get_state(int state[][3]) { int i,j; for(i=0 ; i<3 ; i++) for(j=0 ; j<3 ; j++) { printf("Input element [%d][%d] of the state:\n",i+1,j+1); scanf("%d",&state[i][j]); } }