Проверьте, если слово уже угадано или введено - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь создать игру для поиска слов в C, из которой пользователь будет угадывать / вводить слово, и программа проверит, существует ли слово и является ли оно действительным.

Как я могу проверить если слово, введенное пользователем, уже напечатано / введено? Я действительно запутался, если какую переменную / и сравнивать, или мне нужно создать функцию для этого.

символ угадан [], это глобальный массив.

 bool isAdded(char *token){
        int i = 0;
        while(guessed[i] != NULL){
            if(strcmp(guessed[i], token) == 0){
                return true;
            }
            i++;
        }
    return false;
}

main

while (1) {
   printf("\n[GM: Find a word]> ");
   if (!fgets(word, sizeof word, stdin)) {
    break;
       }
   word[strcspn(word, "\n")] = '\0';

   if (isAdded(word)) {
       printf("[GM: Word already guessed]");
   } else { 

    if (ifExist(matrix, word) && checkDictionary(dictionary, dict_len, word)) {
        printf("[GM: Found it]\n");
       } 
       else if (ifExist(matrix, word)) {
        printf("[GM: It's not in the dictionary]\n");
       }
       else if (strcmp(word, "quit") == 0) {
        break;
       } else {
        printf("[GM: Not found, please try again]\n");
       }
       }
    }
} 

1 Ответ

0 голосов
/ 20 марта 2020

Основным решением c является добавление массива, в котором хранятся прошлые слова, а затем поиск по нему каждый раз, когда запрашивается слово, чтобы узнать, является ли оно повторным словом. Сначала я отправлю репост всего кода, который вы разместили: в будущем, когда вы обновите свое сообщение, пожалуйста, не приводите в пример полный пример. Вы правильно сделали, вставив весь код, потому что я хочу затронуть кое-что. Все изменения сделаны в main(). Решением является базовый c круговой массив, который попирает прошлые записи после того, как он достиг своего предела.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdbool.h>

#define SIZE 10 // row and column size
#define MAX 40  // word size

// Function to check if a word exists in the board 
// starting from the first match in the board 
// index: index till which pattern is matched 
// i, j: current position in 2D array 
bool adjacentSearch(char matrix[SIZE][SIZE], const char *find, int i, int j, int index) {
    // pattern matched
    if (find[index] == '\0')
        return true;

    // out of bounds
    if (i < 0 || j < 0 || i >= SIZE || j >= SIZE || matrix[i][j] != find[index])
        return false;

    // marking this cell as visited 
    matrix[i][j] = '*';

    // finding subpattern in 4 directions 
    bool found = (adjacentSearch(matrix, find, i + 1, j, index + 1) ||
        adjacentSearch(matrix, find, i - 1, j, index + 1) ||
        adjacentSearch(matrix, find, i, j - 1, index + 1) ||
        adjacentSearch(matrix, find, i, j + 1, index + 1));

    // marking this cell 
    // as unvisited again 
    matrix[i][j] = find[index];
    return found;
}

// Function to check if the word exists in the board or not 
bool ifExist(char matrix[SIZE][SIZE], const char *find) {
    int len = strlen(find);

    // if total characters in matrix is 
    // less then pattern length 
    if (len > SIZE * SIZE)
        return false;

    // traverse in the board 
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (adjacentSearch(matrix, find, i, j, 0)) {
                return true;
            }
        }
    }
    return false;
}

// Function to check if the word is in the dictionary 
int checkDictionary(char **arr, int len, char *target) {
    for (int i = 0; i < len; i++) {
        if (strncmp(arr[i], target, strlen(target)) == 0) {
            return true;
        }
    }
    return false;
}

// Prints the board
void printBoard(char matrix[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf(" %c ", matrix[i][j]);
        }
        printf("\n");
    }
}

void asdf(char* a) {
    int k = 2;
    return;
}

// Driver code
int main() {
    char previous[SIZE][MAX];
    int  indexOfPrevious = 0;
    char *dictionary[] = {"one", "two", "three", "four", "five", "six"};
    int dict_len = sizeof dictionary / sizeof dictionary[0];
    asdf(dictionary[0]);
    char word[MAX], matrix[SIZE][SIZE] = {{'r', 'h', 'y', 't', 'h', 'm', 'y', 'o', 'n', 'e'},
    {'j', 'e', 'p', 'u', 'o', 'o', 'f', 'u', 'o', 'l'},
    {'r', 'e', 'n', 'd', 'e', 'o', 'i', 'e', 'l', 'c'},
    {'o', 'p', 'e', 'e', 't', 'h', 'r', 'e', 'e', 'j'},
    {'d', 'y', 'l', 'v', 'p', 'p', 'h', 'e', 't', 'p'},
    {'h', 'e', 's', 'i', 'x', 'o', 'u', 'n', 'w', 'e'},
    {'f', 'v', 'm', 'f', 'o', 'x', 'd', 'k', 'o', 'v'},
    {'f', 'o', 'r', 'o', 's', 't', 'u', 'e', 'o', 'i'},
    {'g', 'a', 'l', 'g', 'o', 'w', 'b', 'y', 'p', 'a'},
    {'h', 'e', 'l', 'l', 'o', 'f', 'o', 'u', 'r', 'd'}};

    printBoard(matrix);

    while (1) {
        Start:
        printf("\n[GM: Find a word]> ");
        if (!fgets(word, sizeof word, stdin)) {
            break;
        }
        word[strcspn(word, "\n")] = '\0';
        if (strcmp(word, "quit") == 0) {
            break;
        }
        int repeatEntry = 0;
        for (int i = 0; i < indexOfPrevious; i++) {
            int Result = strncmp(previous[i], word, MAX);
            if (!Result) {
                repeatEntry |= 1;
                // Insert what you want to do if a word is re-entered here
            }
        }
        if (!repeatEntry) {
            indexOfPrevious %= SIZE;
            memcpy(previous[indexOfPrevious++], word, MAX);
        }

        if (ifExist(matrix, word) && checkDictionary(dictionary, dict_len, word)) {
            printf("[GM: Found it]\n");
        } else if (ifExist(matrix, word)) {
            printf("[GM: It's not in the dictionary]\n");
        }
        else {
            printf("[GM: Not found, please try again]\n");
        }
    }
    return 0;
}

Теперь поговорим о допущенной вами ошибке, не связанной с заданным вопросом, но очень важно с точки зрения правильности кода. Код ошибки:

char *dictionary[] = {"one", "two", "three", "four", "five", "six"};

в сочетании с

int checkDictionary(char **arr, int len, char *target) {
    for (int i = 0; i < len; i++) {
        if (strncmp(arr[i], target, strlen(target)) == 0) {
            return true;
        }
    }
    return false;
}

Проще говоря, переменная dictionary первоначально объявляется как массив указателей, а затем приводится к указателю на указатель ( s), но инициализируется строковыми литералами. Этот последний пункт вызывает проблемы. Я решил go по строкам побайтно, чтобы сделать результат более читабельным, я очистил вывод, заменив нулевые терминаторы пробелом, чтобы его можно было увидеть как одну строку:

one two two three three four four five five six six

Подожди, что? Почему слова повторяются? Это когда вы знаете, что-то просто не правильно. Честно говоря, я не знаю точно, почему это происходит, но это действительно чертовски. Проблема в том, что вы объявляете массив указателей, но инициализируете его строковыми литералами. На мой взгляд, C не должен позволять компиляции, но это так. Кажется, что происходит то, что он размещает строковые литералы где-то еще в памяти и дает вам указатель там, что означает, что разница между адресами огромна. Один пример - 0x0059 (...) против 0x7fff (...). Таким образом, каждый элемент dictionary является указателем на один из них.

Теперь, то, что вы делаете в checkDictionary() с итерацией for l oop, перебирающей указатель как массив, не рекомендуется, так как Вы не можете сделать это вообще, и пусть это будет правильно. Что происходит, так это то, что каждое приращение индекса перемещает доступ к памяти на 8 байт (в 64-разрядных системах, которые, как я предполагаю, вы используете. Я даже не хочу думать о том, как это будет работать в 32-разрядных системах). ). Если dictionary был инициализирован так, как я думаю, вы хотели, чтобы это было с каждым словом в памяти без повторений, это не сработало бы, так как слова были бы пропущены. Однако, как это было бы с «удачей», повторы структурированы так, чтобы они не мешали, и способ, которым вы выполняете итерацию, в итоге работает. Но это не правильно, и такого рода вещи в конечном итоге гарантированно взорвутся чрезвычайно раздражающими сбоями и ужасными ошибками.

Исправление состоит в том, чтобы просто сделать dictionary a char** или char[][] такими, как вы сделал с матрицей. В первом случае вам придется вводить c каждого слова, но также можно динамически добавлять его, тогда как во втором вам нужно будет указывать каждый символ, и в итоге вы будете использовать больше памяти в качестве каждой записи. должен быть гомогенизирован с самым большим строковым литералом.

...