Eu fiz um Sudoku em C que tá funcionando perfeitamente com exceção do problema com as células da tabela que já começam com o valor definido, ou mais conhecidas como "dicas".
O objetivo do Sudoku é você completar toda a tabela usando somente e tão somente raciocínio e dedução lógica. Ou seja, nunca, jamais precisando de adivinhação. Mas com esse programa que eu fiz, na grande maioria das vezes o usuário precisa recorrer à adivinhação, e isso é errado.
A solução pra isso é mudar a programação fazendo com que quando o jogo começa, a disposição dessas células que já começam com o valor preenchido permita que o usuário chegue até o final sem que precise adivinhar nada.
Mas como eu faço isso?
Segue o meu algoritmo:
Obs.: Um jogo desse numa revistinha ou jornal costuma começar com 25 à 30 dicas iniciais. O meu tem 36 e ainda dá esse problema (veja a seção do algoritmo escrito "Definido os números dado pelo jogo").
Obs. 2: Fiz esse algoritmo no Turbo C.
Obs. 3: Execute em tela cheia, senão fica horrível!
#include <conio.h>
#include <stdlib.h>
void main ()
{
unsigned char dialogo1[1078], dialogo2[1196], tela[8000], i, j, k, l, x, y;
randomize ();
/*Parte visual do algoritmo*/
/*Guardando as caixas de di logo em vari veis*/
textattr (1<< 4 | 6);
clrscr ();
_setcursortype (_NOCURSOR);
textbackground (0);
window (2, 2, 48, 10);
clrscr ();
window (2, 12, 45, 22);
clrscr ();
window (3, 7, 44, 19);
cputs (" im ao\n\n\n\n\n\n\rParab‚ns! Vocˆ ‚ muito"
" foda! Varou o jogo!\n Gostaria de come‡ar um novo jogo?\n\n\n\n\r "
" im ao");
textcolor (4);
gotoxy (13, 1);
cputs ("S");
gotoxy (31, 1);
cputs ("N");
gotoxy (12, 13);
cputs ("S");
gotoxy (29, 13);
cputs ("N");
gettext (1, 1, 49, 11, dialogo1);
gettext (1, 11, 46, 23, dialogo2);
/**/
/*Guardando a tela principal numa vari vel*/
window (1, 1, 80, 50);
clrscr ();
textcolor (6);
window (23, 2, 57, 7);
cputs ("ÜÛÛÛÛ Û Û ÛÛÛÜ ÜÛÛÛÜ Û Û Û ÛÛ Û Û Û ÛÜ Û Û Û ÜÛß Û "
"ÛßÛÛÛÜ Û Û Û Û Û Û ÛÛÛ Û Û Û Û Û Û Ûß Û Û Û ßÛÜ Û ÛÛÛÛÛß"
" ßÛÛÛß ÛÛÛß ßÛÛÛß Û Û ßÛÛÛß");
window (1, 8, 19, 48);
textcolor (7);
cputs ("\nO objetivo do jogo ‚ completar toda a tabela de modo que todas as "
"linhas, colunas e blocos 3x3 contenham todos os n£meros de 1 … 9 sem que "
"qualquer um deles repitem ou faltem\n\n\n\n\r C‚lula "
"selecionada pelo usu rio\n\n\n\r Linha, coluna e bloco "
" correspondentes … c‚lula selecionada pelo usu rio\n\n\n\n\r C‚lula com "
"n£mero dado pelo jogo\n\n\n\r C‚lulacom n£mero certeza "
"ajustado pelo usu rio\n\n\n\r N£mero iluminado pela "
" ferramenta \"Iluminar todos\"");
gotoxy (6, 1);
textcolor (1);
cputs ("OBJETIVO\n\n\n\n\n\n\n\n\n\n\n\n\r LEGENDA\n\r");
textcolor (11);
cputs (" C‚lula com borda vermelha:\n\n\n\n\r C‚lula com borda pontilhada:"
"\n\n\n\n\n\n\r C‚lula com cor de fundo amarela:\n\n\n\n\r C‚lula com cor "
"de fundo verde:\n\n\n\n\n\rN£mero iluminado de vermelho:");
window (61, 9, 80, 25);
textcolor (7);
cputs ("\n\n\n Inserir/remover n£mero possibilidade\n\r "
"Inserir n£mero certeza\n\n\r Limpar c‚lula\n\n\r "
" Acessar ferramenta \"Iluminar todos\"\n\n\r Ligar/desligar "
"\"Iluminar todos\"");
gotoxy (7, 1);
textcolor (1);
cputs ("COMANDOS\n\r");
textcolor (11);
cputs (" 1 … 9:\n\n\n\n\rAlt + 1 … 9:\n\n\n\r Delete:\n\n\n\r Tab:"
"\n\n\n\n\r I:");
textattr (1<< 4 | 6);
window (20, 8, 60, 48);
clrscr ();
window (62, 28, 79, 47);
clrscr ();
window (1, 50, 80, 50);
clrscr ();
cputs (" Novo Jogo Reiniciar jogo "
"Sair");
textcolor (4);
gotoxy (8, 1);
cputs ("F2");
gotoxy (32, 1);
cputs ("F3");
gotoxy (63, 1);
cputs ("ESC");
textattr (11);
window (22, 10, 32, 21);
cputs (" Û Û Û Û Û Û ÛÛÛÛÛÛÛÛÛÛÛ Û Û Û Û "
"Û Û ÛÛÛÛÛÛÛÛÛÛÛ Û Û Û Û Û Û ");
gettext (22, 10, 32, 20, tela);
puttext (35, 10, 45, 20, tela);
puttext (48, 10, 58, 20, tela);
gettext (22, 10, 58, 20, tela);
puttext (22, 23, 58, 33, tela);
puttext (22, 36, 58, 46, tela);
window (63, 29, 78, 46);
clrscr ();
cputs ("\n\n\n\n ÛÛÛÛÛ Û Û Û Û Û Û "
" ÛÛÛÛÛ\n\n\r ÛÛÛ\n\r Û Û\n\r ÛÛÛ\n\n\r ÛÛÛ\n\r Û Û\n\r ÛÛÛ");
textcolor (6);
gotoxy (2, 2);
cputs ("Iluminar todos os n£meros:");
gotoxy (6, 12);
cputs ("Ligado");
gotoxy (6, 16);
cputs ("Desligado");
gettext (1, 1, 80, 50, tela);
/**/
/**/
/*L¢gica central do algoritmo*/
inicio:
unsigned char sud[81][10], resp[81];
/*Atribuindo todos os n£meros possibilidades pras c‚lulas*/
for (i= 0; i< 81; i++)
{
sud[i][0]= 10;
for (j= 1; j< 10; j++)
sud[i][j]= j;
}
/**/
/*Sorteando um n£mero certeza pra cada c‚lula*/
for (i= 0; i< 81; i++)
{
if (!sud[i][2])
continue;
if (sud[i][0]> 2)
sud[i][1]= sud[i][random (sud[i][0]-1)+1], sud[i][0]= 2;
/**/
/*Eliminando os n£meros possibilidades das outras c‚lulas*/
/*Na linha*/
if (i%9< 6)
for (j= i+1; j%9; j++)
{
if (j%9/3== i%9/3)
continue;
for (k= 1; k< sud[j][0]; k++)
if (sud[j][k]== sud[i][1])
{
sud[j][0]--, sud[j][k]= sud[j][sud[j][0]];
break;
}
}
/**/
/*Na coluna*/
if (i/9< 6)
for (j= i+9; j< 81; j+= 9)
{
if (j/9/3== i/9/3)
continue;
for (k= 1; k< sud[j][0]; k++)
if (sud[j][k]== sud[i][1])
{
sud[j][0]--, sud[j][k]= sud[j][sud[j][0]];
break;
}
}
/**/
/*No bloco*/
if (i%9%3< 2)
j= i+1;
else
j= i+7;
for (; j/9/3== i/9/3;)
{
for (k= 1; k< sud[j][0]; k++)
if (sud[j][k]== sud[i][1])
{
sud[j][0]--, sud[j][k]= sud[j][sud[j][0]];
break;
}
if ((j+1)%3)
j++;
else
j+= 7;
}
/**/
/**/
/*Procurando c‚lulas com s¢ um n£mero possibilidade*/
for (j= i+1; j< 81; j++)
{
if (sud[j][0]== 2 && sud[j][2])
{
sud[j][2]= 0;
/**/
/*Eliminando os n£meros possibilidades das outras c‚lulas*/
/*Na linha*/
for (k= j/9*9; k%9 || k== j/9*9; k++)
{
if (sud[k][0]< 2 || !sud[k][2] || k%9/3== j%9/3)
continue;
for (x= 1; x< sud[k][0]; x++)
if (sud[k][x]== sud[j][1])
{
sud[k][0]--, sud[k][x]= sud[k][sud[k][0]];
break;
}
}
/**/
/*Na coluna*/
for (k= j%9; k< 81; k+= 9)
{
if (sud[k][0]< 2 || !sud[k][2] || k/9/3== j/9/3)
continue;
for (x= 1; x< sud[k][0]; x++)
if (sud[k][x]== sud[j][1])
{
sud[k][0]--, sud[k][x]= sud[k][sud[k][0]];
break;
}
}
/**/
/*No bloco*/
for (k= j/9/3*27+j%9/3*3; k/9/3== j/9/3;)
{
if (sud[k][0]> 1 && sud[k][2])
for (x= 1; x< sud[k][0]; x++)
if (sud[k][x]== sud[j][1])
{
sud[k][0]--, sud[k][x]= sud[k][sud[k][0]];
break;
}
if ((k+1)%3)
k++;
else
k+= 7;
}
/**/
/**/
j= i;
}
else if (sud[j][0]== 1)
goto inicio;
}
}
/*Copiando o resultado final pra matriz resp*/
for (i= 0; i< 81; i++)
resp[i]= sud[i][1], sud[i][0]= 0;
/**/
/*Definindo os n£meros dados pelo jogo*/
for (i= 0; i< 36;)
if (sud[j= random (81)][0]!= 61)
sud[j][0]= 61, i++;
/**/
/**/
/*Jogo jogado*/
for (i= 40, x= 0, y= 11;;)
{
/*Imprimindo a tela principal*/
puttext (1, 1, 80, 50, tela);
window (1, 1, 80, 50);
gotoxy (70, 35);
textattr (6);
cprintf ("%d", y%10);
gotoxy (65, y/10*4+40);
textcolor (4);
cputs ("Û");
/**/
/*Imprimindo os n£meros da tabela*/
for (j= 0; j< 81; j++)
{
window (22+j%9*4+j%9/3*1, 10+j/9*4+j/9/3*1, 24+j%9*4+j%9/3*1, 13+j/9*4+j/9
/3*1);
textbackground (sud[j][0]/10);
if (sud[j][0]< 10)
textcolor (6);
else
textcolor (0);
for (k= 1; k< sud[j][0]%20+1 || k== 1; k++)
{
if (!sud[j][0])
cputs (" ");
else if (sud[j][0]%20== 1)
cputs (" ");
else if (((sud[j][0]== 2 || sud[j][0]== 3) && k== 1) ||
(sud[j][0]== 4 && k== 3) || (sud[j][0]== 6 && k== 4))
cputs (" ");
else if (sud[j][0]== 2 || (sud[j][0]== 4 && !(k%2)) ||
(sud[j][0]== 5 && k!= 1) || (sud[j][0]== 7 && (k== 4 || k== 5))
|| (sud[j][0]== 8 && k== 5))
cputs (" ");
if (sud[j][0] && sud[j][k]!= y)
cprintf ("%d", sud[j][k]);
else if (sud[j][0])
{
textbackground (4);
cprintf ("%d", sud[j][k]);
textbackground (sud[j][0]/10);
}
if (sud[j][0]%20== 1)
cputs (" ");
else if ((sud[j][0]== 2 && k!= 1) || (sud[j][0]== 3 && k== 3))
cputs (" ");
}
}
/**/
/*Usu rio na tabela*/
if (i< 81)
/*Destacando a c‚lula selecionada e a linha,
coluna e bloco correspondentes … essa c‚lula*/
{
textattr (1<< 4 | 6);
window (21+i%9/3*13, 9+i/9/3*13, 33+i%9/3*13, 22+i/9/3*13);
cputs ("úúúúúúúúúúúúúú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú"
"\n\rúúúúúúúúúúúúú");
window (33+i%9/3*13, 10+i/9/3*13, 33+i%9/3*13, 21+i/9/3*13);
cputs ("úúúúúúúúúúú");
window (21+i%9*4+i%9/3*1, 9, 25+i%9*4+i%9/3*1, 48);
cputs ("úúúúúú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\r"
"ú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú"
"\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rú\n\rúúúúú");
window (25+i%9*4+i%9/3*1, 10, 25+i%9*4+i%9/3*1, 47);
cputs ("úúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúú");
window (21, 9+i/9*4+i/9/3*1, 59, 14+i/9*4+i/9/3*1);
cputs ("úúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúú\n\rú\n\rú\n\rúúúúúúúúúúú"
"úúúúúúúúúúúúúúúúúúúúúúúúúúúú");
window (59, 10+i/9*4+i/9/3*1, 59, 13+i/9*4+i/9/3*1);
cputs ("úúú");
textcolor (4);
window (21+i%9*4+i%9/3*1, 9+i/9*4+i/9/3*1, 25+i%9*4+i%9/3*1, 14+i/9*4+i/9/
3*1);
cputs ("ÛÛÛÛÛÛ\n\rÛ\n\rÛ\r\nÛÛÛÛÛ");
window (25+i%9*4+i%9/3*1, 10+i/9*4+i/9/3*1, 25+i%9*4+i%9/3*1, 13+i/9*4+i/9
/3*1);
cputs ("ÛÛÛ");
/**/
/*Conferindo a quantidade de acertos*/
for (j= 0, k= 0; j< 81; j++)
if (sud[j][0]%20== 1 && sud[j][1]== resp[j])
k++;
/**/
/*Jogo varado*/
if (k== 81)
for (i= 1;;)
{
/*Imprimindo caixa de di logo de jogo varado*/
puttext (18, 19, 63, 31, dialogo2);
for (j= 0; j< 2; j++)
{
if (j== i)
textcolor (4);
else
textcolor (11);
window (29+j*17, 25, 35+j*17, 30);
cputs ("ÛÛÛÛÛÛÛÛ\n\rÛ\n\rÛ\r\nÛÛÛÛÛÛÛ");
window (35+j*17, 26, 35+j*17, 30);
cputs ("ÛÛÛ");
}
/**/
/*Comandos no jogo varado*/
for (k= 0; j= getch (), j!= 13 && j!= 115 && j!= 110 && j!= 83 &&
j!= 78;)
if (!j)
{
k= getch ();
if (k== 75 || k== 77 || k== 107)
break;
else
k= 0;
}
if ((j== 13 && i) || j== 110 || j== 78 || k== 107)
exit (0);
else if (k)
i= (i+1)%2;
else
goto inicio;
/**/
}
/**/
/*Comandos na tabela*/
if (!x)
{
for (k= 0; j= getch (), (!(j> 48 && j< 58) && j!= 27 && j!= 9 && j!=
105 && j!= 8 && j!= 63 && j!= 170 && j!= 73 && j!= 189 && j!= 156 &&
!(j> 250 && j< 254)) || (((j> 48 && j< 58) || j== 8 || j== 63 || (j>
250 && j< 254) || j== 170 || j== 189 || j== 156) && sud[i][0]== 61) ||
(j== 8 && !sud[i][0]) || ((((j== 63 || j== 251) && sud[i][1]== 1) ||
(j== 170 && sud[i][1]== 6) || (j== 189 && sud[i][1]== 5) || (j== 156
&& sud[i][1]== 4) || (j== 252 && sud[i][1]== 3) || (j== 253 &&
sud[i][1]== 2)) && sud[i][0]== 21);)
if (!j)
{
k= getch ();
if (k== 75 || k== 77 || k== 72 || k== 80 || ((k> 120 && k< 129) &&
sud[i][0]!= 61 && (sud[i][0]!= 21 || k-119!= sud[i][1])) || (k==
83 && sud[i][0]!= 61 && sud[i][0]) || k== 60 || k== 61 || k== 107)
break;
else
k= 0;
}
if (k== 75)
if (i%9)
i--;
else
i+= 8;
else if (k== 77)
i= i/9*9+(i+1)%9;
else if (k== 72)
if (i/9)
i-= 9;
else
i+= 72;
else if (k== 80)
i= (i+9)%81;
else if ((k> 120 && k< 129) || j== 63 || (j> 250 && j< 254) ||
j== 170 || j== 189 || j== 156)
{
if (k> 120 && k< 129)
sud[i][1]= k-119;
else if (j== 63 || j== 251)
sud[i][1]= 1;
else if (j== 170)
sud[i][1]= 6;
else if (j== 189)
sud[i][1]= 5;
else if (j== 156)
sud[i][1]= 4;
else if (j== 252)
sud[i][1]= 3;
else
sud[i][1]= 2;
sud[i][0]= 21;
}
else if (j> 48 && j< 58)
{
for (l= 1; l< sud[i][0]%20+1; l++)
if (j-'0'== sud[i][l])
break;
if (l== sud[i][0]%20+1)
sud[i][0]= sud[i][0]%20+1, sud[i][sud[i][0]]= j-'0';
else
{
for (; l< sud[i][0]%20+1; l++)
sud[i][l]= sud[i][l+1];
sud[i][0]= sud[i][0]%20-1;
}
}
else if (j== 27)
x= 1;
else if (j== 9)
i+= 81;
else if (j== 105 || j== 73)
y= (y+10)%20;
else if (j)
sud[i][0]= sud[i][0]%20-1;
else if (k== 83)
sud[i][0]= 0;
else if (k!= 107)
x= k-58;
else
exit (0);
}
/**/
}
/**/
/*Usu rio no "Iluminar todos"*/
else
{
/*Selecionando a c‚lula
do "Iluminar todos"*/
textcolor (4);
window (68, 33, 72, 38);
cputs ("ÛÛÛÛÛÛ\n\rÛ\n\rÛ\n\rÛÛÛÛÛ");
window (72, 34, 72, 38);
cputs ("ÛÛÛ");
/**/
/*Comandos no "Iluminar todos"*/
for (k= 0; j= getch (), (!(j> 48 && j< 58) && j!= 9 && j!= 27 && j!=
105 && j!= 73) || (j-48== y);)
if (!j)
{
k= getch ();
if (k== 60 || k== 61 || k== 107)
break;
else
k= 0;
}
if (j> 48 && j< 58)
y= j-'0';
else if (j== 27 || j== 9)
i-= 81;
else if (k== 60)
x= 2;
else if (k== 61)
x= 3;
else if (k)
exit (0);
else
y= (y+10)%20;
/**/
}
/**/
/*Usu rio nas caixas de di logo*/
if (x)
for (l= 0; x;)
/*Imprimindo uma caixa de di logo*/
{
puttext (16, 20, 64, 30, dialogo1);
window (18, 22, 63, 22);
textattr (6);
if (x== 1)
cputs (" Tem certeza de que quer sair do jogo?");
else if (x== 2)
cputs ("Tem certeza de que quer come‡ar um novo jogo?");
else
cputs (" Tem certeza de que quer reiniciar o jogo?");
for (j= 0; j< 2; j++)
{
if (j== l)
textcolor (4);
else
textcolor (11);
window (28+j*18, 24, 34+j*18, 29);
cputs ("ÛÛÛÛÛÛÛÛ\n\rÛ\n\rÛ\r\nÛÛÛÛÛÛÛ");
window (34+j*18, 25, 34+j*18, 29);
cputs ("ÛÛÛ");
}
/**/
/*Comandos nas caixas de di logo*/
for (k= 0; j= getch (), j!= 13 && j!= 27 && j!= 115 && j!= 110 && j!=
83 && j!= 78;)
if (!j)
{
k= getch ();
if (k== 75 || k== 77 || k== 107)
break;
else
k= 0;
}
if ((j== 13 && !l) || j== 115 || j== 83 || k== 107)
{
if (x== 1 || k== 107)
exit (0);
else if (x== 2)
goto inicio;
else
{
for (i= 0; i< 81; i++)
if (sud[i][0]!= 61)
sud[i][0]= 0;
i= 40, x= 0, y= 11;
}
}
else if (j)
x= 0;
else
l= (l+1)%2;
/**/
}
/**/
}
/**/
}
Pergunta
Ricardo Martins
Eu fiz um Sudoku em C que tá funcionando perfeitamente com exceção do problema com as células da tabela que já começam com o valor definido, ou mais conhecidas como "dicas".
O objetivo do Sudoku é você completar toda a tabela usando somente e tão somente raciocínio e dedução lógica. Ou seja, nunca, jamais precisando de adivinhação. Mas com esse programa que eu fiz, na grande maioria das vezes o usuário precisa recorrer à adivinhação, e isso é errado.
A solução pra isso é mudar a programação fazendo com que quando o jogo começa, a disposição dessas células que já começam com o valor preenchido permita que o usuário chegue até o final sem que precise adivinhar nada.
Mas como eu faço isso?
Segue o meu algoritmo:
Obs.: Um jogo desse numa revistinha ou jornal costuma começar com 25 à 30 dicas iniciais. O meu tem 36 e ainda dá esse problema (veja a seção do algoritmo escrito "Definido os números dado pelo jogo").
Obs. 2: Fiz esse algoritmo no Turbo C.
Obs. 3: Execute em tela cheia, senão fica horrível!
Editado por Ricardo MartinsLink para o comentário
Compartilhar em outros sites
0 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.