Загрузка данных


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

// ============================================================
// ВЫБОР ЗАДАЧИ ДЛЯ КОМПИЛЯЦИИ
// ------------------------------------------------------------
// Для задачи 1 (Фибоначчи):
//     #define TASK1
//     // #define TASK2
//
// Для задачи 2 (Сапёр):
//     // #define TASK1
//     #define TASK2
// ============================================================
#define TASK2
// #define TASK2


// ============================================================
// ОБЩИЕ МАКРОСЫ
// ============================================================

#define PRINT_HEADER(txt) \
    printf("\n========================================\n"); \
    printf("  %s\n", txt); \
    printf("========================================\n")

#define PRINT_LINE() \
    printf("----------------------------------------\n")

#define RAND_RANGE(min, max) \
    (rand() % ((max) - (min) + 1) + (min))

#define FILL_2D(arr, rows, cols, val) \
    do { \
        for (int i = 0; i < (rows); i++) { \
            for (int j = 0; j < (cols); j++) { \
                (arr)[i][j] = (val); \
            } \
        } \
    } while(0)

// Вывод таблицы чисел
#define PRINT_NUMS(arr, rows, cols) \
    do { \
        printf("      "); \
        for (int j = 1; j <= (cols); j++) printf("%5d", j); \
        printf("\n"); \
        for (int i = 0; i < (rows); i++) { \
            printf("%4d: ", i + 1); \
            for (int j = 0; j < (cols); j++) \
                printf("%5d", (arr)[i][j]); \
            printf("\n"); \
        } \
    } while(0)

// Вывод таблицы 0/1
#define PRINT_FLAGS(arr, rows, cols) \
    do { \
        printf("      "); \
        for (int j = 1; j <= (cols); j++) printf("%5d", j); \
        printf("\n"); \
        for (int i = 0; i < (rows); i++) { \
            printf("%4d: ", i + 1); \
            for (int j = 0; j < (cols); j++) \
                printf("%5d", (arr)[i][j]); \
            printf("\n"); \
        } \
    } while(0)


// ============================================================
// ЗАДАЧА 1: Последовательность Фибоначчи через рекурсию
// ============================================================
#ifdef TASK1

// Рекурсивная функция вычисления числа Фибоначчи
int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

// Рекурсивная функция вывода последовательности до 584
void print_fib(int n) {
    int value = fib(n);

    if (value > 584) return;

    printf("%d ", value);
    print_fib(n + 1);
}

void task1() {
    PRINT_HEADER("ЗАДАЧА 1: Последовательность Фибоначчи (рекурсия)");

    printf("\nИСХОДНЫЕ ДАННЫЕ:\n");
    printf("  Показать числа Фибоначчи от F(0) до числа 584\n");
    printf("  (используется рекурсивная функция)\n");

    printf("\nРЕЗУЛЬТАТ:\n  ");
    print_fib(0);
    printf("\n");

    PRINT_LINE();
}

#endif


// ============================================================
// ЗАДАЧА 2: Игра-аналог "Сапёр"
// ============================================================
#ifdef TASK2

#define SIZE 5
#define MAX_VALUE 127

// Рекурсивно открыть ВСЕ клетки со значением target
void open_all_with_value(int values[SIZE][SIZE],
                         int opened[SIZE][SIZE],
                         int row, int col, int target) {
    if (row >= SIZE) return;
    if (col >= SIZE) return;

    if (values[row][col] == target && !opened[row][col]) {
        opened[row][col] = 1;
    }

    if (col + 1 < SIZE)
        open_all_with_value(values, opened, row, col + 1, target);
    else
        open_all_with_value(values, opened, row + 1, 0, target);
}

void task2() {
    PRINT_HEADER("ЗАДАЧА 2: Игра-аналог \"Сапёр\"");

    srand(time(NULL));

    int target_value;
    int values[SIZE][SIZE];
    int opened[SIZE][SIZE];

    printf("\nВведите число-ключ (0-127): ");
    if (scanf("%d", &target_value) != 1) {
        printf("Ошибка ввода! Беру 50.\n");
        target_value = 50;
        while (getchar() != '\n');
    }
    if (target_value < 0 || target_value > MAX_VALUE) {
        printf("Вне диапазона! Беру 50.\n");
        target_value = 50;
    }

    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < SIZE; j++)
            values[i][j] = RAND_RANGE(0, MAX_VALUE);

    // Гарантируем ключ в нескольких клетках
    values[0][2] = target_value;
    values[2][4] = target_value;
    values[4][0] = target_value;
    values[3][3] = target_value;

    FILL_2D(opened, SIZE, SIZE, 0);

    // ---------- ИСХОДНЫЕ ДАННЫЕ ----------
    printf("\n");
    PRINT_LINE();
    printf("ИСХОДНЫЕ ДАННЫЕ:\n");
    PRINT_LINE();
    printf("Размер поля: %d x %d\n", SIZE, SIZE);
    printf("Число-ключ: %d\n", target_value);
    printf("\nПоле чисел в начале игры:\n");
    PRINT_NUMS(values, SIZE, SIZE);

    // ---------- РЕЗУЛЬТАТ ----------
    printf("\n");
    PRINT_LINE();
    printf("РЕЗУЛЬТАТ:\n");
    PRINT_LINE();

    int r0 = -1, c0 = -1;
    for (int i = 0; i < SIZE && r0 == -1; i++)
        for (int j = 0; j < SIZE; j++)
            if (values[i][j] == target_value) { r0 = i; c0 = j; break; }

    if (r0 == -1) {
        printf("Клеток со значением %d нет.\n", target_value);
    } else {
        printf("Пользователь открывает клетку [%d][%d] = %d.\n",
               r0 + 1, c0 + 1, target_value);
        printf("Открываются все клетки со значением %d.\n\n", target_value);

        open_all_with_value(values, opened, 0, 0, target_value);

        printf("Поле после открытия (1 — открыта, 0 — закрыта):\n");
        PRINT_FLAGS(opened, SIZE, SIZE);
    }

    PRINT_LINE();
}

#endif


// ============================================================
// ГЛАВНАЯ ФУНКЦИЯ
// ============================================================
int main() {
    setlocale(LC_ALL, "Russian");

    printf("Лабораторная работа: Рекурсивные функции\n");
    printf("Выбранная задача для компиляции: ");

#ifdef TASK1
    printf("ЗАДАЧА 1 (Фибоначчи)\n");
    task1();
#endif

#ifdef TASK2
    printf("ЗАДАЧА 2 (Сапёр)\n");
    task2();
#endif

#if !defined(TASK1) && !defined(TASK2)
    printf("НЕ ВЫБРАНА!\n");
    printf("Раскомментируйте #define TASK1 или #define TASK2 в начале файла.\n");
#endif

    printf("\nНажмите Enter для выхода...");
    getchar();
    getchar();
    return 0;
}