BOOKS i'm reading
 |
/*
* Module ID: lab2.cpp
* Titre : Module principal du Lab 2 du cours ELE-440
* Utilite : Solution du projet P3 de la section 3.3
* du livre 'Data structures and program design in C'
* en eliminant la recursivite du probleme a l'aide
* de stack.
*
* Auteur : Olivier Langlois <olivier@olivierlanglois.net>
* Date : 4 Fevrier 1998
*
*/
#ifdef __BORLANDC__
// Indique au compilateur que les instances de template utilisees dans ce
// module seront definies dans un autre module.
#pragma option -Jgx
#endif
/*
* Fichiers d'entetes
*/
#include "lab2ches.h"
#include "signon.h"
#include <stdlib.h> /* Pour rand() */
#include <time.h>
#ifdef WIN32
#include "diagwin.h"
#else
#include "diagdos.h"
#endif
/*
* Un stack statique est plus approprie dans le present probleme car nous
* savons que le nombre d'entrees dans le stack ne peut pas depasser 64
* mais puisque le but de ce programme est de demontrer le bon fonctionnement
* du stack dynamique pour le lab2, le stack dynamique est utilise par defaut.
*/
#ifdef STATICSTACK
#include "collect/stack.h"
#else
#include "collect/dynastck.cpp"
#endif
/*
* Definitions
*/
/*
* Declarations de fonctions & de classes locales
*/
/******************************************************************************
*
* Nom : solveKnightTourPuzzle
*
* Utilite : Resoud le probleme P3 (solveKnightTourPuzzle)
*
* Parametres:
* board (ChessBoard *) Jeu a utilise.
* x ,y (int) Position de depart
* strategy (int) Strategie a utilise (heuristique/force brutale)
*
* Note : Avec la methode heuristique, l'algorithme choisit la case
* suivante en preferant les cases plus difficilement accessibles,
* C'est a dire les cases ayant moins d'origines possibles.
* (Ex.: les coins)
*
* Valeur de retour: (unsigned long) Nombre de backtracks utilises.
*
****************************************************************************/
static unsigned long solveKnightTourPuzzle( ChessBoard &board,
int x,
int y,
int strategy
);
/*
* Definition des fonctions
*/
void main( void )
{
#ifdef __GNUG__
Lab2ChessBoard::sentinel = new Lab2ChessCase(-1);
#endif
char answer;
Lab2ChessBoard board;
board.initColumns();
srand((unsigned)time(NULL));
try
{
signon("Lab2 de ELE-440");
cout << "Voulez vous utiliser la methode heuristique (O/N) ?" << endl;
cin.get(answer);
cout << "Nombre de backtrack : "
<< solveKnightTourPuzzle( board, rand()%NUMCOL, rand()%NUMROW,
(answer == 'O' || answer == 'o') )
<< endl;
cout << endl << "Solution :" << endl << board;
#ifdef __GNUG__
delete Lab2ChessBoard::sentinel;
#endif
}
catch( ExceptionBase &x )
{
#ifdef WIN32
x.Explain( DiagOutWin("Exception") );
#else
DiagOutDOS output = DiagOutDOS(cerr);
x.Explain( output );
#endif
}
#ifndef __GNUG__
catch( bad_cast &x )
{
cerr << "Bad_cast" << endl;
}
#else
catch( exception &x )
{
cerr << x.what() << endl;
}
#endif
}
/******************************************************************************
*
* Nom : solveKnightTourPuzzle
*
****************************************************************************/
static unsigned long solveKnightTourPuzzle( ChessBoard &board,
int x,
int y,
int strategy
)
{
unsigned long result = 0;
#ifdef STATICSTACK
stack_dcl(CasesStack,Lab2ChessCase *,64);
#else
StackDynamic<Lab2ChessCase *> CasesStack;
#endif
Lab2Knight knight( &board[x][y] );
Lab2ChessCase *ptrCase, *nextMove;
if( strategy )
// Methode heuristique
board.accept( knight );
// Sinon methode force brutale
// Initialise le jeu avec la case de depart
ptrCase = dynamic_cast<Lab2ChessCase *>(&board[x][y]);
ptrCase->accept( knight );
while(1)
{
if( ptrCase->possibleNextMoves->isEmpty() == BOOL_FALSE )
{
#ifdef STATICSTACK
push(CasesStack,ptrCase);
ptrCase->seq = stack_ele(CasesStack);
#else
CasesStack.Push(ptrCase);
ptrCase->seq = CasesStack.entries();
#endif
nextMove = getNext( ptrCase );
ptrCase = nextMove;
ptrCase->accept( knight );
}
#ifdef STATICSTACK
else if( stack_ele(CasesStack) == NUMROW*NUMCOL-1 )
#else
else if( CasesStack.entries() == NUMROW*NUMCOL-1 )
#endif
{
ptrCase->seq = NUMROW*NUMCOL;
break;
}
else
{
#ifdef STATICSTACK
nextMove = pop(CasesStack);
#else
nextMove = CasesStack.Pop();
#endif
nextMove->seq = 0;
ptrCase = nextMove;
// Incremente le compteur de backtrack.
// Affiche un . a chaque 1 000 000 ieme backtrack
// pour ne pas laisser penser a l'usager que le programme
// est mort car son execution (surtout avec la methode force brutale)
// peu etre tres tres tres longue (Dans le pire des cas, le nombre
// d'essais necessaires pour trouver une reponse peut etre de l'ordre de
// 60! et plus).
if(!(result++%1000000))
cout << ".";
}
}
return result;
}
#ifdef __GNUG__
#ifndef STATICSTACK
template class StackDynamic<Lab2ChessCase *>;
#endif
#endif
|