Automi e Macchina di Turing
Esempio 3: Si vuole ora estendere l’esempio precedente inserendo anche la gestione, previa selezione, di un semaforo di tipo austriaco e uno tipico dei paesi dell’est slavo. Per fare questo inseriamo un gruppo di radio button per la selezione dei tre casi possibili. La finestra apparirà ora come segue.
Stabiliamo subito che ancora una volta gli ingressi sono l’intervallo di tempo oppure il pulsante.
Chiariamo subito come funziona un semaforo di tipo austriaco, il passaggio dal verde al rosso avviene con verde lampeggiante, il passaggio dal rosso al verde con l’accensione anche dell’arrancione. Si avrà quindi un automa di questo tipo.
Come si vede c’è uno stato in più, il verde lampeggiante, mentre l’arancione è presente assieme al rosso.
Ora sono necessarie alcune modifiche al programma dell’esempio 2.
Si modifica la procedura dell’evento del timer per stabilire quale tipo deve essere implementato.
// Quando scatta il timer.
procedure TfrmSemaforo.Timer1Timer(Sender: TObject);
begin
case radTipoSemaforo.ItemIndex of
0 : TransizioneItalia();
1 : TransizioneAustriaca();
2 : TransizioneSlava();
end;
end;
Ora ci saranno sia la transizione austriaca che quella slava, implementate dalle rispettive procedure.
// Gestisce la transizione di stato nel caso di semaforo italiano.
procedure TfrmSemaforo.TransizioneSlava();
var
istato: integer; // salva temporaneamente lo stato attuale.
begin
istato := m_iStato;
case m_iStato of
1: SemaforoArancioneRosso();
2: begin
case m_iStatoPre of
1: SemaforoVerde();
2: SemaforoRosso();
end;
end;
3: SemaforoArancioneVerde();
end;
// Salvo lo stato precedente.
m_iStatoPre := istato;
end;
// Gestisce la transizione di stato nel caso di semaforo italiano.
procedure TfrmSemaforo.TransizioneAustriaca();
var
istato: integer; // salva temporaneamente lo stato attuale.
begin
istato := m_iStato;
case m_iStato of
1: SemaforoArancioneRosso();
2: begin
case m_iStatoPre of
1: SemaforoVerde();
2: SemaforoRosso();
end;
end;
3: SemaforoVerdeLampegginate();
4: begin
SemaforoRosso;
tmrVerde.Enabled := False;
end;
end;
// Salvo lo stato precedente.
m_iStatoPre := istato;
end;
Necessariamente devono essere introdotte le procedure per attivare gli stati opportuni e quindi le nuove colorazioni.
// Semaforo arancione e rosso.
procedure TfrmSemaforo.SemaforoArancioneRosso();
begin
ColorazioneLampade(True, True, False);
m_iStato := 2;
end;
// Semaforo arancione e verde.
procedure TfrmSemaforo.SemaforoArancioneVerde();
begin
ColorazioneLampade(False, True, True);
m_iStato := 2;
end;
// Semaforo verde lampeggiante.
procedure TfrmSemaforo.SemaforoVerdeLampegginate();
begin
ColorazioneLampade(False, False, True);
m_iStato := 4;
tmrVerde.Enabled := True;
end;
La variabile globale m_iStato ora assumerà valori in {1 = rosso, 2 = arancione, 3 = Verde, 4 = verde lampeggiante, 5 = rosso e arancione, 6 = arancione e verde}, mentre per gestire l’arancione devo stabilire quale era lo stato precedente, se rosso oppure verde, si introduce quindi la variabile m_iStatoPre .
Il problema maggiore è ora quello di fare lampeggiare il verde per il semaforo austriaco, quando si transita nel verde lampeggiante si attiva un secondo timer per colorare e scolorare il verde.
// Colora e scolora il verde.
procedure TfrmSemaforo.tmrVerdeTimer(Sender: TObject);
begin
if (shpLampada3.Brush.Color = clGreen) then
ColorazioneLampade(False, False, False)
else
ColorazioneLampade(False, False, True);
end;
Evidentemente l’intervallo di attivazione del Timer2 deve essere inferiore al Timer1, ed è stato stabilito in 100 millisecondi.
Altra implementazione Delphi
Copyright © 2006 by
Emanuele Scapin
All Rights reserved
Designed by GOEMO.de