На шахматной доске определите поля, в которые может попасть конь за n ходов из указанной позиции

Рейтинг: 0Ответов: 1Опубликовано: 16.03.2023

Задание: На шахматной доске определите поля, в которые может попасть конь за n ходов из указанной позиции.

У меня почему-то выходит неправильно, если я считаю сама на шахматной доске. Мне нужно распечатать с х и у , а также как на доске это выглядит. Шаги все отражать, включая последний n шаг.

Подскажите, в чем ошибка, как надо описывать, себе пометила комментарии (может я неправильно пометила комментарии, подскажите).

#include <iostream>
#include <math.h>
using namespace std;

bool prov(int x, int y, int razm) //проверяем правильную позицию квадратов коня
{
    return ((x >= 0) && (y >= 0) && (x < razm) && (y < razm));
}

void func(int** doska, int kon_x, int kon_y, int razm, int step)
{
    // Условие выхода из рекурсии
    if (step == 0)
    {
        doska[kon_y][kon_x] = 1;
        return;// Не нужно возвращать значение функции, так как меняется только состояние доски, а доска одна
    }
    
    // Количество возможных ходов 8
    int new_x[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
    int new_y[8] = { -1, 1, -2, 2, -2, 2, -1, 1 };
    
    // А теперь их перебираем
    for (int i = 0; i < 8; i++)
    {
        int x = kon_x + new_x[i];
        int y = kon_y + new_y[i];
        
        // Если новая позиция корректная
        if (prov(x, y, razm))
        {
            //doska[y][x] = 1, то делаем рекурсивный вызов
            func(doska, x, y, razm, step - 1);
        }
        
    }
}

int main()
{
    setlocale(LC_ALL, "Russian");
    int n, kon_x, kon_y, step;
    
    cout << "Введите размер поля: " ;
    cin >> n;
    while (n <= 0)
    {
        cin.clear();
        while (cin.get() != '\n');
        cout << "Неверно. Введите размер поля снова: ";
    }
    
    int** doska = new int* [n];
    for (int i = 0; i < n; i++)
        doska[i] = new int[n];
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            doska[i][j] = 0;
    }
    
    cout << "Введите позицию лошади:" << endl;
    cout << "номер строки x = ";
    cin >> kon_x;
    cout << "номер столбца y = ";
    cin >> kon_y;
    while ((kon_x <= 0) || (kon_y <= 0))
    {
        cin.clear();
        while (cin.get() != '\n');
        cout << "Неверно. Введите положение лошади снова: ";
    }
    
    // Уменьшается на единицу каждый индекс, так как пользователь считает с 1, а я с 0
    kon_x--;
    kon_y--;
    cout << "Введите количество шагов: ";
    cin >> step;
    while (step <= 0)
    {
        cin.clear();
        while (cin.get() != '\n');
        cout << "Неверно. Введите количество шагов снова: ";
    }
    
    func(doska, kon_x, kon_y, n, step); // печать с х и у
    for (int i = 0; i < n; i++)
    {
        cout << " " << endl;
        for (int j = 0; j < n; j++)
        {
            if (doska[i][j] == 1)
                cout << "x = " << j + 1 << " " << "y = " << i + 1 << endl;
        }
        cout << endl;
    }
    
    func(doska, kon_x, kon_y, n, step); // печать как на шахматной доске
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cout << doska[i][j] << " ";
        }
        cout << endl;
    }
    
    system("pause");
    return 0;
}

Ответы

▲ 1

Да, вы неправильно поставили комментарии. Вот тут вы закомментировали нужную операцию.

// Если новая позиция корректная
if (prov(x, y, razm))
{
    //doska[y][x] = 1, то делаем рекурсивный вызов  --- ошибка!!!

    // должно быть так
    doska[y][x] = 1; // то делаем рекурсивный вызов
    func(doska, x, y, razm, step - 1);
}

Ещё вы в main() дважды вызываете func(). Это не приводит к неправильным результатам, просто программа работает 2 раза дольше.

    ....
    func(doska, kon_x, kon_y, n, step); // печать с х и у       --- !!!
    for (int i = 0; i < n; i++)
    {
        ....
    }
    
    func(doska, kon_x, kon_y, n, step); // печать как на шахматной доске --- !!!
    for (int i = 0; i < n; i++)
    {
        ....
    }

Неправильно написана проверка. Если числа отрицательные - получится вечный цикл.

    cin >> n;
    while (n <= 0)
    {
        cin.clear();
        while (cin.get() != '\n');
        cout << "Неверно. Введите размер поля снова: ";
    }

Такая же ошибка с проверкой первоначальных координат фигуры и количества шагов.
Наверное все же стоит ограничить размер доски. Ну по крайней мере количеством символов в строке - чтобы можно было напечатать вашу доску. Или просто сказать, что размер = 8.

Нет проверки, что введенное положение фигуры находится на доске - из-за этого будет выход за пределы массива - это UB и программа рухнет (если повезет).

Ну и по мелочам:
Шахматная фигура называется "конь"

cout << "Введите позицию лошади:" << endl;
cout << "Неверно. Введите положение лошади снова: ";

И в шахматах сначала говорят позицию строки а потом столбца, а у вас наоборот.

doska[kon_y][kon_x] = 1;
doska[y][x] = 1;