Изменение 6 различных случайных чисел с помощью SRAND на доске, созданной с помощью динамически размещенных массивов

Итак, у меня есть код, который создает доску 7x7 с динамически распределенными массивами, а внутри платы есть "?" и что я хочу создать новую функцию, и внутри функции я использовал команду rand, чтобы получить такие случайные числа, как это,

int random() {
    return ((rand() % 7) + 1);
}

Поэтому у меня возникла проблема с изменением 6 случайных чисел на доске, и мой код ниже,

Ниже я пытался получить случайные числа для массива

    printf("Enter number: ");
    scanf("%d", &b);
    char *rando = (char *)malloc(7 * 7 * sizeof(char));
    for (i = 0; i < b; i++) {
        rand1 = random();
        rand2 = random();
        *(rando + rand1 + rand2) = '*';
    }

И здесь я напечатал "?" знаков, а также там, где я пытался изменить 6 разных знаков, и он выводит только часть "else", игнорируя "если" по какой-то причине

        for (j = 0; j < 7; j++) {
            if (*(board + i + j) == *(rando + i + j))
                printf("| %c ", *(rando + i + j));
            else
                printf("| %c ", *(board + i + j));
            }

И весь мой код такой, он довольно длинный, но большинство из них предназначены для красивой доски

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

int random() {
    return ((rand() % 7) + 1);
}

int main() {
    int i, j, k, rand1, rand2, b;
    srand(time(NULL));
    printf("Enter number: ");
    scanf("%d", &b);
    char *rando = (char *)malloc(7 * 7 * sizeof(char));
    for (i = 0; i < b; i++) {
        rand1 = random();
        rand2 = random();
        *(rando + rand1 + rand2) = '*';
    }
    char *board = (char *)malloc(7 * 7 * sizeof(char));
    for (i = 0; i < 7; i++) {
        for (j = 0; j < 7; j++) {
            *(board + i + j) = '?';
        }
    }
    for (i = 1; i <= 7; i++) {
        printf("%4d", i);
    }
    printf("\n  ");
    for (i = 0; i < 7; i++) {
        printf("+---");
    }
    printf("+\n");
    for (i = 0; i < 7; i++) {
        printf("%d ",i);
        for (j = 0; j < 7; j++) {
            if (*(board + i + j) == *(rando + i + j))
                printf("| %c ", *(rando + i + j));
            else
                printf("| %c ", *(board + i + j));
        }
        printf("|\n");
        for (k = 0; k <= 7; k++) 
            if (k == 0)
                printf("  ");
            else
                printf("+---");
        printf("+\n");
    }
}

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


person user9414    schedule 14.04.2020    source источник


Ответы (1)


В вашем коде несколько проблем:

  • вы выделяете матрицу 7x7 как единый массив из 49 символов. Однако вы не индексируете этот массив по правильной формуле. Элемент в позиции (_1 _, _ 2_) доступен как *(board + 7 * i + j), а не *(board + i + j).

    Было бы проще объявить rando и board, чтобы они указывали на 2D-матрицу и использовали синтаксис []:

    char (*board)[7] = malloc(7 * sizeof(*board));
    

    и используйте board[i][j].

  • Кроме того, массив rando не инициализирован, поэтому программа имеет неопределенное поведение при чтении содержимого элементов, для которых не было установлено значение '*' в первом цикле. Вы должны инициализировать этот массив с помощью '?'. Вы можете сделать это с помощью memset().

  • функция random() возвращает целое число в диапазоне от 1 до 7 включительно. Вместо этого вы должны вычислять псевдослучайные координаты в диапазоне от 0 до 6. Удалите +1;

  • тест в цикле печати платы бесполезен: если элемент платы в позиции _20 _, _ 21_ такой же, как в матрице rando, вы печатаете элемент rando, иначе t элемент платы. Это всегда печатает элемент платы.

Вот модифицированная версия:

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

int random(void) {
    return rand() % 7;
}

void init_board(char board[7][7]) {
    // board can be initialized with 2 nested loops or
    // a single call to
    //memset(board, '?', 7 * 7);
    for (int i = 0; i < 7; i++) {
        for (int j = 0; j < 7; j++) {
            board[i][j] = '?';
        }
    }
}

void print_board(char board[7][7]) {
    for (int i = 0; i < 7; i++) {
        printf("%4d", i + 1);
    }
    printf("\n  ");
    for (int i = 0; i < 7; i++) {
        printf("+---");
    }
    printf("+\n");
    for (int i = 0; i < 7; i++) {
        printf("%d ", i + 1);
        for (int j = 0; j < 7; j++) {
            printf("| %c ", board[i][j]);
        }
        printf("|\n");
        printf("  ");
        for (int j = 0; j < 7; j++) {
            printf("+---");
        }
        printf("+\n");
    }
}

int main() {
    int b;

    srand(time(NULL));
    printf("Enter number: ");
    scanf("%d", &b);
    char (*rando)[7] = malloc(7 * sizeof(*rando));
    if (!rando)
        return 1;
    init_board(rando);
    for (int i = 0; i < b; i++) {
        int rand1 = random();
        int rand2 = random();
        rando[rand1][rand2] = '*';
    }
    char (*board)[7] = malloc(7 * sizeof(*board));
    if (!board)
        return 1;
    init_board(board);

    /* print the mines */
    print_board(rando);

    /* print the board */
    print_board(board);

    free(rando);
    free(board);
    return 0;
}
person chqrlie    schedule 15.04.2020
comment
небольшая опечатка: вы забыли объявить k в print_board (например, int i, j, k; вместо int i, j ;)). Уф в любом случае, да я слишком нежный :-) - person bruno; 15.04.2020
comment
Можно ли обойтись без струн? Я имею в виду, без мемсета - person user9414; 15.04.2020
comment
@ user9414: Я использовал memset, потому что базовый тип матрицы - байтовый. Вы можете писать вложенные циклы: for (i = 0; i < 0; i++) for (j = 0; j < 7; j++) board[i][j] = '?'; - person chqrlie; 16.04.2020
comment
@bruno: ответ обновлен. Я также удалил бесполезные определения в main(). Это типичный пример преимущества использования переменных индекса C99 for с областью видимости. - person chqrlie; 16.04.2020
comment
Извините, я забыл упомянуть, что сейчас использую C - person user9414; 16.04.2020
comment
@ user9414: C99 равно C. Очень немногие компиляторы не поддерживают функции C99. Если ваш компилятор скомпилировал код, указанный в вопросе, определение переменных индекса в предложении инициализации оператора for должно быть нормальным: вы уже используете расширение C99, а именно определение rando и board в середине блока. - person chqrlie; 16.04.2020