Click here to Skip to main content
15,881,852 members
Articles / Desktop Programming / MFC

Solve the Pentomino puzzle with C++ and dancing links

Rate me:
Please Sign up or sign in to vote.
4.80/5 (22 votes)
2 Dec 2011CPOL11 min read 121K   3.1K   37  
Program to find all the solutions to a Pentomino puzzle.
#include "stdafx.h"
#include "CPuzzleSolver.h"
#include "../Globals.h"

void CPuzzleSolver::SolvePuzzle()
{
	soluciones.clear();
	
	board.InitPiezasDisp();
	board.Init();

	board.Ancho = ANCHO;
	board.Alto = ALTO;
	board.ClearContenido();
	
	Termino = FALSE;
	while (!Termino && IsProcessing)
		HacerMovida();
}

void CPuzzleSolver::HacerMovida()
{
	CNodo* nodo = &(board.nodos[board.inodo]);

	//Verifico si tengo que ir para atras
	if (nodo->Index == board.vecpiezas.size())
	{
		//Debo eliminar el nodo
		board.inodo--;
		
		if (board.inodo < 0)
		{
			Termino = TRUE;
			return;
		}
		nodo->SetToNull();

		//Obtengo el nodo anterior
		CNodo* nodoant = &(board.nodos[board.inodo]);
		//Obtengo la pieza del nodo anterior
		CPieza* pieza = board.mappiezas[nodoant->IdPieza];
		//Posiciono el cusor del tablero en el nodo para borrarlo
		board.Fila = nodoant->Fila;
		//board.Columna = nodoant->Columna  + (pieza->GetComienzo() - 1);
		board.Columna = nodoant->Columna;
		//Elimino la pieza del tablero
		board.MarcarCasillas(pieza, FALSE);

		//Agrego la pieza como disponible
		board.MarcarPiezaInfo(pieza, TRUE);
		
		nodoant->Index = board.GetIndexFirstAvailable(nodoant->Index);
		//Le asigno el id al nodo a partir del index
		if (nodoant->Index != board.vecpiezas.size())
			nodoant->IdPieza = board.vecpiezas[nodoant->Index]->GetPiezaId();
		
	}
	else
	{
		CPieza* pieza = board.vecpiezas[nodo->Index];
		//Trato de agregar una pieza
		board.nodeseval++;
		if (board.CorrespondePieza(pieza))
		{
			board.MarcarCasillas(pieza, TRUE);
			board.MarcarPiezaInfo(pieza, FALSE);

			nodo->IdPieza = pieza->GetPiezaId();
			nodo->Fila = board.Fila;
			nodo->Columna = board.Columna;

			//Muestra el progreso en la barra
			MostrarProgreso(nodo);

			if (!board.AsignarProxColumnaFila())
			{
				soluciones.push_back(board.nodos);
				//Ahora tengo que eliminar la pieza y continuar
				board.MarcarCasillas(pieza, FALSE);
				board.MarcarPiezaInfo(pieza, TRUE);

				nodo->Index = board.GetIndexFirstAvailable(nodo->Index);
				if (nodo->Index != board.vecpiezas.size())
					nodo->IdPieza = board.vecpiezas[nodo->Index]->GetPiezaId();
			}
			else
			{
				board.inodo++;
				nodo = &(board.nodos[board.inodo]);
				nodo->Index = board.GetIndexFirstAvailable(-1);
				//Le asigno el id al nodo a partir del index
				nodo->IdPieza = board.vecpiezas[nodo->Index]->GetPiezaId();
			}
		}
		else
			nodo->Index = board.GetIndexFirstAvailable(nodo->Index);
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Argentina Argentina
System developer from Argentina.

Programmed in VB 5,6,.NET, C#, Java, PL-SQL, Transac-SQL, C, C++ and even some "calculator" language.

Love to build small, useful applications.
Usually building big and complicated apps based on solid, reliable components.

Hobbies: reading, photography, chess, paddle, running.

Comments and Discussions