Nick_is_asking Ответов: 1

Судоку в C (палочки)


Привет всем!
Я использую C ,чтобы сделать судоку, но моя программа работает до первой строки и успешно печатает числа от 1 до 9,но вторая строка никогда не делается,потому что программа прилипает.
Я дважды проверил код,но не могу понять,где ошибка, поэтому мне нужна ваша помощь, чтобы выяснить это.

Выход:

Инициализация судоку с нулями...


0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0



Пытаюсь решить судоку...


1 5 3 4 6 8 2 9 7
и вот программа застревает(навсегда) Я полагаю...


Код:

Что я уже пробовал:

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

int check_all_laws(int (*array)[9] , int row , int column , int number);
void initialization_array(int (*array)[9]);
int check_rows(int (*array)[9] , int column , int number);
int check_columns(int (*array)[9] , int row , int number);
int check_square_3_3(int (*array)[9] , int number);
int check_all_laws(int (*array)[9] , int row , int column , int number);
void solve_array_random(int (*array)[9]);

int main(void)
{
    srand(time(NULL));
    int array[9][9] = {{0}};
    printf("\n\nInitializing sudoku with zeros...\n\n\n");
    initialization_array(array);
    printf("\n\n\n");
    printf("Trying to solve sudoku...\n\n\n");
    solve_array_random(array);
    printf("\n\n\nSudoku is solved succesfully !\n\n\n");
}

void initialization_array(int (*array)[9])
{
    for(int i = 0; i < 9; i++)
    {
        for(int j = 0; j < 9; j++)
        {
            printf("%d " , array[i][j]);
        }
        printf("\n");
    }
}

void solve_array_random(int (*array)[9])
{
    int random;
    for(int i = 0; i < 9; i++)
    {
        for(int j = 0; j < 9; j++)
        { 
            random = (rand() % 9) + 1;
            while(check_all_laws(array , i , j , random) == 0)
            {
                random = (rand() % 9) + 1;
            }
            array[i][j] = random;

            printf("%d " , array[i][j]);
        }
        printf("\n");
    }
}

int check_rows(int (*array)[9] , int column , int number)
{
    int is_ok = 1;
    for(int i = 0; i < 9; i++)
    {
        if(array[i][column] == number)
        {
            is_ok = 0;
        }
    }
    return is_ok;
}


int check_columns(int (*array)[9] , int row , int number)
{
    int is_ok = 1;
    for(int i = 0; i < 9; i++)
    {
        if(array[row][i] == number)
        {
            is_ok = 0;
        }
    }
    return is_ok;
}


int check_square_3_3(int (*array)[9] , int number)
{
    int is_ok = 1;
    int k = 3;
    int l = 0;
    int m = 0;
    int n = 3;

    for(int i = l; i < k; i++)
    {
        for(int j = m; j < n; j++)
        {
            if(array[i][j] == number)
            {
                is_ok = 0;
            }
        }
        k += 3;
        l += 3;
        if(k == 9)
        {
            m += 3;
            n += 3;
            l = 0;
            k = 3;
        }
    }
    return is_ok;
}

int check_all_laws(int (*array)[9] , int row , int column , int number)
{
    int all_ok = 0;
    if(check_rows(array , column , number) && check_columns(array , row , number) && check_square_3_3(array , number))
    {
        all_ok = 1;
    }
    return all_ok;
}



Заранее спасибо! :)

jeron1

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

Rick York

Использование буквального значения 9 везде - плохая идея. Следует избегать использования литеральных значений. Что, если бы вас попросили написать игру судоку, которая работает в шестнадцатеричном формате? или используются значения от 0 до 9? Хлоп.

Вы должны определить значение const, такое как GameSize, чтобы удерживать это число - 9 или 10 или то, что вы хотите использовать для него. Вы можете попробовать свою программу на меньших размерах, таких как 4 или 5, Если хотите, просто чтобы начать работу. Вопрос в том, почему он должен быть зафиксирован на значениях от 1 до 9 или от 0 до 8? Как насчет 0-9 (10 предметов) или 0-9 & A-F (16 предметов) или быть еще более странным 0-9 & A-Z (36 предметов)? Поскольку машина решает их, вы должны дать ей шанс.

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

1 Ответов

Рейтинг:
7

Patrice T

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

Довольно просто, вы кодируете, чтобы solve_array_random попал в ловушку (бесконечный цикл), когда он достигнет точки, где следующую ячейку невозможно заполнить из-за предыдущих ячеек.
Посмотреть на это
1 2 3 4 5 6 7 8 9
4 5 6 1 2 3 x

x невозможно заполнить, соблюдая правила.
Виноват-это:
void solve_array_random(int (*array)[9])
{
    int random;
    for(int i = 0; i < 9; i++)
    {
        for(int j = 0; j < 9; j++)
        { 
            random = (rand() % 9) + 1;
            while(check_all_laws(array , i , j , random) == 0)
            { // this loop never ends when a cell is impossible to fill
                random = (rand() % 9) + 1;
            }
            array[i][j] = random;

            printf("%d " , array[i][j]);
        }
        printf("\n");
    }
}

Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что должен делать ваш код, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]

1.11 — отладка программы (пошаговое выполнение и останова) | выучить C++[^]

Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.


Nick_is_asking

Спасибо,я постараюсь ,потому что не понимаю, почему это происходит...

Patrice T

Посмотрите на мой пример, на x, никакое число невозможно из-за правил, и в этом случае ваш код бесконечно петляет.