3D Word Search Puzzle

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 13

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.

h> //This function flushes the input so that any subsquent read operation on an inp ut stream reads new data from the associated stream void flushall() { char junk[80]; gets(junk); } // This function gets the coordinates from the user, checks them for errors, an d returns them as a pointer to an int 1 dimensional array containing them // dimgrid is the dimensions of the grid int *Getcoords(int *dimgrid) { int rowf = 0, colf = 0, layerf = 0, rowe = 0, cole = 0, layere = 0, coords[6 ]; while(1) { printf("Start guess? "); int x = scanf("%d", &rowf); if(x != 1) { flushall(); continue; } if(rowf == 0) { printf("You chose to quit\n"); coords[0] = -1; return coords; } x = scanf(" %d %d", &colf, &layerf); if(x != 2) { flushall(); printf("Please enter valid coordinates with spaces between each one\ n"); continue; } if((rowf > dimgrid[0] || rowf < 1) || (colf > dimgrid[1] || colf < 1) || (layerf > dimgrid[2] || layerf < 1)) { printf("Please enter valid coordinates with spaces between each one\ n"); flushall(); continue; } else break; } while(1) { printf("End guess? "); int x = scanf("%d %d %d", &rowe, &cole, &layere); if(x != 3) { flushall(); printf("Please enter valid coordinates with spaces between each one\

n"); continue; } if((rowe > dimgrid[0] || rowe < 1) || (cole > dimgrid[1] || cole < 1) || (layere > dimgrid[2] || layere < 1)) { printf("Please enter valid coordinates with spaces between each one\ n"); flushall(); continue; } else break; } coords[0] = rowf; coords[1] = colf; coords[2] = layerf; coords[3] = rowe; coords[4] = cole; coords[5] = layere; return coords; } //This function joins the directory to the folder and the file name to give a fu ll directory to the file // dir1 and 2 are the strings containing what we want to join together char *Joindir(char dir1[128], char dir2[128]) { char *fulldir = (char *)malloc(128); fulldir[0]='\0'; strcat(fulldir, dir1); strcat(fulldir, "\\"); strcat(fulldir, dir2); return fulldir; } //This function gets the dimensions from the first line in the file and checks f or erros in the dimension line format // file is the file to read from (grid or list) and size is the predicted number of dimensions to be entered (1 for list, and 3 for grid) int *Getdim(FILE *file, int size) { char strdim[128]="\0"; fgets(strdim, 128, file); int *dimension = (int *)malloc(size*sizeof(int)), i=1; char *temp = NULL; temp = strtok(strdim, " "); if(atoi(temp)) dimension[0]=atoi(temp); else { printf("Error: Enter a valid dimension line\n"); exit(0); } while((temp=strtok(NULL," ")) != NULL) { if((i<size) && (atoi(temp)==0)) { printf("Error: Enter a valid dimension line\n"); exit(0); } else if((i>size-1) && (temp!= NULL))

{ printf("Error: Enter a valid dimension line\n"); exit(0); } else { dimension[i]=atoi(temp); i++; } } if(i<size) { printf("Error: Enter a valid dimension line"); exit(0); } return dimension; } //This function puts the character given in the array provided using the row, co lumn and layer provided in the arguments // posrow,poscol,poslayer are the respective row,column and layer in which the c haracter is in void putInArray(int posrow, int poscol, int poslayer, char *array, int *dimensio ns, char c) { array[To_onedim(posrow, poscol, poslayer, dimensions)] = c; } //This function gets a character from the array provided using the row,column an d layer provided //posrow,poscol,poslayer are the respective row,column and layer in which the ch aracter is in. dimensions is the dimensions of the array char getFromArray(int posrow, int poscol, int poslayer, char *array, int *dimens ions) { return array[To_onedim(posrow, poscol, poslayer, dimensions)]; } //This function will fill the grid in the arguments from the file in the argumen ts. Dimensions is the dimensions of the grid to be filled //The function also checks for format and input errors. It returns a new one dim ensional array of the grid void Fillgrid(int *dimensions, FILE *file, char *grid) { int row, column, layer, c=0; char tempchar; for(layer=0; layer<dimensions[2]; layer++) { for(row=0; row<dimensions[0]; row++) { for(column=0; column<dimensions[1]; column++) { tempchar=fgetc(file); if((isupper(tempchar))||(!isalpha(tempchar))) { printf("Error: Please enter a valid grid"); exit(0); } putInArray(row, column, layer, grid, dimensions, tempchar); c++; } tempchar=fgetc(file); if((tempchar!='\n')&&(tempchar!=EOF))

{ printf("Error: Please enter a valid grid"); exit(0); } } tempchar=fgetc(file); if(((c==dimensions[0]*dimensions[1]*dimensions[2])&&(tempchar!=EOF))||(( c<dimensions[0]*dimensions[1]*dimensions[2])&&(tempchar==EOF))) { printf("Error: Please enter a valid grid"); exit(0); } if((tempchar!='\n')&&(tempchar!=EOF)) { printf("Error: Please enter a valid grid"); exit(0); } } } //This function will fill the list in the arguments from the file in the argumen ts. Dimension is the number of words in the list //The function also checks for format and input errors. It returns a new one dim ensional array of the list. The words are sparated by spaces and the string ends with a fullstop. void Filllist(int *dimension, FILE *file, char *list) { int counter = 0, i = 0; char tempchar = 's'; while(tempchar!= EOF) { tempchar = fgetc(file); if(isupper(tempchar)) { printf("Please enter a valid list"); exit(0); } if((tempchar != '\n')&&(tempchar != EOF)) { if(isalpha(tempchar)) list[i] = tempchar; else { printf("Please enter a valid list"); exit(0); } } if(tempchar == '\n') { list[i] = ' '; counter++; tempchar = fgetc(file); if(isupper(tempchar)) { printf("Please enter a valid list"); exit(0); } if(tempchar == '\n') { printf("Please enter a valid list"); exit(0);

} if(tempchar != EOF) { if(isalpha(tempchar)) { i++; list[i] = tempchar; } else { printf("Please enter a valid list"); exit(0); } } } i++; } if(counter != dimension[0]-1) { printf("Please enter a valid list"); exit(0); } list[i-1]='.'; } //This function will find the first character from a word in the array provided. The character is c and the array is the grid inserted in the arguments int *FindFirst(char c, char *array) { int i, j=0, found = 0; int *queue = (int *)malloc((strlen(array)-1)*sizeof(int *)); for(i=0; i<strlen(array); i++) { if(array[i] == c) { queue[j] = i; j++; found=1; } } if(!found) { printf("Could not find the letter\n"); exit(0); } queue[j] = -1; return queue; } //This function checks if the character in the one dimensional position given is actually the character inserted in the arguments // c is the character to be checked, pos is the one dimensional position, and gr id is the one dimensional grid that the character should be in int Checkletter(char c, int pos, char *grid) { if(!IsinGrid(pos, grid)) return 0; if(grid[pos] == c) return 1; else return 0; }

//This function checks if the position provided in the argument is still inside the grid int IsinGrid(int pos, char *grid) { if((pos>strlen(grid)-1) || (pos<0)) return 0; else return 1; } //This function changes a 3 dimensional position (row, column and layer) to a co rresponding one dimensional position and returns it. Dimensions is the dimension s of the grid int To_onedim(int posrow, int poscol, int poslayer, int *dimensions) { int dimrow = dimensions[0]; int dimcol = dimensions[1]; int onedim = (dimrow*dimcol)*poslayer+dimrow*posrow+poscol; return (onedim); } //This function changes a one dimensional position to the corresponding 3 dimens ional positions and returns them as a pointer to an array containing them int *To_threedim(int pos, int *dimensions) { int dimrow = dimensions[0]; int dimcol = dimensions[1]; int posrow, poscol, poslayer; int *position = (int *)malloc(3*sizeof(int)); poslayer = pos / (dimrow * dimcol); posrow = (pos / dimcol) - (dimrow * poslayer); if((pos > 0) && (pos < dimcol - 1)) poscol = pos; else poscol = pos % dimcol; position[0] = posrow; position[1] = poscol; position[2] = poslayer; return position; } //This function finds the second letter s inserted in the arguments. //The function also takes in the position of the first character (posfirst) so i t only looks around it. //Grid is the grid to look in and dimensions is the dimensions of this grid int *FindSecond(char s, int *posfirst, char *grid, int *dimensions) { int i, j, k, onedimsec, torf = 0, counter =0; int possecond[3]; int *offsets = (int *)malloc((26*3+1)*sizeof(int)); for(i = -1; i<2; i++) { for(j = -1; j<2; j++) { for(k = -1; k<2; k++) { if(!(i == 0 && j == 0 && k == 0)) { possecond[0] = i + posfirst[0]; possecond[1] = j + posfirst[1]; possecond[2] = k + posfirst[2]; onedimsec = To_onedim(possecond[0], possecond[1], possecond[ 2], dimensions);

torf = Checkletter(s, onedimsec, grid); if(torf) { offsets[counter] = i; counter++; offsets[counter] = j; counter++; offsets[counter] = k; counter++; } } } } } offsets[counter] = -3; return offsets; } //This function takes a list and gives the word that starts at the position z in the list. It knows when it ends when it hits a space. char *Giveword(char *list, int z) { int i = z; int j=0; char *word = (char *)malloc(46*sizeof(char)); while((list[i] != ' ') && (list[i] != '.')) { word[j] = list[i]; j++; i++; } word[j] = '.'; return word; } //This function searches for the word given in the argument in the grid (also in argument). It returns a pointer to an array with the positions of the character s of the word. //This is a function to be used in Searchlist to find all the words int *Searchword(char *word, char *grid, int *dimensions) { char first_letter = word[0]; int *character_pos = (int *)malloc(46*sizeof(int)), *first_queue = FindFirst (first_letter, grid); if(word[1] == '.') { if(first_queue[0] != -1) { character_pos[0] = first_queue[0]; character_pos[1] = -1; return character_pos; } else { character_pos[0] = -1; return character_pos; } } char second_letter = word[1]; int i, j, torf; for(i = 0; first_queue[i] != -1; i++) {

character_pos[0] = first_queue[i]; int *first_coord = To_threedim(first_queue[i], dimensions), *offset_coor d = FindSecond(second_letter, first_coord, grid, dimensions); if(offset_coord[0] == -3) { character_pos[0] = -1; return character_pos; } else if(word[2] == '.') { int second_coord[3] = {(first_coord[0] + offset_coord[0]), (first_co ord[1] + offset_coord[1]), (first_coord[2] + offset_coord[2])}; character_pos[1] = To_onedim(second_coord[0], second_coord[1], secon d_coord[2], dimensions); character_pos[2] = -1; return character_pos; } else { for (j = 0; offset_coord[j] != -3; j=j+3) { int second_coord[3] = {(first_coord[0] + offset_coord[j]), (firs t_coord[1] + offset_coord[j+1]), (first_coord[2] + offset_coord[j+2])}; character_pos[1] = To_onedim(second_coord[0], second_coord[1], s econd_coord[2], dimensions); torf = 1; int k = 2; int offset_row = offset_coord[j], offset_col = offset_coord[j+1] , offset_layer = offset_coord[j+2]; while(word[k] != '.') { int row = first_coord[0] + offset_row*k, col = first_coord[1 ] + offset_col*k, layer = first_coord[2] + offset_layer*k; int onedim_pos = To_onedim(row, col, layer, dimensions); character_pos[k] = onedim_pos; torf = torf*Checkletter(word[k], onedim_pos, grid); k++; } if(torf) { character_pos[k] = -1; return character_pos; } } } } character_pos[0] = -1; return character_pos; } //This function takes the list, grid, its dimensions, and the number of words to be found. Then it searches for all the words in the list and returns a pointer to an array with the positions of all the found right characters. int *Searchlist(char *list, char *grid, int *dimensions, int nwords) { int i = 0, j=0; int *all_found_pos = (int *)malloc(nwords*46*sizeof(int)); while((isalpha(list[i])) || (list[i] == ' ')) { int l = 0; char *word = Giveword(list, i);

int *positions = Searchword(word, grid, dimensions); int z = 0; while(positions[z] != -1) { all_found_pos[j] = positions[z]; j++; z++; } all_found_pos[j] = -1; j++; while (word[l] != '.') { l++; } i = i + l + 1; } all_found_pos[j] = -2; return all_found_pos; } //This is the main function for noninteractive. It calls on other functions to d o the whole procedure. //It takes in the dimensions of the grid, and of the list (number of words), the grid itself, list, and command line 4 (i or n). void Noninteractive(int *dimgrid, int *dimlist, char *grid, char *list, char *ar g) { int *all_found = Searchlist(list, grid, dimgrid, dimlist[0]); char grid2[dimgrid[0]*dimgrid[1]*dimgrid[2]]; int i,j,k; PrintGrid(grid, dimgrid); PrintList(list, arg); for(i=0; i<dimgrid[0]*dimgrid[1]*dimgrid[2]; i++) { grid2[i] = grid[i]; } for(i = 0; all_found[i] != -2 ; i++) { if(all_found[i] != -1) { char c = grid[all_found[i]]; grid2[all_found[i]] = toupper(c); } } PrintGrid(grid2, dimgrid); printf("Word list:\n\n"); i =0, j=0; while(list[i] != '.') { while((list[i] != ' ') && (list[i] != '.')) { printf("%c", list[i]); i++; } if(list[i] != '.') i++; if(all_found[j] == -1) { printf(" not found.\n"); j++; }

else { int *first_letter = To_threedim(all_found[j], dimgrid); for(k=j+1; all_found[k] != -1; k++); int *last_letter = To_threedim(all_found[k-1], dimgrid); j=k+1; printf(" (%d,%d,%d) to (%d,%d,%d)\n", first_letter[0]+1,first_letter [2]+1,first_letter[2]+1,last_letter[0]+1,last_letter[1]+1,last_letter[2]+1); } } } //This is the main function for interactive. It also calls on other functions to do the whole procedure. //It takes in the dimensions of the grid, and of the list (number of words), the grid itself, list, and command line 4 (i or n). void Interactive(int* dimgrid, int *dimlist, char *grid, char *list, char *arg) { PrintGrid(grid, dimgrid); PrintList(list, arg); int i, guesses = 0, words_found =0; char grid2[dimgrid[0]*dimgrid[1]*dimgrid[2]]; for(i=0; i<dimgrid[0]*dimgrid[1]*dimgrid[2]; i++) { grid2[i] = grid[i]; } i = 0; char list2[dimlist[0]*46+1]; while(list[i] != '.') { list2[i] = list[i]; i++; } list2[i] = '.'; here2: while(words_found < dimlist[0]) { int *coords = Getcoords(dimgrid); if(coords[0] != -1) { guesses++; int offset[3], max; offset[0] = coords[3] - coords[0]; offset[1] = coords[4] - coords[1]; offset[2] = coords[5] - coords[2]; int unit_vector[3]; if(offset[0] == 0 && offset[1] == 0 && offset[2] == 0) { unit_vector[0] = 0; unit_vector[1] = 0; unit_vector[2] = 0; max = 0; } else { if(abs(offset[0])>abs(offset[1])) max = abs(offset[0]); else max = abs(offset[1]); if(max>abs(offset[2])) {

; } else max = abs(offset[2]); if(!(offset[1] % max == 0) || !(offset[2] % max == 0)) { printf("That combination does not work!"); goto here2; } unit_vector[0] = offset[0] / abs(max); unit_vector[1] = offset[1] / abs(max); unit_vector[2] = offset[2] / abs(max); } int first_coord[3] = {coords[0]-1,coords[1]-1, coords[2] -1}; int wordlen = abs(max) + 1; char word[wordlen]; for(i = 0; i<wordlen; i++) { int letter_coord[3] = {first_coord[0] + unit_vector[0]*i, first_ coord[1] + unit_vector[1]*i, first_coord[2] + unit_vector[2]*i}; int pos = To_onedim(letter_coord[0], letter_coord[1], letter_coo rd[2], dimgrid); word[i] = grid[pos]; } i = 0; int torf = 0; while(list[i] != '.') { torf = 1; int j = 0; while((list[i] != ' ') && (list[i] != '.')) { if(j < wordlen) torf = torf*(word[j] == list[i]); else torf = 0; j++; i++; } if(list[i] != '.') i++; if(torf) { words_found++; int k = 0; if(list[i] != '.') k = 1; int t; for(t = 0; t < wordlen; t++) list2[i-wordlen-k+t] = '-'; break; } } if(!torf) goto here; for(i = 0; i<wordlen; i++) { int letter_coord[3] = {first_coord[0] + unit_vector[0]*i, first_ coord[1] + unit_vector[1]*i, first_coord[2] + unit_vector[2]*i}; int pos = To_onedim(letter_coord[0], letter_coord[1], letter_coo

rd[2], dimgrid); grid2[pos] = toupper(grid[pos]); } here: PrintGrid(grid2, dimgrid); PrintList(&list2, arg); } else break; } printf("You used %d guesses and found %d words\n", guesses, words_found); } //This function prints a grid given in the arguments. Dimensions of the grid are also to be provided. void PrintGrid(char *grid, int *dimgrid) { int i, j, k, z=0; printf("Grid:\n\n"); for(i = 0; i< dimgrid[2]; i++) { for(j=0; j< dimgrid[0]; j++) { for(k=0; k< dimgrid[1]; k++) { printf("%c", grid[z]); z++; } printf("\n"); } printf("\n"); } } //This function prints a list given in the arguments. Command line 4 (i or n) sh ould also be provided. void PrintList(char *list, char *arg) { int i = 0; if(!strcmp(arg, "i")) printf("Words left:\n\n"); else printf("Word list:\n\n"); while(list[i] != '.') { for(i; (list[i] != ' ') && (list[i] != '.'); i++) { if(list[i] != '-') printf("%c", list[i]); } if(list[i] == '.') break; else i++; if(list[i-2] != '-') printf("\n"); } printf("\n\n"); } //The main function /*Adham Bakr, bakradha Zaid Al-Taher, taherzai

Wafic El-Assi, assiwafi Tarek Abul-Fotouh, fotouhta*/ int main(int argc, char *argv[]) { char *dirgrid = Joindir(argv[1], argv[2]); char *dirlist = Joindir(argv[1], argv[3]); FILE *gridf= fopen(dirgrid, "r"); FILE *listf= fopen(dirlist, "r"); int *dimgrid = Getdim(gridf, 3); int *dimlist = Getdim(listf, 1); char grid[dimgrid[0]*dimgrid[1]*dimgrid[2]]; char list[dimlist[0]*45]; Fillgrid(dimgrid, gridf, &grid); Filllist(dimlist, listf, &list); if(!strcmp(argv[4], "n")) { Noninteractive(dimgrid, dimlist, &grid, &list, &argv[4]); } else if(!strcmp(argv[4], "i")) { Interactive(dimgrid, dimlist, &grid, &list, &argv[4]); } else { printf("Put either i for interactive or n for noninteractive in the last argument"); } return 0; }

You might also like