PROGRAM BACKTRACKING ; (*************************************************************************) (* Programme : BACKTRAC.LOG *) (* Date : 04/03/93 *) (* Auteur : SIMON Philippe LICENCE INFORMATIQUE 1992/93 *) (* *) (* Ce programme permet d'effectuer des op‚rations de retour arriŠre *) (* de fa‡on intelligente. Pour cela 2 exemples de BACKTRACKING ont ‚t‚ *) (* choisi. La Gestion du Planning d'une Semaine et le ProblŠme des Pions *) (* Noirs et Blancs. Le choix de ces 2 exemples ce faisant par un MENU *) (* principal. *) (*************************************************************************) VAR choix,touche : integer, r : SEM, pi :pion; (*************************************************************************) (* METHODES USUELLES *) (* *) (* Cette partie contient des m‚thodes usuelles de travail (BIBLIOTHEQUE) *) (*************************************************************************) UNIT eff : PROCEDURE ; (* envoie un ordre d'‚ffacer l'‚cran *) var i : integer ; BEGIN WRITE( chr(27), "[2J"); END ; UNIT GetCar : IIuwgraph FUNCTION : INTEGER; (* attend que l'utilisateur tape une touche et renvoie le code ASCII *) VAR i : INTEGER; BEGIN i := 0; WHILE i=0 DO i := INKEY; Result := i; OD; END GetCar; UNIT attendre : PROCEDURE(t : integer); (* Procedure permettant d'attendre pendant 't' seconde(s) *) VAR j : integer; BEGIN j := TIME; while (ABS(j - TIME) < t) do od; END; (*--------------------------------------------------------------*) (* PROCEDURE li‚es la gestion du MENU Principal *) (*--------------------------------------------------------------*) UNIT menu : PROCEDURE ; (* Appelle les m‚thodes correspondantes au choix de l'utilisateur *) VAR boucle : BOOLEAN; BEGIN boucle := TRUE; WHILE (boucle) DO CALL eff; WRITELN; WRITELN (" ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); WRITELN (" ³ M E N U ³"); WRITELN (" ³ ³"); WRITELN (" ³ 'BACKTRACKING INTELLIGENT' ³"); WRITELN (" ³ ³"); WRITELN (" ³ ³"); WRITELN (" ³ 0.......... QUITTER ³"); WRITELN (" ³ ³"); WRITELN (" ³ ³"); WRITELN (" ³ 1 ..... Gestion du planning de la ³"); WRITELN (" ³ semaine. ³"); WRITELN (" ³ ³"); WRITELN (" ³ 2 ..... ProblŠme des pions noirs ³"); WRITELN (" ³ et blancs. ³"); WRITELN (" ³ ³"); WRITELN (" ³ ³"); WRITELN (" ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); WRITELN;WRITELN; WRITE (" Entrez votre choix : "); READLN (choix); CASE choix WHEN 0 : boucle := FALSE; WHEN 1 : CALL eff; r := NEW SEM; WHEN 2 : CALL eff; pi := NEW pion; ESAC; choix := 0; OD; END menu; (***************************************************************************) (* LA PARTIE GESTION DU PLANNING DE LA SEMAINE *) (* *) (* il s'agit ici de la DECLARATION de l'objet SEM *) (* (utilise la bibliothŠque Graphique IIugraph) *) (***************************************************************************) UNIT SEM : IIuwgraph CLASS; VAR i,cpt,ex,pl,et,arg,retour,val,N,N2,M : integer, exercice,plaisir,argent,etude,interv,interv2,interv3 : integer, MA,ME,JE,res : ARRAYOF integer, L1,L2,V1,V2 : ARRAYOF ARRAYOF integer, solution_possible : boolean; UNIT recurs : PROCEDURE(i : integer, res : ARRAYOF integer); (* recurs est la proc‚dure principale, appel‚e de fa‡on recursive *) (* afin de cr‚er l'arboresence de tous les cas possibles d'une *) (* Gestion de Semaine. A l'interieur de cette proc‚dure nous avons *) (* 6 autres sous_proc‚dures li‚es aux 6 premiers jours de la *) (* semaine (LUNDI MARDI MERCREDI JEUDI VENDREDI). Chacune de ces *) (* proc‚dures est propre … un test, … des affectation et … des *) (* retours arriŠres particuliers. *) (* Chaque solution trouv‚e est rang‚e dans le tableau 'res'. *) VAR j,w : integer; UNIT lundi : PROCEDURE; (* La proc‚dure lundi correspond en quelque sorte … la racine *) (* de l'arbre de gestion de la semaine. Les affectations *) (* touchent ici les exercices, le plaisir, et l'argent. De plus *) (* on gŠre, grace … la variable retour, les retours arriŠres *) (* afin de calculer les branches de l'arbre … ‚laguer. *) BEGIN FOR w := 1 TO N DO FOR j := 1 TO M DO (* on initialise les variables de travail li‚es aux exercices, aux plaisirs, et … l'argent *) ex := 0; pl := 0; arg := 0; et := 0; res(i) := L1(2,w); res(i+1) := L2(2,j); res(i+2) := L1(1,w) + L2(1,j); (* On incr‚mente les variables de travail *) ex := ex + res(i); pl := pl + res(i+1); arg := arg + res(i+2); (* appel de la procedure recurs correspondant au mardi *) CALL recurs(i+1,res); (* On decrement les variable de travail *) ex := ex - res(i); pl := pl - res(i+1); arg := arg - res(i+2); (* retour = 4 ou 5 correspond au vendredi *) IF retour = 4 THEN w := (exercice - val)/interv2; j := M; FI; IF retour = 5 THEN j := (plaisir - val); FI; retour := 0; OD; OD; solution_possible := FALSE; END lundi; UNIT mardi : PROCEDURE; (* La proc‚dure mardi correspond … la seconde tranche de l'arbre*) (* de gestion de la semaine. Les affectations touchent ici les *) (* ‚tudes. *) (* On gŠre, grace … la variable retour, les retours arriŠres du *) (* mercredi afin de calculer les branches de l'arbre … ‚laguer. *) BEGIN FOR w := 1 TO N DO res(i+2) := MA(w); et := 0; IF retour = 0 THEN (* On incremente les variable de travail *) et := et + res(i+2); (* appel de la procedure recurs correspondant au mercredi *) CALL recurs(i+1,res); (* On decremente les variable de travail *) et := et - res(i+2); FI; (* retour = 2 correspond au mercredi *) IF retour = 2 THEN w := (etude - val)/interv; IF w >= N THEN retour := 1; ELSE retour := 0; FI; FI; OD; solution_possible := FALSE; END mardi; UNIT mercredi : PROCEDURE; (* La proc‚dure mercredi correspond … la troisiŠme tranche de *) (* l'arbre de gestion de la semaine. Les affectations touchent *) (* ici les ‚tudes. *) (* On gŠre, grace … la variable retour, les retours arriŠres du *) (* jeudi afin de calculer les branches de l'arbre … ‚laguer. *) BEGIN FOR w := 1 TO N DO res(i+2) := ME(w); IF retour = 0 THEN (* On incremente les variable de travail *) et := et + res(i+2); (* appel de la procedure recurs correspondant au jeudi *) CALL recurs(i+1,res); (* On decremente les variable de travail *) et := et - res(i+2); FI; (* retour = 3 correspond au jeudi *) IF retour = 3 THEN w := (etude - val)/interv; IF w >= N THEN retour := 2; val := val + ME(N); ELSE retour := 0; FI; FI; OD; solution_possible := FALSE; END mercredi; UNIT jeudi : PROCEDURE; (* La proc‚dure jeudi correspond … la quartriŠme tranche de *) (* l'arbre de gestion de la semaine. Les affectations touchent *) (* ici les ‚tudes. *) (* On gŠre, grace … la variable retour, les retours arriŠres du *) (* jeudi au mercredi afin de calculer les branches de l'arbre … *) (* ‚laguer. *) BEGIN FOR w := 1 TO N DO res(i+2) := JE(w); IF retour = 0 THEN (* On incremente les variable de travail *) et := et + res(i+2); IF et < etude THEN (* si aucun cas n'est trouv‚ on indique un retour arriŠre et on calcul grace … la variable val et a l'indice de boucle w les branches … ‚laguer. *) IF w = N THEN retour := 3; val := et; ELSE w := (etude - et)/interv; IF w>=N THEN w := N - 1 FI; FI; ELSE (* appel de la procedure recurs correspondant au vendredi *) CALL recurs(i+1,res); FI; (* On decremente les variable de travail *) et := et - res(i+2); FI; OD; solution_possible := FALSE; END jeudi; UNIT vendredi : PROCEDURE; (* La proc‚dure vendredi correspond … la cinquiŠme tranche de *) (* l'arbre de gestion de la semaine. Les affectations touchent *) (* ici les exercices, le plaisir, et l'argent. *) (* On gŠre, grace … la variable retour, les retours arriŠres du *) (* lundi afin de calculer les branches de l'arbre … ‚laguer. *) BEGIN FOR w := 1 TO N DO FOR j := 1 TO M DO res(i+2) := V1(2,w); res(i+3) := V2(2,j); res(i+4) := V1(1,w) + V2(1,j); (* On incremente les variable de travail *) ex := ex + res(i+2); pl := pl + res(i+3); arg := arg + res(i+4); IF arg > argent THEN j := M; ELSE IF ex < exercice THEN (* si aucun cas n'est trouv‚ on indique un retour arriŠre et on calcul grace … la variable val et … l'indice de boucle w les branches … ‚laguer. *) IF w = N THEN retour := 4; val := ex; exit; ELSE w := ((exercice - ex)/interv2); IF w >= N THEN w := N-1 FI; j := M; FI ELSE IF pl < plaisir THEN (* si aucun cas n'est trouv‚ on indique un retour arriŠre et on calcul grace … la variable val et a l'indice de boucle j les branches … ‚laguer. *) IF j = M THEN retour := 5; val := pl; ELSE j := (plaisir - pl)/interv3; FI; (* appel de la procedure recurs correspondant … une solution trouv‚e *) ELSE CALL recurs(i+1,res); FI FI FI; (* On decremente les variable de travail *) ex := ex - res(i+2); pl := pl - res(i+3); arg := arg - res(i+4); OD; OD; solution_possible := FALSE; END vendredi; BEGIN retour := 0; solution_possible := TRUE; CASE i WHEN 1 : CALL lundi; WHEN 2 : CALL mardi; WHEN 3 : CALL mercredi; WHEN 4 : CALL jeudi; WHEN 5 : CALL vendredi; ESAC; (* si une solution est trouv‚e on l'imprime … l'‚cran *) IF solution_possible THEN CALL imprim(res) FI; END recurs; (*------------------------------------------------------------------*) (* PROCEDURE li‚es la gestion du MENU de la Gestion de la Semaine *) (*------------------------------------------------------------------*) UNIT menu_ps : PROCEDURE; VAR i : integer; BEGIN WRITELN(" ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ "); WRITELN(" ³ PLANNING DE LA SEMAINE AVEC CONTRAINTES ³ "); WRITELN(" ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ "); WRITELN(" Chaque jour implique un choix particulier :"); WRITELN; WRITELN(" * LUNDI :"); FOR i := 1 TO N DO WRITE(" $",L1(1,i):2," Exercice ",L1(2,i):2); IF i > M THEN WRITELN; ELSE WRITELN(" $",L2(1,i):2," Plaisir ",L2(2,i)); FI; OD; WRITELN; WRITELN(" * MARDI MERCREDI JEUDI :"); FOR i := 1 TO N DO WRITELN(" Etude ",MA(i):2," ",ME(i):2," ",JE(i)); OD; WRITELN; WRITELN(" * VENDREDI :"); FOR i := 1 TO N DO WRITE(" $",V1(1,i):2," Exercice ",V1(2,i):2); IF i > M THEN WRITELN; ELSE WRITELN(" $",V2(1,i):2," Plaisir ",V2(2,i)); FI; OD; WRITELN; WRITE(" CONTRAINTES : "); WRITE(" Exercice >= ",exercice:2," Argent ($) =< ",argent:2); WRITELN(" Etude >= ",etude:2," Plaisir >= ",plaisir:2); touche := Getcar; END; (*---------------------------------------------------------------------*) (* PROCEDURES li‚es la gestion de l'AFFICHAGE … l'‚cran des resultats *) (*---------------------------------------------------------------------*) UNIT imprim : PROCEDURE(res : ARRAYOF integer); (* La proc‚dure imprim permet d'afficher toutes les solutions *) (* possibles (les unes a la suite des autres) pages par pages … *) (* l'‚cran, sous forme de tableau de resultat. *) VAR j : integer; BEGIN IF cpt = 0 THEN CALL eff; (* affichage de l'entete … l'‚cran *) CALL entete; FI; WRITE ("³",res(1):4,"³",res(2):4,"³",res(3):4); WRITE ("³",res(4):6," ³",res(5):6," ³",res(6):6); WRITE (" ³",res(7):4,"³",res(8):4,"³",res(9):4); WRITE ("º",ex:4,"³",pl:4,"³",arg:4,"³",et:4,"³"); WRITELN; cpt := cpt + 1; IF cpt = 16 THEN WRITELN ("Appuyez sur une touche pour continuer..."); touche := Getcar; cpt := 0; FI; END imprim; UNIT entete : PROCEDURE; (* Affiche l'entete du tableau de resultat … l'‚cran. *) BEGIN WRITELN("CONTRAINTES : "); WRITE("Exercice >= ",exercice:2," Argent ($) =< ",argent:2); WRITELN(" Etude >= ",etude:2," Plaisir >= ",plaisir:2); WRITE("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄ"); WRITELN("ÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄËÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); WRITE("³ LUNDI ³ MARDI ³MERCREDI³ JEUD"); WRITELN("I ³ VENDREDI º TOTAL ³"); WRITE("ÃÄÄÄÄÂÄÄÄÄÂÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄ"); WRITELN("ÄÄÄÅÄÄÄÄÂÄÄÄÄÂÄÄÄÄÎÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄ´"); WRITE("³Exer³Plai³ $ ³ Etude ³ Etude ³ Etud"); WRITELN("e ³Exer³Plai³ $ ºExer³Plai³ $ ³Etud³"); WRITE("ÃÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄ"); WRITELN("ÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÎÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´"); END entete; UNIT fin : PROCEDURE; (* Affiche la fin du tableau de resultat … l'‚cran. *) BEGIN WRITE("ÀÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄ"); WRITELN("ÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÙ"); WRITELN ("Appuyez sur une touche pour continuer..."); touche := Getcar; END fin; BEGIN PREF IIUWGraph block; BEGIN (* Initialisation des tableaux et des variables de JEUX D'ESSAI *) N := 4; M := 3; N2 := 2; (* D‚claration d'intervalles *) interv := 2; interv2 := 5; interv3 := 1; ARRAY res DIM (1:9); ARRAY L1 DIM (1:N2); FOR i := 1 TO N2 DO ARRAY L1(i) DIM (1:N); OD; ARRAY L2 DIM (1:N2); FOR i := 1 TO N2 DO ARRAY L2(i) DIM (1:M); OD; ARRAY MA DIM (1:N); ARRAY ME DIM (1:N); ARRAY JE DIM (1:N); ARRAY V1 DIM (1:N2); FOR i := 1 TO N2 DO ARRAY V1(i) DIM (1:N); OD; ARRAY V2 DIM (1:N2); FOR i := 1 TO N2 DO ARRAY V2(i) DIM (1:M); OD; (* Initialisation des tableaux jeux d'essai du mardi,mercredi et jeudi concernant les ‚tudes. *) FOR i := 1 TO N DO MA(i),ME(i),JE(i) := (i-1) * interv; OD; (* Initialisation des tableaux jeux d'essai du lundi et vendredi concernant l'argent. *) L1(1,1),V1(1,1) := 0; L1(1,2),V1(1,2) := 0; L1(1,3),V1(1,3) := 0; L1(1,4),V1(1,4) := 20; (* Initialisation des tableaux jeux d'essai du lundi et vendredi concernant les exercices. *) FOR i := 1 TO N DO L1(2,i),V1(2,i) := (i-1) * interv2; OD; (* Initialisation des tableaux jeux d'essai du lundi et vendredi concernant les plaisirs ou divertissements. *) L2(1,1),V2(1,1) := 0; L2(1,2),V2(1,2) := 0; L2(1,3),V2(1,3) := 20; FOR i := 1 TO M DO L2(2,i),V2(2,i) := (i-1) * interv3; OD; (* Les contraintes d'une semaine ‚quilibr‚e sont les suivantes : *) argent := 30; etude := 14; exercice := 20; plaisir := 2; cpt := 0; CALL GRON(1); CALL menu_ps; CALL recurs(1,res); CALL fin; CALL GROFF; END; END SEM; (***************************************************************************) (* LA PARTIE GESTION DU JEU DES PIONS NOIRS ET BLANCS *) (* *) (* il s'agit ici de la DECLARATION de l'objet PION *) (* (utilise la bibliothŠque Graphique IIugraph) *) (***************************************************************************) UNIT PION : IIuwgraph CLASS; VAR n,i,M : integer, tab : ARRAYOF char, trouve,manuel: boolean; UNIT procent : PROCEDURE(A,B : char, P,NN : integer); (* La procedure procent permet de parcourir l'arbre des solutions *) (* en anticipant le meilleur des chemins c'est a dire en parcourant*) (* le moins de chemin possible. *) (* Les paramŠtres d'entr‚s A et B prennent soit la valeur Noir et *) (* Blanc ou Blanc et Noir. Idem pour les 2 entier P et NN qui *) (* prennent en fonction de la couleur des pions soit la valeur 1 et*) (* M (2*n+1) ou -1 et 1. (P indique le sens de deplacement). *) VAR bo : boolean, j, k : integer; UNIT proc : PROCEDURE(X : char); (* La proc‚dure proc permet de connaitre si l'on se trouve dans *) (* position de blocage ou bien si l'on peut continuer dans ce *) (* chemin. (Cas o— l'on place un pion … cot‚ d'un autre pion de *) (* mˆme couleur). *) BEGIN bo := TRUE; k := 2; j := i + 2*P; IF (j >= 1) AND (j <= M) THEN WHILE ((bo) AND (j <> NN+P)) DO (* On test si tous les pions suivants sont de mˆme couleur. Si oui alors on poursuit le chemin dans l'arbre, sinon on se trouve bloqu‚. *) IF tab(j) <> X THEN bo := FALSE; ELSE k := k + 1; FI; j := j + P; OD; FI; END proc; UNIT affect2 : PROCEDURE; (* La proc‚dure affect2 permet de d‚placer un pion en sautant *) (* par dessus un pion de couleur adverse. *) (* Le sens du d‚placement ‚tant indiquer par l'entier P. *) BEGIN tab(i) := tab(i-2*P); tab(i-2*P) := ' '; i := i - 2*P; (* appel de la proc‚dure principale tentative *) CALL tentative; i := i + 2*P; tab(i-2*P) := tab(i); tab(i) := ' '; END affect2; UNIT affect1 : PROCEDURE; (* La procedure affect1 permet de d‚placer un pion d'une *) (* case en avant (pion avance dans la case vide). *) (* Le sens du d‚placement ‚tant indiquer par l'entier P. *) BEGIN tab(i) := tab(i-P); tab(i-P) := ' '; i := i - P; (* appel de la proc‚dure principale tentative *) CALL tentative; i := i + P; tab(i-P) := tab(i); tab(i) := ' '; END affect1; BEGIN (* On test si l'on se trouve en bordures du jeux (du tableau) C'est a dire que l'on verifie que les indices de tables sont toujours valide pour continuer les tests suivants. *) IF ((i-P) > 0) AND ((i-P) <= M) THEN (* On test si l'on peut avancer le pion dans la case vide en fonction de P (indique le sens du d‚placement). *) IF tab(i-P) = A THEN (* On test si l'on se trouve en bordures du jeux, en fonction du sens du d‚pacement. *) IF ((i+P) > 0) AND ((i+P) <= M) THEN (* On test si le pion situ‚ aprŠs la case vide est de mˆme couleur que celui plac‚ avant. *) IF tab(i+P) = A THEN (* Si oui on appele la proc‚dure proc *) CALL proc(A); (* On test si l'on poursuit le chemin *) IF bo THEN CALL affect1; (* On test si l'on se trouve dans l'‚tat final du jeux. (k=n) *) IF k = n THEN trouve := FALSE FI; IF trouve THEN CALL aff_retour_ar FI; FI; ELSE (* Sinon on appele la proc‚dure d'affectation affect1, et on poursuit le chemin. *) CALL affect1; IF trouve THEN CALL aff_retour_ar FI; FI; ELSE (* Sinon on appele la proc‚dure d'affectation affect1 *) CALL affect1; IF trouve THEN CALL aff_retour_ar FI; FI; ELSE (* On test si l'on se trouve en bordures du jeux (du tableau) C'est a dire que l'on verifie que les indices de tables sont toujours valide pour continuer les tests suivants. *) IF ((i-2*P) > 0) AND ((i-2*P) <= M) THEN (* On test si l'on peut avancer le pion plac‚ 2 cases avant la case vide en sautant un pion de couleur adverse plac‚ une case avant la case vide, toujours en fonction du sens P. *) IF (tab(i-2*P) = A) AND (tab(i-P) = B) THEN (* On test si l'on se trouve en bordures du jeux, en fonction du sens du d‚pacement. *) IF ((i+P) > 0) AND ((i+P) <= M) THEN (* On test si le pion situ‚ aprŠs la case vide est de mˆme couleur que celui plac‚ 2 cases avant la case vide. *) IF tab(i+P) = A THEN (* Si oui on appele la proc‚dure proc *) CALL proc(A); (* On test si l'on poursuit le chemin *) IF bo THEN CALL affect2; (* On test si l'on se trouve dans l'‚tat final du jeux. (k=n) *) IF k = n THEN trouve := FALSE; FI; IF trouve THEN CALL aff_retour_ar FI; FI; ELSE (* Sinon appel de la proc‚dure d'affectation affect2, et on poursuit le chemin. *) CALL affect2; IF trouve THEN CALL aff_retour_ar FI; FI; ELSE (* appel de la proc‚dure d'affectation affect2 *) CALL affect2; IF trouve THEN CALL aff_retour_ar FI; FI; FI; FI; FI; FI; END procent; UNIT tentative : PROCEDURE; (* Cette proc‚dure permet de parcourir l'arbre du jeux des pions. *) (* En faisant d'abord avancer les pions Noirs puis les pions Blancs*) (* Tant que l'‚tat final n'est pas atteint on affiche l'‚volution *) (* du d‚placement dans l'arbre. *) BEGIN IF trouve THEN CALL cls; (* On imprime le resultat a l'instant t *) CALL imprim; (* On d‚place les pions Noirs *) CALL procent('N','B',1,M); (* On d‚place les pions Blancs *) CALL procent('B','N',-1,1); FI; END tentative; (*---------------------------------------------------------------------*) (* PROCEDURES li‚es la gestion de l'AFFICHAGE … l'‚cran des resultats *) (*---------------------------------------------------------------------*) UNIT aff_retour_ar : PROCEDURE; (* Proc‚dure permettant d'indiquer … l'‚cran que l'on effectue *) (* un retour arriŠre (BACKTRACKING). *) BEGIN CALL CLS; CALL move(150,220); CALL draw(360,220); CALL move(150,260); CALL draw(360,260); CALL move(150,220); CALL draw(150,260); CALL move(360,220); CALL draw(360,260); CALL move(180,237); CALL outstring("RETOUR ARRIERE ..."); CALL imprim; END; UNIT imprim : PROCEDURE; (* Proc‚dure permettant d'afficher de maniŠre graphique les *) (* pions Noirs et Blancs dans un tableaux proportionnel au *) (* nombre de pions. *) (* Les proc‚dures graphiques utilis‚es : outstring, move, draw *) (* cirb. *) VAR l,col,xi,touche : integer; BEGIN CALL move(100,10); CALL outstring("LE PROBLEME DES PIONS NOIRS ET BLANCS"); (* Affichage du tableau de jeux *) CALL move(70,80); CALL draw(70+60*(2*n+1),80); CALL move(70,120); CALL draw(70+60*(2*n+1),120); FOR l := 0 TO ((n+1)*2-1) DO CALL move(70+(60*l),80); CALL draw(70+(60*l),120); OD; (* Affichage des pions Noirs et Blancs *) FOR l := 1 TO M DO xi := 100 + ((l-1) * 60); IF tab(l) <> ' ' THEN IF tab(l) = 'B' THEN col := 15; ELSE col := 0; FI; CALL cirb(xi,100,20,10,10,15,col,2,2); FI; OD; IF manuel THEN CALL move(50,300); CALL outstring("Appuyez sur une touche pour continuer..."); touche := Getcar; ELSE CALL attendre(2); FI; END imprim; UNIT menu_p : PROCEDURE; VAR choix : integer; BEGIN manuel := TRUE; CALL eff; WRITELN(" ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ "); WRITELN(" ³ PROBLEME DES PIONS NOIRS ET BLANCS ³ "); WRITELN(" ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ "); WRITELN; WRITELN; WRITELN (" A partir d'un etat initial qui est le suivant :"); WRITELN (" NNN*BBB"); WRITELN (" Il faut aboutir … un etat final qui est le suivant :"); WRITELN (" BBB*NNN"); WRITELN; WRITELN (" Sachant que l'on … des rŠgles fix‚es :"); WRITELN (" ÄÄ> <ÄÄ"); WRITELN (" - Les sens sont fix‚s : NNN*BBB"); WRITELN (" - Un pion peut avancer dans une case vide '*' si :"); WRITELN (" * Elle est juste devant. "); WRITELN (" * Il l'atteint en sautant par dessus un pion"); WRITELN (" de couleur adverse."); WRITELN; WRITELN (" D‚sirez vous un traitement :"); WRITELN; WRITELN (" 1 ......... MANUEL"); WRITELN (" 2 ......... AUTOMATIQUE"); WRITELN; WRITE (" Votre choix : "); READLN (choix); IF choix = 2 THEN manuel := FALSE FI; CALL eff; WRITELN; WRITELN; WRITELN; WRITELN; n := 0; WHILE ((n < 2) OR (n > 4)) DO WRITE(" Donnez le Nombre de Pions (2,3 ou 4) : "); READLN (n); OD; END; BEGIN (* On utilise pour repr‚senter de fa‡on graphique … l'‚cran les pions *) (* Noirs et Blancs la Biblioth‚que graphique IIugraph. *) PREF IIUWGraph block; BEGIN CALL GRON(1); CALL menu_p; (* initialisation … l'‚tat initial du tableau de jeux en fonction *) (* du nombres de pions entr‚s pr‚alablement. ex: NNN BBB *) ARRAY tab DIM (1:(n*2)+1); FOR i := 1 TO n DO tab(i) := 'N' OD; tab(n+1) := ' '; FOR i := (n+2) TO (n*2)+1 DO tab(i) := 'B' OD; i := n + 1; (* La variable M repr‚sente l'indice maximum du tableau du jeux *) (* en fonction du nombres de pions. ex: si n=3 ÄÄ> M=7 *) M := 2*n + 1; trouve := TRUE; (* Appel de la proc‚dure principale 'tentative' de parcours d'arbre. *) CALL tentative; CALL GROFF; END; END PION; (*******************************) (*** PROGRAMME PRICIPAL *****) (*******************************) BEGIN (* Appel du menu principal *) CALL menu; END BACTRACKING;