Algorithme

Accueil Remonter class CcaseNB

 

A la base de l'algorithme, il y a les objets "CcaseNB" représentant chacun une case de l'échiquier. Pour construire des carrés magiques, l'algorithme reste le même. Seules, les méthodes des objets, sur lesquels l'algorithme opère, ont été modifiées. Le polymorphisme, mis en oeuvre à travers les méthodes virtuelles du C++, permet de conserver, quel que soit le type de recherche (carré magique, carré quelconque, parcours utilisant en priorité les cases excentrées, parcours privilégiant les cases centrales ...) le même algorithme.

CcaseNB propose de nombreuses méthodes publiques mais seulement 4 de ces méthodes sont utilisées dans l'algorithme de recherche:

virtual bool IsFree(int Index);
virtual int FirstStep(int Src);
virtual int NextStep();
virtual int GetSource();

La première méthode, IsFree(index) demande à la case visée si elle est libre, c'est à dire s'il est possible d'effectuer un saut sur cette case. Le paramètre Index n'existait pas dans l'algorithme standard qui recherchait simplement des chemins sur l'échiquier. Grâce à Index, la case peut par avance calculer la somme qui serait obtenue sur la ligne et sur la colonne si le bond est effectué. Si la ligne est complète (toutes les cases de la ligne sont occupées) ou si la colonne est complète et que la somme des Index sur la ligne ou sur la colonne ne vaut pas 260, la case n'est pas libre et IsFree() retourne false.

Le deuxième méthode FirstStep(Src) effectue le bond sur la case. Cette méthode retourne la case suivante dans la liste des possibilités. Cette liste est initialisée en début de programme pour chaque case. Cette initialisation est réalisée dans le constructeur spécialisé de la case qui prend en paramètre la position de la case sur l'échiquier.

La troisième méthode, NexStep() est appelée pour obtenir de la case courante une autre case de l'échiquier, lorsque la case retournée par FirstStep(), ou par NexStep() s'est avérée être occupée. En effet chaque case proposée en retour de l'une de ces 2 méthodes est ensuite testée par IsFree(Index). Le tableau des cases atteignables, à partir d'une case donnée, est terminée par -1. Lorsque FirstStep() ou NextStep() retourne -1, GetSource() est appelé.

GetSource retourne la case d'origine et indique que la case est a nouveau libre (attribut free = true). Il est important de remarquer que chaque appel de  GetSource() est suivi d'un appel de NextStep(). Ainsi, lorsque le cavalier recule, il arrive sur une case et essaye ensuite la deuxième possibilité du tableau des destinations possibles de cette case. La première possibilité ne convient pas car le cavalier vient de reculer. Lorsque le cavalier recule de la case n, l'arbre complet de tous les chemins possibles a partir de la case n a été parcouru.

FirstStep fait avancer effectivement le cavalier et GetSource le fait reculer, les 2 autres méthodes des cases ne le font pas bouger. Il y a 2 séquences dans l'algorithme

  1. FirstStep / IsFree
  2. NextStep / IsFree

L'algorithme, au cœur du contrôle Kmagic, est le suivant :

Il peut être surprenant de ne pas trouver dans l'algorithme ci-dessus un test indiquant  que l'arbre de recherche a été entièrement parcouru. Cependant, ce test est bien présent. L'algorithme exploite un tableau de pointeurs de CcaseNB[64]. Au début du programme, la case du départ est spécialisée. La méthode NextStep() de cette case indique qu'il n'y a pas de solution lorsque cette dernière retourne -1. La méthode GetSource()  retourne une case spéciale, la case 64, qui met fin à la boucle de recherche (Save2Do = true) . 

Dans sa structure actuelle, le même algorithme permet de rechercher à la fois des parcours complets de cavalier sans contraintes particulières, des parcours complets qui répondent à la contrainte de carré magique ou de carré semi-magique(1). Il est aussi possible, sans changer l'algorithme, d'imposer comme but de recherche un carré magique dont la somme des diagonales vaut la même valeur que les lignes et les colonnes, c'est à dire un carré magique avec diagonales. Les différents objectifs sont configurables en début de programme. Ce sont des propriétés du contrôle. 

Un contrôle ActiveX a deux modes de fonctionnement : un mode création (design-time) et un mode exécution (run-time). Pendant la phase de création, les propriétés du contrôle sont accessibles à travers une boite de dialogue spécialisée, programmée par le développeur du contrôle. Ces propriétés sont également accessibles à travers différentes APIs (Application Program Interface) dans différents langages C++, Visual Basic ou des langages de script (Visual Basic Script). En mode exécution le déroulement du programme est paramétré par les propriétés qui ont été initialisées en mode création.  

Certaines propriétés du contrôle Kmagic permettent de modifier l'objectif de la recherche. Ce n'est pas l'algorithme qui change mais les objets "CcaseNB" utilisés par l'algorithme , qui sont modifiés. Comme l'algorithme exploite un tableau de pointeur de CcaseNB à travers 4 méthodes propres à chaque case, il faut que ces méthodes soient virtuelles dans la case racine pour que la méthode correcte de la case spécialisée soit invoquée.

L'initialisation en début de recherche du tableau pcaseNB[] est assez complexe car la combinatoire n'est pas triviale. Elle est décrite selon 2 axes

  • arborescences des clases dérivées de CcaseNB.
  • utilisation des classes de cette arborescence en fonction du type de chemin recherché.

De plus, afin de réduire le temps de recherche, il est important de supprimer dans les méthodes des classes dérivées chaque test dépendant d'un paramètre (d'une propriété) du contrôle. Ainsi, plus le contrôle possède de propriétés, plus le nombre de classes est important.

 

(1) Un carré semi-magique est un carré 8x8 ou chaque quart 4x4 est lui même magique. Dans ce cas la somme des lignes et des colonnes de chaque quart vaut 130