Ampel-Simulation

LeonInfo19

Bekanntes Mitglied
Hallo,
ich will die Schaltung einer Ampel simulieren:
Java:
public class Ampel{
    
    
    private boolean rot;
    private boolean gelb;
    private boolean grün;
    
    
    Ampel(){
        rot=true;
    }
    
     public void schalten(){
        
        if(rot){
             gelb=true;
            
            return;
        }
        
        if(rot &&  gelb){
            rot=false;
            gelb=false;
            grün=true;
            return;
        }
        if(grün){
            
            gelb=true;
            grün=false;
            return;
        }
    
        if(gelb){
            rot=true;
            gelb=false;
            
            return;
        }   
    }
    
    public String toString(){
    
        
         if(rot)  return "rot";
         else if((rot) && ( gelb)) return "rotgelb";
         else if(grün) return " grün";
         else return "gelb";
    }
}


Wenn ich dann folgenden Test durchführe:
Java:
class Main {

    public static void main(String[] args) {
        
        Ampel test=new Ampel();
        
        System.out.println(test);
        
        test.schalten();
        System.out.println(test);
        
    }
}

..., dann wird aber nur rot ausgeben.
Wo liegt denn der Fehler in meiner Methode?
 

httpdigest

Top Contributor
Durch das erste Schalten wird ja gelb auf true gesetzt. Somit ist jetzt gelb und rot auf true. Deine toString() Methode prüft aber erstmal nur per `if(rot) return "rot";`, ob rot=true ist und steigt dann sofort mit return "rot" aus.
Ändere es vielleicht auf:
Java:
public String toString(){
  if (rot && gelb) return "rotgelb";
  else if (rot) return "rot";
  else if (grün) return "grün";
  return "gelb";
}
 

httpdigest

Top Contributor
Dasselbe Problem mit der Reihenfolge der if-Abfragen hast du auch in schalten(). Da fragst du ja auch zuerst nur ab, ob rot=true ist und setzt dann gelb auf true und beendest sofort die Methode.
Generell würde ich die Schaltungslogik anders implementieren. Eher so:
Java:
public class Ampel {
  private static final boolean[][] programm = {
      /* rot, gelb, grün */
      { true, false, false },
      { true, true, false },
      { false, false, true },
      { false, true, false }
  };

  private boolean rot;
  private boolean gelb;
  private boolean grün;
  private int phase;

  public Ampel() {
    setzeSignale();
  }

  private void setzeSignale() {
    boolean[] signale = programm[phase];
    this.rot = signale[0];
    this.gelb = signale[1];
    this.grün = signale[2];
  }

  public void schalten() {
    phase = (phase + 1) % 4;
    setzeSignale();
  }

  public String toString() {
    if (rot && gelb)
      return "rotgelb";
    else if (rot)
      return "rot";
    else if (grün)
      return "grün";
    return "gelb";
  }
}
 

LeonInfo19

Bekanntes Mitglied
Danke für deinen Vorschlag. Wenn ich aber bei meiner Programmstruktur bleiben will, sollte ich dann nicht den Fall rot ganz zum Schluss behandeln?
 

httpdigest

Top Contributor
Wenn du mehrere Bedingungen hast, und diese Bedingungen Teilmengen voneinander sind (das heißt, `a` ist Teilmenge von `b`, wenn gilt: a => b, also aus `a` folgt `b`), dann musst du die stärkste Bedingung zuerst abfragen. Also (rot && gelb) ist stärker als (rot), ist aber auch Teilmenge von (rot), denn es gilt (rot && gelb) => (rot). Somit musst du (rot && gelb) zuerst abfragen.
Wenn die Bedingungen unabhängig voneinander sind, wie es ja bei (rot), (gelb) und (grün) der Fall ist, dann ist die Reihenfolge egal, weil ja niemals zwei der drei Bedingungen gleichzeitig auftreten können.
 

mihe7

Top Contributor
Ich würde allerdings davon abraten, über die Stärke der Bedingung zu gehen, da damit die Abfragen abhängig von der Ausführungsreihenfolge werden.

Entweder die if-Abfragen verschachteln oder explizit abfragen. Letzteres halte ich für die geeignetste Variante, denn es handelt sich beim Fall "Rot" und "Rot-Gelb" tatsächlich um zwei verschiedene, voneinander unabhängige Fälle, die nur zufällig das Rot gemeinsam haben. Klar wird es, wenn man andere Bezeichnungen für die Fälle einführt, z. B. Stop, Bereit , Fahren, da tritt das Problem erst gar nicht auf.
 

httpdigest

Top Contributor
Mit abhängig/unabhängig und aus a folgt b, meinte ich die reine Aussagenlogik. Denn die Variable/Bedingung rot=true ist nunmal auch in der Bedingung rot=true && gelb=true enthalten.
Aber ich stimme dir zu, dass alles andere besser ist als wie es aktuell umgesetzt ist. :)
 
X

Xyz1

Gast
In einer echten Ampel, sieht es ungefähr so aus:
Java:
public class SqlToTable {

    private int i;
    private String[] s = {"grün", "gelb", "rot", "rot-gelb"};

    public void iS() {
        i = (i + 1) % 4;
    }

    public String cS() {
        return s[i];
    }

    public String nS() {
        iS();
        return cS();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        SqlToTable stt = new SqlToTable();
        for (int i = 0; i <= 11; i++) {
            System.out.println(i + " " + stt.nS());
        }
    }

}

(Nich verwunderlich sein, SqlToTable soll eigentlich Ampel sein)
 
X

Xyz1

Gast
Ok, es passte eher in die Plauderecke... aber sobald andere Personen, Tiere, Verkehrsteilnehmer... auf der Fahrbahn sind oder eine Ampel nicht läuft, ist ohnehin erhöhte Vorsicht geboten.
 

MoxxiManagarm

Top Contributor
Wobei eine Ampel auch schnell als State-Machine via Enum abgebildet werden kann. Etwa so:

Java:
enum TrafficLightState {
    INITIAL(false, true, false, true) {
        @Override
        public TrafficLightState nextState() {
            return RED;
        }
    },
    RED(true, false, false, false) {
        @Override
        public TrafficLightState nextState() {
            return REDYELLOW;
        }
    },
    REDYELLOW(true, true, false, false) {
        @Override
        public TrafficLightState nextState() {
            return GREEN;
        }
    },
    GREEN(false, false, true, false) {
        @Override
        public TrafficLightState nextState() {
            return YELLOW;
        }
    },
    YELLOW(false, true, false, false) {
        @Override
        public TrafficLightState nextState() {
            return RED;
        }
    };

    private boolean red, yellow, green, blinking;

    private TrafficLightState(boolean red, boolean yellow, boolean green, boolean blinking) {
            this.red = red;
            this.yellow = yellow;
            this.green = green;
            this.blinking = blinking;
    }

    public abstract TrafficLightState nextState();
   
    public String toString() {
        String s = this.name() + ": ";
        s += (red ? "R" : ".");
        s += (yellow ? "Y" : ".");
        s += (green ? "G" : ".") + " ";
        s += (blinking ? "(blinking)" : "(permanent)");
       
        return s;
    }
   
    public static void main(String... args) {
        TrafficLightState state = INITIAL;
        System.out.println(state);
       
        for(int i = 0; i < 100; i++) {
            System.out.println(state = state.nextState());
        }
    }
}
 
Zuletzt bearbeitet:

LeonInfo19

Bekanntes Mitglied
Ich habe es mir nochmal durch den Kopf gehen lassen und meine Lösung ist leider zu sehr vom konkreten Zustand abhängig. Vielen Dank für euere Vorschläge:)
 
X

Xyz1

Gast
Unser Tutor hat uns auch die gleiche Übung gestellt, daher weiß ich das noch ... Es war aber keine Simulation - wir mussten eine echte Ampel in klein aufbauen. o_O
Ich lehne mich mal etwas aus dem Fenster: Ein (Ampel)-Automat mit nur 3 Zuständen kann nicht durch eine >Typ-1-Grammatik beschrieben werden.
 

MoxxiManagarm

Top Contributor
und unser Prof hat das erst so wie ich gemacht.
Lass mich das hier mal klarstellen: Wir sehen hier im Forum viel zu oft Aufgabenstellungen und Ansätze von Profs, welche mehr als fragwürdig sind. Ich hätte mich schon das eine oder andere mal mit dem Prof angelegt wäre es meiner. Profs sind halt auch nicht perfekt. Hilft nur: eigene Gedanken machen und verstehen. Und lass mich dir sagen, viele ifs hintereinander sind eigentlich immer schlecht und es gibt in 99.5% eine bessere Lösung. Vielleicht hole ich jetzt weit aus, aber im Berufsleben musst du Unittests schreiben und die beinhalten eine Zweigabdeckung....

Am besten erinnere ich mich an den Prof, der einen Tetraeder von einem Dreieck erben lassen wollte. Das würde so viel bedeuten wie "ein Tetreader ist ein Dreieck" anstatt "ein Tetraeder hat ein Dreieck als Grundfläche". Daher man merke: composition over inheritance
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Ampel Programmieren die jede 10 sekunden ihre farbe wechselt Java Basics - Anfänger-Themen 6
P9cman Ampel in Java implementieren Java Basics - Anfänger-Themen 3
D Ampel für Mitarbeiter zum An-/Abwesend zeigen Java Basics - Anfänger-Themen 28
S Ampel Programmieren Java Basics - Anfänger-Themen 5
Y Ampel Java Basics - Anfänger-Themen 11
T Ampel implementieren Java Basics - Anfänger-Themen 12
M Ampel Symbole Java Basics - Anfänger-Themen 4
B Ampel (mitBlueJ) Java Basics - Anfänger-Themen 6
M Ampel Java Basics - Anfänger-Themen 14
B Erste Schritte handgeschaltete Ampel programieren Java Basics - Anfänger-Themen 8
Z Ampel Java Basics - Anfänger-Themen 19
D Ampel Programmieren Java Basics - Anfänger-Themen 5
G Ampel automatisch umschalten Java Basics - Anfänger-Themen 18
I Ampel mit Verzögerung Java Basics - Anfänger-Themen 2
V Grafische Auswertung (Ampel-System) Java Basics - Anfänger-Themen 12
Robert_Klaus Hamster java Simulation Hilfe bei einer Aufgabe Java Basics - Anfänger-Themen 5
B Scanner-If/else kleine Abhebungs-Simulation Java Basics - Anfänger-Themen 3
W Cache Simulation Java Basics - Anfänger-Themen 3
CT9288 Kleine Simulation programmieren, denkanstöße erbeten Java Basics - Anfänger-Themen 19
D Erste Schritte Jäger-Beute Simulation Java Basics - Anfänger-Themen 19
M Simulation - Algorithmus Java Basics - Anfänger-Themen 3
S Simulation auf Knopfdruck Java Basics - Anfänger-Themen 29
L Maus Click Simulation Java Basics - Anfänger-Themen 5
D Simulation von Geburt/Tod und "richtige" Erkennung eines Hindernisses Java Basics - Anfänger-Themen 7
G menü in simulation Java Basics - Anfänger-Themen 3
maddin86 Simulation Wettrennen mit diversen Fahrzeugen Java Basics - Anfänger-Themen 9
X Monte Carlo Simulation (integral) Java Basics - Anfänger-Themen 4
frau-u Simulation eines Fernsehers Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben