2015-12-03 7 views
0

Я написал следующий код, который принимает слова от пользователя, сортирует их от самого длинного до кратчайшего, а затем проверяет, есть ли место для слова быть поставлен. У меня возникают проблемы с выяснением того, как проверить, может ли слово размещаться горизонтально или вертикально. Любая помощь будет принята с благодарностью.Проверка возможности размещения слова по горизонтали или вертикали в игре кроссворда

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

void initialize_board(char board[][15]); 
void get_user_info(char words[][16], int *numbofwords); 
void sort_words(char words[][16], int numbofwords); 
void display_solution_board(char board[][15]); 
void place_words(char board[][15], char words[][16], int numbofwords); 
int check_if_fits(char board[][15], char * word, int *j, int *n); 


int main(){ 
    char words[20][16]; 
    char board[15][15]; 
    int numbofwords = 0; 
    int i; 
    //create a board of all pound symbols 
    initialize_board(board); 
    //get words for crossword from user 
    get_user_info(words, &numbofwords); 
    //sort words array to go from longest word to shortest 
    sort_words(words,numbofwords); 
    //places the words in appropriate places 
    place_words(board,words,numbofwords); 
    //displays the output of the board with answers 
    display_solution_board(board); 
} 

void initialize_board(char board[][15]){ 
    int j,k; 
    for(j = 0; j < 15; j++){ 
     for(k = 0; k < 15; k++){ 
      strcpy(&board[j][k],"#"); 
     } 
    } 
} 

void get_user_info(char words[][16], int *numbofwords){ 
    char word[16]; 
    int i = 0; 
    printf("Please enter up to 20 words of up to 15 characters in length.\n"); 
    printf("Use a period to end your input if you want less than 20 words.\n"); 
    scanf("%s", word); 
    while(strcmp(word, ".") != 0){ 
     strcpy(words[i],word); 
     i++; 
     if(i == 20){ 
      break; 
     } 
     scanf("%s", word); 
    } 
    *numbofwords = i; 

} 

void sort_words(char words[][16], int numbofwords){ 
    int i, j; 
    char temp[16]; 
    for(i = 0; i < numbofwords-1; i++){ 
     for(j = 0; j < numbofwords-i-1;j++){ 
      if(strlen(words[j]) < strlen(words[j+1])){ 
       strcpy(&temp[0],words[j]); 
       strcpy(words[j],words[j+1]); 
       strcpy(words[j+1],&temp[0]); 
      } 
     } 
    } 
} 

void display_solution_board(char board[][15]){ 
    int j,k; 
    for(j = 0; j < 15; j++){ 
     for(k = 0; k < 15; k++){ 
      printf("%c",board[j][k]); 
     } 
     printf("\n"); 
    } 
} 

void place_words(char board[][15], char words[][16], int numbofwords){ 
int i,j,k,max; 
int n,r = 0; 

//sets the longest word in the middle of the grid 
max = strlen(words[0]); 
printf("max is %d\n",max); 
printf("num words is %d\n",numbofwords); 
strncpy(&board[7][(15-max)/2],words[0], strlen(words[0])); 
//goes through all other words to find a place for them 
for(i = 1; i < numbofwords; i++){ 
    if(check_if_fits(board,words[i],&j,&k) == 0 && check_vertical_placement(board,words[i],j,k) == 0){ 
     //printf("The word %s fits in col %d and row %d\n", words[i],k,j); 
     for(k = k;k < strlen(words[i]);k++){ 
      board[j][k] = words[i][r]; 
      r++; 
     } 
    }else if(check_if_fits(board,words[i],&j,&k) == 0 && check_horizontal_placement(board,words[i],j,k) == 0){ 
     //printf("The word %s fits in col %d and row %d\n", words[i],k,j); 
     for(j = j; j < strlen(words[i]); j++){ 
      board[j][k] = words[i][n]; 
      n++; 
     } 
    }else if(check_if_fits(board,words[i],&j,&k) == 1){ 
     printf("The word %s doesn't fit\n", words[i]); 
    } 
} 
} 

int check_if_fits(char board[][15], char * word, int *j, int *n){ 
    int k,t,h,g; 
    for(t = 0; t < 15; t++){ 
     for(h = 0; h < 15; h++){ 
      for(k = 0; k < strlen(word); k++){ 
       if(board[t][h] == word[k]){ 
        *j = t+1; 
        *n = h+1; 
        return 0; 
       } 
      } 
     } 
    } 
    return 1; 
} 

int check_horizontal_placement(char board[][15],char * word, int j,int k){ 
    int i,val; 
    for(i = k; i < strlen(word);i++){ 
     if(board[j][i] == '#' && board[j+1][i] == '#' && board[j-1][i] == '#') val = 0; 
    } 
    if(val == 0) return(0); 
    else{return(1);} 
} 

int check_vertical_placement(char board[][15],char * word, int j,int k){ 
    int i,val; 
    for(i = j; i < strlen(word);i++){ 
     if(board[i][k] == '#' && board[i][k+1] == '#' && board[i][k-1] == '#') val = 0; 
    } 
    if(val == 0) return(0); 
    else{return(1);} 
} 
+0

Ваша доска представляет собой 2-мерный массив символов. Тогда не делайте этого: 'strcpy (& board [j] [k]," # ")'. Это скопирует хеш-метку, но также перезапишет следующий символ в массиве с нулевым терминатором. Вам нужна панель [j] [k] = '#') '. Обратите внимание на одинарные кавычки; хэш в одинарных кавычках - всего лишь один символ. –

+0

@MOehm, если он перезаписывает следующий символ, тогда я бы ожидал, что на плате будут пустое пространство, когда я его распечатаю, но это не так. Я внедрил ваше предложение независимо от того, что вижу, что это может вызвать ошибку при проверке платы. – mukolatte

+0

Вы сразу же переписываете пробелы. Скажем, вы 'strcpy' хэш-строку для' board [0 [0] '. Это помещает '' # ''в' board [0] [0] 'и' '\ 0'' (который вы обычно не можете печатать) в' board [0] [1] '. Далее в вашем цикле вы инициализируете 'board [0 [[1]', тем самым перезаписывая нулевой символ из более раннего strcpy. Для последней ячейки на плате у вас есть доступ к памяти за пределами границ. –

ответ

0

Есть ли у вас какие-либо предложения о том, как проверить, подходит ли слово сверху среднего ряда?

Заменить в place_words() теле вашего for(i = 1; i < numbofwords; i++) петли с

switch (check_if_fits(board, words[i], &j, &k)) 
    { 
    case -1:// vertical_placement 
     //printf("The word %s fits in col %d and row %d\n", words[i],k,j); 
     for (r = 0; r < strlen(words[i]); r++) board[j+r][k] = words[i][r]; 
     break; 
    case 0: // horizontal_placement 
     //printf("The word %s fits in col %d and row %d\n", words[i],k,j); 
     for (n = 0; n < strlen(words[i]); n++) board[j][k+n] = words[i][n]; 
     break; 
    case 1: 
     printf("The word %s doesn't fit\n", words[i]); 
    } 

заменить линий *j = t+1; *n = h+1; в check_if_fits() с чеками для обоих размещений:

    if (check_vertical_placement(board, word, *j=t-k, *n=h)==0) 
        return -1; 
        if (check_horizontal_placement(board, word, *j=t, *n=h-k)==0) 

и контрольные функции с

int check_horizontal_placement(char board[][15], char *word, int j, int k) 
{ 
    int i; 
    if (k < 0 || 15 < k+strlen(word)) return 1; // word outside board 
    if (k && board[j][k-1] != '#') return 1; // another word in front 
    for (i = 0; i < strlen(word); i++) 
     if (board[j][k+i] != '#' && board[j][k+i] != word[i]) return 1; 
    if (k+i < 15 && board[j][k+i] != '#') return 1; // another word behind 
    return 0; 
} 

int check_vertical_placement(char board[][15], char *word, int j, int k) 
{ 
    int i; 
    if (j < 0 || 15 < j+strlen(word)) return 1; // word outside board 
    if (j && board[j-1][k] != '#') return 1; // another word in front 
    for (i = 0; i < strlen(word); i++) 
     if (board[j+i][k] != '#' && board[j+i][k] != word[i]) return 1; 
    if (j+i < 15 && board[j+i][k] != '#') return 1; // another word behind 
    return 0; 
}