-1
I have the following code on C
:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Variáveis globais
int jogo_tabuleiro[9][9] = {0};
int func_quadrante(int quadrante, int numero) {
int retorno_quadrante = 0;
int linha_inicio, linha_final, coluna_inicio, coluna_final;
if(quadrante == 0) {
linha_inicio = 0;
coluna_inicio = 0;
linha_final = 2;
coluna_final = 2;
} else if(quadrante == 1) {
linha_inicio = 0;
coluna_inicio = 3;
linha_final = 2;
coluna_final = 5;
} else if(quadrante == 2) {
linha_inicio = 0;
coluna_inicio = 6;
linha_final = 2;
coluna_final = 8;
} else if(quadrante == 3) {
linha_inicio = 3;
coluna_inicio = 0;
linha_final = 5;
coluna_final = 2;
} else if(quadrante == 4) {
linha_inicio = 3;
coluna_inicio = 3;
linha_final = 5;
coluna_final = 5;
} else if(quadrante == 5) {
linha_inicio = 3;
coluna_inicio = 6;
linha_final = 5;
coluna_final = 8;
} else if(quadrante == 6) {
linha_inicio = 6;
coluna_inicio = 0;
linha_final = 8;
coluna_final = 2;
} else if(quadrante == 7) {
linha_inicio = 6;
coluna_inicio = 3;
linha_final = 8;
coluna_final = 5;
} else if(quadrante == 8) {
linha_inicio = 6;
coluna_inicio = 6;
linha_final = 8;
coluna_final = 8;
}
for(int l_i = linha_inicio; l_i <= linha_final; l_i++) {
for(int c_i = coluna_inicio; c_i <= coluna_final; c_i++) {
if(jogo_tabuleiro[l_i][c_i] == numero) {
retorno_quadrante = 1;
}
}
}
return retorno_quadrante;
}
int func_linha(int linha, int numero) {
int retorno_linha = 0;
for(int c = 0; c < 9; c++) {
if(jogo_tabuleiro[linha][c] == numero) {
retorno_linha = 1;
}
}
return retorno_linha;
}
int func_coluna(int coluna, int numero) {
int retorno_coluna = 0;
for(int l = 0; l < 9; l++) {
if(jogo_tabuleiro[l][coluna] == numero) {
retorno_coluna = 1;
}
}
return retorno_coluna;
}
void func_numeros(int numeros_quadrante) {
// Preenchendo todo o tabuleiro (quadrante por quadrante)
int linha_inicio, coluna_inicio, linha_final, coluna_final;
int quadrante_tabuleiro = numeros_quadrante;
int numero_novo;
if(quadrante_tabuleiro == 0) {
linha_inicio = 0;
coluna_inicio = 0;
linha_final = 2;
coluna_final = 2;
} else if(quadrante_tabuleiro == 1) {
linha_inicio = 0;
coluna_inicio = 3;
linha_final = 2;
coluna_final = 5;
} else if(quadrante_tabuleiro == 2) {
linha_inicio = 0;
coluna_inicio = 6;
linha_final = 2;
coluna_final = 8;
} else if(quadrante_tabuleiro == 3) {
linha_inicio = 3;
coluna_inicio = 0;
linha_final = 5;
coluna_final = 2;
} else if(quadrante_tabuleiro == 4) {
linha_inicio = 3;
coluna_inicio = 3;
linha_final = 5;
coluna_final = 5;
} else if(quadrante_tabuleiro == 5) {
linha_inicio = 3;
coluna_inicio = 6;
linha_final = 5;
coluna_final = 8;
} else if(quadrante_tabuleiro == 6) {
linha_inicio = 6;
coluna_inicio = 0;
linha_final = 8;
coluna_final = 2;
} else if(quadrante_tabuleiro == 7) {
linha_inicio = 6;
coluna_inicio = 3;
linha_final = 8;
coluna_final = 5;
} else if(quadrante_tabuleiro == 8) {
linha_inicio = 6;
coluna_inicio = 6;
linha_final = 8;
coluna_final = 8;
}
for(int l_i = linha_inicio; l_i <= linha_final; l_i++) {
for(int c_i = coluna_inicio; c_i <= coluna_final; c_i++) {
numero_novo = rand() % 9 + 1;
int verifica_quadrante = func_quadrante(quadrante_tabuleiro, numero_novo);
int verifica_linha = func_linha(l_i, numero_novo);
int verifica_coluna = func_coluna(c_i, numero_novo);
if(verifica_quadrante == 1 || verifica_linha == 1 || verifica_coluna == 1) {
c_i -= 1;
} else {
jogo_tabuleiro[l_i][c_i] = numero_novo;
}
}
}
}
void func_tabuleiro() {
for(int sla = 0; sla < 9; sla++) {
func_numeros(sla);
}
printf("|=================================|\n| - | 1 2 3 | 4 5 6 | 7 8 9 |\n|=================================|\n");
for(int linha = 0; linha < 9; linha++) {
if(linha == 3 || linha == 6) {
printf("| |---------+---------+---------|\n");
}
for(int coluna = 0; coluna < 9; coluna++) {
if(coluna == 0) {
printf("| %d |", linha + 1);
}
if(jogo_tabuleiro[linha][coluna] == 0) {
printf(" ");
} else {
printf(" %d ", jogo_tabuleiro[linha][coluna]);
}
if(coluna == 2 || coluna == 5) {
printf("|");
}
if(coluna == 8) {
printf("|\n");
}
}
if(linha == 8) {
printf("|=================================|\n");
}
}
}
main() {
srand(time(NULL)); // Inicializando função rand
func_tabuleiro();
}
My goal is to fill and solve the entire board by following the rules of the game, that is, a number (from 1 to 9) cannot be repeated in the same row, column or quadrant (3 by 3). Following my logic, it was supposed to be working, but it never resolves "first" and most of the time it goes into infinite loop. What I did was: I’m filling in quadrant by quadrant, so I can check the previous quadrants and avoid filling in the matrix with repeated numbers. Then I created three functions, one to check if the generated number already exists in a quadrant, another to check the row and the other to column (each returns 1 if the number exists and 0 if it does not exist) and use their return in the following check:
if(verifica_quadrante == 1 || verifica_linha == 1 || verifica_coluna == 1) {
c_i -= 1;
} else {
jogo_tabuleiro[l_i][c_i] = numero_novo;
}
In the above condition I check if the number already exists in any of the areas (quadrant, row or column), if the number exists it decreases from the for
referring to the column and if it does not exist it adds the number in the matrix, that is, this loop will repeat until a number is generated that does not exist in any of the areas.
I’m using the following for
within the function func_tabuleiro
:
for(int sla = 0; sla < 9; sla++) {
func_numeros(sla);
}
The code above serves to fill the nine quadrants of the matrix, quadrant by quadrant and after this for
I just draw the board.
As I said before, most of the time it enters an infinite loop, that is, I need to recompile the code several times until it can generate the board. Below is the result of the maximum quadrants he can fill (8) after several recompilations of the code (with the value for(int sla = 0; sla < 8; sla++)
), < 8
because that’s as much as he can get if I change it to < 9
, that is, to fill everything, it always stays in infinite loop (even re-running the code multiple times).
How to fix this infinite loop so that the board/matrix can always be filled in the correct way right at the first run?
Well, I don’t understand your logic, but there is even some potential to go into infinite loop there precisely because you decrease the variable
c_i
. This decrease doesn’t make much sense to me (could you try to explain it?). In a scenario where your value has just becomen
, for example, this decrease makes you becomen-1
just before returning to the loop - which will return the value ton
! What’s the point of this?– Luiz Vieira
Another potentially serious problem with your code is that the choice of numbers is random. This causes your algorithm to be nondeterministic, so it can take a long time (and appear to be an infinite loop even if it isn’t). For example, if calls from
rand()
are generating 3, 7, 9, 3, 7, 9, 3, 7, 9, 3, 7, 9... your algorithm will never finish! If your choice of algorithm is this, the most suitable is to use a list with the numbers from 0 to 9 and remove the used ones from the list.– Luiz Vieira
So, @Luizvieira, I use the decrease in the variable
c_i
for him to repeat the loop until it generates a non-existent number in the quadrant, row or column so that he can add it to the matrix. About randomness, could you explain this list of numbers better (1 to 9)? I would like it to be as random as possible...– Igor
Well, if you need to repeat keeping track of the variable
c_i
, should preferably use awhile
instead of afor
. Like I said, there’s a potential for infinite loop, I’m not saying it’s necessarily the problem. In fact, the problem most surely lies in randomness. What I suggested is that you create a list (in C a vector even fits) with the numbers from 0 to 9, arrange them randomly (read about random permutation and take a look at the last example of that page) and then use them one by one.– Luiz Vieira
Could you give an example of how to use
while
? 'Cause I’m using thefor
in order to enter the generated number in the correct position... In relation to the random permutation, I must use it for the possibility of therand()
generate equal numbers even randomly?– Igor
Colleague, sorry, this site is not a forum. If you have difficulties in building a
while
, can try asking for help on [chat]. Aboutrand
, is just that the point: randomness does not include guarantee of different numbers. If you use random permutation, ai you ensures that the numbers will be different.– Luiz Vieira