Backtracking : Les 8 Reines
Le problème des huit reines consiste à positionner 8 reines sur un échiquier afin qu'aucune de ces reines ne puissent en menacer une autre, c'est-à-dire qu'elles ne partagent ni la même ligne, ni la même colonne, ni la même diagonale.
Ce programme initialement réalisé en 1992 donne l'ensemble des solutions.
Version initiale
// problème des huit reines
#include <conio.h>
#include <stdio.h>
#include <time.h>
typedef int bool;
typedef struct {
int nb_reines;
int reineligne[8];
bool reinecol[8];
bool reinediagp[15];
bool reinediags[15];
} Echiquier;
void afficher (Echiquier *echiq)
{
int i;
static n=1;
printf ("\n----------%d\t",n++);
for (i=0; i<8; i++)
printf ("%d-%d ", i+1, echiq->reineligne[i]);
}
bool case_ok (Echiquier *echiq, int ligne, int col)
{
int diagp, diags;
diagp = ligne + col - 2;
diags = col - ligne + 7;
return echiq->reinecol[col-1] && echiq->reinediagp[diagp]
&& echiq->reinediags[diags];
}
void ajouter_reine (Echiquier *echiq, int ligne, int col)
{
echiq->nb_reines++;
echiq->reineligne[ligne-1] = col;
echiq->reinecol[col-1] = 0;
echiq->reinediagp[ligne + col - 2] = 0;
echiq->reinediags[col - ligne + 7] = 0;
}
void retirer_reine (Echiquier *echiq)
{
int i;
echiq->nb_reines--;
for (i = 0; i < 8; i++)
echiq->reinecol[i] = 1;
for (i = 0; i < 15; i++)
echiq->reinediags[i] = echiq->reinediagp[i] = 1;
for (i = 0; i < echiq->nb_reines; i++) {
echiq->reinecol[ echiq->reineligne[i] - 1] = 0;
echiq->reinediagp [ i + echiq->reineligne[i] -1 ] = 0;
echiq->reinediags [ echiq->reineligne[i] - i + 6 ] = 0;
}
}
void pb_reines (Echiquier *echiq)
{
int ligne,col;
if (echiq->nb_reines == 8)
afficher (echiq);
else {
ligne = echiq->nb_reines +1;
for (col = 1 ; col <= 8; col++)
if (case_ok (echiq, ligne, col)) {
ajouter_reine (echiq, ligne, col);
pb_reines (echiq);
retirer_reine (echiq);
}
}
}
main ()
{
Echiquier echiquier = {0, {0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
time_t t1,t2;
t1 = time(NULL);
pb_reines (&echiquier);
t2 = time(NULL);
printf ("temps = %f", difftime(t2,t1));
return 0;
}
Version révisée pour une meilleure présentation des résultats
// problème des huit reines
#include <stdio.h>
#include <time.h>
typedef struct {
int nb_reines;
int reineligne[8];
bool reinecol[8];
bool reinediagp[15];
bool reinediags[15];
} Echiquier;
void afficher (Echiquier *echiq)
{
int i, j;
static int n=1;
printf ("----------%d\n",n++);
for (i=0; i<8; i++) {
for (j=0; j<8; j++)
if (echiq->reineligne[i] == j+1)
printf ("Q ");
else if ((i+j)%2)
printf ("□ ");
else
printf ("■ ");
printf ("\n");
}
printf ("\n");
}
bool case_ok (Echiquier *echiq, int ligne, int col)
{
int diagp, diags;
diagp = ligne + col - 2;
diags = col - ligne + 7;
return echiq->reinecol[col-1] && echiq->reinediagp[diagp]
&& echiq->reinediags[diags];
}
void ajouter_reine (Echiquier *echiq, int ligne, int col)
{
echiq->nb_reines++;
echiq->reineligne[ligne-1] = col;
echiq->reinecol[col-1] = 0;
echiq->reinediagp[ligne + col - 2] = 0;
echiq->reinediags[col - ligne + 7] = 0;
}
void retirer_reine (Echiquier *echiq)
{
int i;
echiq->nb_reines--;
for (i = 0; i < 8; i++)
echiq->reinecol[i] = 1;
for (i = 0; i < 15; i++)
echiq->reinediags[i] = echiq->reinediagp[i] = 1;
for (i = 0; i < echiq->nb_reines; i++) {
echiq->reinecol[ echiq->reineligne[i] - 1] = 0;
echiq->reinediagp [ i + echiq->reineligne[i] -1 ] = 0;
echiq->reinediags [ echiq->reineligne[i] - i + 6 ] = 0;
}
}
void pb_reines (Echiquier *echiq)
{
int ligne,col;
if (echiq->nb_reines == 8)
afficher (echiq);
else {
ligne = echiq->nb_reines +1;
for (col = 1 ; col <= 8; col++)
if (case_ok (echiq, ligne, col)) {
ajouter_reine (echiq, ligne, col);
pb_reines (echiq);
retirer_reine (echiq);
}
}
}
int main ()
{
Echiquier echiquier = {0, {0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
time_t t1,t2;
t1 = time(NULL);
pb_reines (&echiquier);
t2 = time(NULL);
printf ("temps = %f", difftime(t2,t1));
return 0;
}

Solutions
92 solutions sont trouvées. En voici une :

