{ File: labdef2.pas } { Definizioni per matrice labirinto, con procedure di lettura da file e stampa su video. Vettore percorso di attraversamento, con procedura di stampa su video e procedura di modifica di una matrice labirinto per evidenziarvi un percorso dato; Le costanti N, M, PASSAGGIO, e EVIDENTE sono definite nel programma che include queste definizioni. } const NP1 = N + 1; MP1 = M + 1; NCAMM = n*m - 2*m - 2*n + 6; type IndiceRiga = 0..NP1; IndiceColonna = 1..MP1; Labirinto = array [IndiceRiga, IndiceColonna] of char; { Per memorizzare l'attraversamento del labirinto, facciamo uso di un vettore, dimesionato secondo il massimo numero di passi possibile in un labirinto avente solo i muri perimetrali (con almeno due entrate/uscite) e senza muri all'interno (nm-2m-2n+6). Ciascun elemento del vettore rappresenta un punto del cammino percorso. Se il vettore contiene un cammino effettivo, allora esso termina con un punto di passaggio avente coordi pari a N o 1 oppure coordj pari a M o 1. Gli elementi successivi del cammino verranno ignorati da una eventuale stampa. } TNcamm = 1..NCAMM; Attraversamento = array [TNcamm] of record coordi : IndiceRiga; coordj : IndiceColonna; end; procedure LeggiLabirinto (var f : text; var lab : Labirinto); var i : IndiceRiga; j : IndiceColonna; begin { LeggiLabirinto } reset(f); for i := 1 to N do begin for j := 1 to M do read(f, lab[i, j]); readln(f) end end; { LeggiLabirinto } procedure StampaLabirinto (var lab: Labirinto); var i : IndiceRiga; j : IndiceColonna; begin { StampaLabirinto } writeln; writeln(' LABIRINTO'); for i := 1 to N do begin for j := 1 to M do write(lab[i, j]); writeln; end end; { StampaLabirinto } procedure StampaAttraversamento (var att: Attraversamento; q: integer); { stampa il percorso: il primo passo (entrata) e l'ultimo (uscita) su linee separate; q elementi per linea al massimo } var k : TNcamm; { per scandire l'attraversamento } cont : integer; { per stampare q passi su una linea } finecammino : boolean; { per valutare quando la stampa ha raggiunto l'ultima componente significativa del cammino } begin { StampaAttraversamento } writeln; writeln(' ATTRAVERSAMENTO del LABIRINTO:'); { stampa del primo passo } writeln('(', att[1].coordi : 2, ',', att[1].coordj : 2, ')'); cont := 0; { stampato un passo sulla linea } k := 2; { prossimo passo da stampare: indice 2 } { init della condizione di fine stampa } finecammino := (att[k].coordi = 1) or (att[k].coordj = 1) or (att[k].coordi = N) or (att[k].coordj = M); repeat { stampa q passi su una linea (o quanti ne rimangono) } while (cont < q) and not finecammino do begin write(' (', att[k].coordi : 2, ',', att[k].coordj : 2, ')'); cont := cont + 1; { stampato un altro elemento} k := k + 1; { ci si prepara a stampare il successivo se finecammino=TRUE non si dovra` eseguire la prossima iterazione } finecammino := (att[k].coordi = 1) or (att[k].coordj = 1) or (att[k].coordi = N) or (att[k].coordj = M) end; cont := 0; { il prossimo while stampera' altri n passi... } writeln { ...sulla riga successiva } until finecammino; { stampa dell'ultimo passo } write('(', att[k].coordi : 2, ',', att[k].coordj : 2, ')') end; { StampaAttraversamento } procedure StampaPercorsoSuLabirinto (lab: Labirinto; att: Attraversamento); { Modifica la matrice labirinto passata per valore in modo che i punti del percorso att vengano evidenziati con il carattere EVIDENTE. Poi la stampa. } var k : integer; begin { primo passo } lab[att[1].coordi, att[1].coordj] := EVIDENTE; { passi successivi } k := 1; repeat k := k + 1; lab[att[k].coordi, att[k].coordj] := EVIDENTE until (att[k].coordi = 1) or (att[k].coordj = 1) or (att[k].coordi = N) or (att[k].coordj = M); StampaLabirinto(lab) end; { StampaPercorsoSuLabirinto }