Ver Mensaje Individual
  #2 (permalink)  
Antiguo 16/05/2011, 15:31
yochiwarez
 
Fecha de Ingreso: enero-2009
Mensajes: 7
Antigüedad: 15 años, 3 meses
Puntos: 0
Respuesta: Necesito entender este codigo de Sudoku en C++

Bueno , me respondo a mi mismo, después de trabajar mucho logre crear el código que genera el tablero de sudoku, tal vez no es la mejor forma pero funciona, espero que a alguien le sirva..

Código:
// sudoku a.cpp: define el punto de entrada de la aplicación de consola.

#include "stdafx.h"
#include "math.h"//funciones matematicas , en este caso ceil
#include "cstdlib"//para numeros random
#include "ctime"//para la hora
#include "iostream"
using namespace std;

//funcion que comprueva el array en cruz
bool checkrep(int num[9][9],int n, int f, int c)
{
	bool rp=false;

		for(int i=0; i<9; i++)
		{
			if(n == num[f][i])
				rp=true;
		}

		if(rp==false)
		{
			for(int i=0; i<9; i++)
			{
				if(n == num[i][c])
					rp=true;
			}
		}

    return rp;

}

//sedecha el numero que le indiquemos
void Desechar(int num[9][9],int n)
{
	for(int i=0;i<=9;i++)
		for(int j=0;j<=9;j++)
			if(num[i][j]==n)
				num[i][j]=0;
}

//funcion que inicializa el array
void InitArray(int num[9][9])
{
	for(int l=0; l<9; l++)
    {
		for(int j=0;j<9;j++)
		{
		    num[l][j]=0;
		}
    }
}

//funcion que dibuja el sudoku
void ShowArray(int num[9][9])
{
	for(int l=0; l<9; l++)
    {
		if(l%3==0 && l>0)
		{	
			for(int i=1;i<=21;i++)
				cout<<"=";
			cout<<endl;
		}
		for(int j=0;j<9;j++)
		{
			if(j%3==0 && j>0)
				cout<<"| ";
			if(num[l][j]!=0)
				cout<<num[l][j]<<" ";
			else
				cout<<"- ";
		}

		cout<<endl;
	}

	cout<<endl;
}



int _tmain(int argc, _TCHAR* argv[])
{

	srand(time(NULL));//para que los numeros aleatorios no se repitan
    int n,m, num[9][9],pos[9];
	int size;

	//rellenar el sudoku del 1 al 8;
comienza:

	InitArray(num);//incializa el array en 0

	int cont;//para contar reintentos
	
	int d=1;//numero que ecribiremos d
	while(d<=8)
	{
		cont=0;
reintento:

		//se recorre la tabla de 3 en 3;
		for(int i=0; i<=6; i+=3)
		{
			for(int j=0;j<=6;j+=3)
			{
		
				//inicializa el array de las posiciones en 0
				for(int s=0;s<=8;s++)
					pos[s]=0;
				
				//busca posiciones posibles y las almacena en un array 9
				//las almacena del 1 al nueve, representando su posicion en la region
				// 1 2 3 
				// 4 5 6 
				// 7 8 9

				int ind=1;
				int elem=1;
				for(int k=0;k<=2;k++)
					for(int l=0;l<=2;l++)
					{
							if(num[i+k][j+l]==0)
							{
								pos[ind-1]=elem;
								ind++;
							}
							elem++;
					}

				size=ind-1;


				//seleciona una posicion aleatoriamente del array
				int fe,ce,indc,ele;
				float ff;
				bool salir=false;

				int count=0;

				while(salir==false && size>0)
				{
					//genera un indice aleatorio
					indc=rand()%size;
					ele=pos[indc];

					
					//elimina la posicion del array para evitar que se repita
					while(indc<size-1)
					{
						pos[indc]=pos[indc+1];
						pos[indc+1]=0;
						indc++;
					}

					//ahora hay ke convertir esos numeros a 
					//posiciones, lo hago con ceil y mod...
					//dividiendo el numero entre 3 y con ceil tendremos 111222333
					//calculamos la posicion del elemento
					ff=ele;
					fe=ceil(ff/3)-1;//fila del elemento

					//con mod tendremos 120120120
					//entonces convertimos el 0 en 3;
					ce=ele%3;
					if(ce==0)
						ce=3;
					ce--;//columna del elemento
					
					//a ambos le restamos 1 y tenemos la posicion

					//crequea ke no haygan repetiodos en la fila y columna
					if(checkrep(num,d,i+fe,j+ce)==false)
					{
						//si no hay repetidos escribe el numero y sale del bucle que busca posiciones
						salir=true;
						//aca sumo la posicion de la regin mas la posicion aleatoria
						num[i+fe][j+ce]=d;
					}

					//se reduce el tamaño del array de posiciones
					size--;

					//si ya no existen mas posiciones reintenta de nuevo esto evita que se atasque
					if(size==0)
					{
						Desechar(num,d);
						cont++;

						//si reintenta con un numero mas de 20 veces reinicia la creacion del sudoku
						//le puse 20 porque generalmente se atascaba en el 8, quedando dos posiciones
						//libres en cada region, que al multiplicarlas por 9 son 18 posiciones..
						if(cont>20)
							goto comienza;

						goto reintento;
					}

				}

			}
		}
		d++;
	}

	//rellena los espacios vacios con 9 ves;
	for(int i=0;i<=9;i++)
		for(int j=0;j<=9;j++)
			if(num[i][j]==0)
				num[i][j]=9;

	//muestra el sudoku
	cout<<"Sudoku de YochiWarez 16/05/2011"<<endl<<endl;
	ShowArray(num);
	system("pause");
	
	return 0;
}