/* * KaraMaus1.java, (c) 2001 Horst Müller * Version vom 6. 11. 2001 * * Anpassung an JavaKara 2: 07.03.2002 [sz] */ import JavaKaraProgram; /* * COMMANDS: * kara.move() kara.turnRight() kara.turnLeft() * kara.putLeaf() kara.removeLeaf() * SENSORS: * kara.treeFront() kara.treeLeft() kara.treeRight() * kara.mushroomFront() kara.onLeaf() */ // --------------------------------------------------------------------------- // Kara als Labyrinthbewältiger: Implementierung einer Druckmaus mit nur // einem Drucksymbol, durch Simulation einer Druckmaus mit 5 Drucksymbolen, // die den Tremaux-Algorithmus benutzt. // Damit der Algorithmus korrekt arbeitet, muss eine endliche betretbare Fläche // mit Bäumen abgegrenzt sein // --------------------------------------------------------------------------- // START DEFINE YOUR METHODS: public class KaraMaus1 extends JavaKaraProgram { // public class KaraErweiterung extends JavaKaraProgram { /* * COMMANDS: * boolean freeMove() Testet, ob das vor Kara liegende Feld unmarkiert und ohne Mauer ist. Wenn ja, wird es betreten. Wenn nein, wird um 180 Grad gedreht. * boolean leafOrTreeFront() Testet, ob das vor Kara liegende Feld ein Blatt trägt * turn() Drehung um 180 Grad * zurueck() umdrehen und ein Schritt vorwärts * markiere() Falls noch nicht auf Blatt, Blatt ablegen * void printSituation() Druckt die momentane Situation aus * String richtungRechts(String richtung) * String richtungLinks(String richtung) * String gegenRichtung(String richtung) * String makroTeil(String orientierung, String richtung) * ordnet der Orientierung (rechts, links) und der Richtung die * Lage des betretenen Teilfeldes (karaTeilPos) zu: * orientierung richtung ----> makroTeil(orientierung, richtung) * ----------------------------------------------------------------- * rechts N SE * rechts W NE * rechts S NW * rechts E SW * links N SW ... */ // --------------------------------------------------------------------------- // START DEFINE YOUR METHODS: // public String karaRichtung = "undef" ; // momentane Richtung von Kara public String karaTeilPos = "undef" ; // Teilposition auf Makrofeld public String makrofeldSeite = "undef" ; // Rechts oder Links // zum Merken der Seite, auf der ein Makrofeld // betreten wurde. Rechts : ????^ ; Links : ???^? // --------------------------------------------------------------------------- public boolean freeMove() { // falls das vor Kara liegende Feld frei ist, gehe dorthin // sonst dreh um und gib false zurueck if (kara.treeFront()) { turn(); return false;} else { kara.move() ; if (kara.onLeaf()) {this.zurueck() ; return false ;} else return true ; } } // end freeMove // --------------------------------------------------------------------------- public boolean leafOrTreeFront() { // testet, ob vor Kara ein Baum oder ein Blatt ist if (kara.treeFront()) { return true ;} else { kara.move() ; if (kara.onLeaf()) { this.zurueck() ; turn(); return true ;} else { this.zurueck() ; turn(); return false ; } } } // end leafOrTreeFront() // --------------------------------------------------------------------------- public void markiere() { // setze Blatt, fall nicht schon eins da ist if (!kara.onLeaf()) kara.putLeaf() ; } // end markiere // --------------------------------------------------------------------------- public void turn() {this.turnRight(); this.turnRight(); } // --------------------------------------------------------------------------- public void zurueck() { // Vorbedingung: rückwärtiges Feld betretbar turn(); kara.move(); } // --------------------------------------------------------------------------- public void turnLeft() { // erweitert turnLeft um die Protokollierung // der Aenderung in karaRichtung kara.turnLeft(); karaRichtung = richtungLinks(karaRichtung); } // end turnLeft // --------------------------------------------------------------------------- public void turnRight() { // erweitert turnRight um die Protokollierung // der Aenderung in karaRichtung kara.turnRight(); karaRichtung = richtungRechts(karaRichtung); } // end turnRight // --------------------------------------------------------------------------- public String richtungRechts(String richtung) { if (richtung == "N") return "E"; else if (richtung == "E") return "S"; else if (richtung == "S") return "W"; else if (richtung == "W") return "N"; else if (richtung == "NW") return "NE"; else if (richtung == "SW") return "NW"; else if (richtung == "NE") return "SE"; else if (richtung == "SE") return "SW"; else return "undef"; } // nach rechts um 90 Grad // ---------------------------------------------------------------- public String richtungLinks(String richtung) { if (richtung == "N") return "W"; else if (richtung == "E") return "N"; else if (richtung == "S") return "E"; else if (richtung == "W") return "S"; else if (richtung == "NW") return "SW"; else if (richtung == "SW") return "SE"; else if (richtung == "NE") return "NW"; else if (richtung == "SE") return "NE"; else return "undef"; } // nach links um 90 Grad // ---------------------------------------------------------------- public String gegenRichtung(String richtung) { if (richtung == "N") return "S"; else if (richtung == "E") return "W"; else if (richtung == "S") return "N"; else if (richtung == "W") return "E"; else if (richtung == "NW") return "SE"; else if (richtung == "SW") return "NE"; else if (richtung == "NE") return "SW"; else if (richtung == "SE") return "NW"; else return "undef"; } // gegenRichtung // ---------------------------------------------------------------- public String makroTeil(String orientierung, String richtung) { if (orientierung == "Rechts") { if (richtung == "N") return "SE"; else if (richtung == "E") return "SW"; else if (richtung == "S") return "NW"; else if (richtung == "W") return "NE"; else return "undef"; } else if (orientierung == "Links") { if (richtung == "N") return "SW"; else if (richtung == "E") return "NW"; else if (richtung == "S") return "NE"; else if (richtung == "W") return "SE"; else return "undef"; } else { System.out.println("+++ Fehler in makroTeil +++"); return "undef"; } } // makroTeil // ---------------------------------------------------------------- // :END DEFINE YOUR METHODS // --------------------------------------------------------------------------- // } // Ende KaraErweiterung // // aus BetretungsversuchRechts // public boolean vorwaerts = true ; // Vorwärts-Phase des Algorithmus public boolean fertig = false ; // für Erkennung der korrekten Termination public boolean test = false ; // für Fehlersuche public int makrofeldTypnummer = 0; public String ankunftsSeite = "undef" ; public String ankunftsRichtung = "undef" ; public String ankunftsPos = "undef" ; public int ruecknr = 0; // -------------------------------------------------------------------------- public void printSituation() { if (test) { System.out.println("++printSituation++"); if (fertig) System.out.println("fertig"); if (vorwaerts) System.out.println("vorwärts"); else System.out.println("rückwärts"); System.out.println("ankunftsRichtung = " + this.ankunftsRichtung); System.out.println("ankunftsPos = " + this.ankunftsPos); System.out.println("ankunftsSeite = " + this.ankunftsSeite); System.out.println("karaRichtung = " + this.karaRichtung); System.out.println("karaTeilPos = " + this.karaTeilPos); System.out.println("makrofeldSeite = " + this.makrofeldSeite); System.out.println("makrofeldTypnummer = " + this.makrofeldTypnummer); System.out.println("ruecknr = " + this.ruecknr); System.out.println("+++++++++++++++++++++++++++++++++"); } } // end printSituation // ---------------------------------------------------------------- public boolean betretungsversuchRechts() { // von einem Feld vor dem SE-Teilfeld aus in Richtung N // wird analysiert, // ob das Makrofeld blockiert, frei oder makromarkiert ist. // Wenn es frei war und eine Verzweigung möglich ist, // wird es mit der Ankunftsrichtung makromarkiert. // resultat = true // War es makromarkiert oder blockiert, wird zurückgegangen. res = false if (!this.freeMove()) { /* Fall 2 ???(X|M) ; kara geht auf rechts suedlich */ makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; // Mauer oder markiert } // End Fall 2 else // Fall 1. SE frei in Richtung N betreten { if (kara.treeFront()) { /*Fall 11 ?X?F^ */ if (kara.treeLeft()) // Typ 2 { /* Fall 111 ?XXF^ */ makrofeldSeite = "Rechts"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } else { /* Fall 112 ?X-XF<*/ // SW keine Mauer turnLeft(); if (this.freeMove()) { // Fall 1121.?XF SW markiert, Richtung W, zurueck { turnRight(); kara.move(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end Fall 1122 } // end Fall 112 } // end Fall 11 else // Fall 12 ?-X?F^ { if (this.freeMove()) /* Fall 121 ?F^?F Nord frei */ { if (kara.treeLeft()) // Fall 1211 Typ XF?F^ {this.zurueck(); if (kara.treeRight()) //Fall 12111, XFXFv { kara.putLeaf(); turn(); makrofeldSeite = "Rechts"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end Fall 12111 else // Fall 12112 XF-XFv { turnRight(); if (this.freeMove()) // Fall 121121 XFF { turnRight(); kara.move(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end fall 121122 } // end Fall 12112 } // end fall 1211 else // Fall 1212 -XF^?F { turnLeft(); if (this.freeMove()) // Fall 12121 F?F { turnRight(); kara.move(); kara.move(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end Fall 12122 } // end Fall 1212 } // end Fall 121 else // Fall 122 ?M?Fv { kara.move(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end Fall 122 } // end Fall 12 } // end Fall 1 } // end betretungsversuchRechts // // aus BetretungsversuchLinks // public boolean betretungsversuchLinks() {// von einem Feld vor dem SW-Teilfeld aus // wird analysiert, // ob das Makrofeld blockiert, frei oder makromarkiert ist. // Wenn es frei war und eine Verzweigung möglich ist, // wird es mit der Ankunftsrichtung makromarkiert. // resultat = true // War es makromarkiert oder blockiert, wird zurückgegangen. resultat = false if (!this.freeMove()) { /* Fall 2 ??(X|M)? Kara geht auf links suedlich*/ makrofeldSeite = "Rechts"; return false; // Mauer oder markiert } // End Fall 2 else // Fall 1. SW frei in Richtung N betreten { if (kara.treeFront()) { /*Fall 11 X?F^? */ if (kara.treeRight()) // Typ 2 { /* Fall 111 X?F>X */ makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } else { /* Fall 112 X?F<(F|M) */ // SE keine Mauer turnRight(); if (this.freeMove()) { // Fall 1121.X?FF>, SE frei if (kara.treeLeft()) // Fall 11211 Typ XXFF>, S makromarkieren { kara.putLeaf(); this.zurueck(); kara.putLeaf(); turnRight(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end 11211 else // Fall 11212 X(F|M)FF> { turnLeft(); if (this.freeMove()) // Fall 112121 XF^FF , NE frei { this.zurueck(); kara.putLeaf(); turnRight(); kara.move(); kara.putLeaf(); turnRight(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } else // Fall 112122 XMFFv { // Makrofeld bereits makromarkiert, zurueck turnRight(); kara.move(); turnLeft(); kara.move(); makrofeldSeite = "Rechts"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false ; } // end Fall 112122, } // end Fall 11212 } // end Fall 1121 else // Fall 1122 X?FM> SE markiert, Richtung E, zurueck { turnLeft(); kara.move(); makrofeldSeite = "Rechts"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end Fall 1122 } // end Fall 112 } // end Fall 11 else // Fall 12 (F|M)?F^? { if (this.freeMove()) /* Fall 121 F^?F? Nord frei */ { if (kara.treeRight()) // Fall 1211 Typ XFF^? {this.zurueck(); if (kara.treeLeft()) //Fall 12111, FXFvX { kara.putLeaf(); this.turn(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end Fall 12111 else // Fall 12112 FXFv(F|M) { turnLeft(); if (this.freeMove()) // Fall 121121 FXFF> { kara.putLeaf(); this.zurueck(); kara.putLeaf(); turnRight(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end Fall 121121 else // Fall 121122 FXFFX { this.zurueck(); turnLeft(); kara.move(); kara.putLeaf(); turn(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end Fall 121211 else // Fall 121212 FF>F(F|M) { turnRight(); if (this.freeMove()) // Fall 1212121 FFFFv { kara.putLeaf(); turnRight(); kara.move(); kara.putLeaf(); turnRight(); makrofeldSeite = "Links"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; this.vorwaerts = true; return true ; } // end Fall 1212121 else // Fall 1212122 FF^FM { turnLeft(); kara.move(); turnLeft(); kara.move(); kara.move(); makrofeldSeite = "Rechts"; karaTeilPos = makroTeil(makrofeldSeite, karaRichtung) ; return false; } // end Fall 1212122 } // end Fall 121212 } // end Fall 12121 else // Fall 12122 F, rueck = S */ { zurueck() ; turnRight() ; return 3;} else {/*X?MF>, rueck = W */ zurueck() ; turnRight() ; return 4;} } else { /* X?F^?*/ turnRight(); kara.move(); if (kara.onLeaf()) { /* X?FM> rueck = E */ zurueck() ; turnRight() ; return 2;} else { /* X?FF> */ turnLeft(); kara.move(); if (kara.onLeaf()) {/* XM^FF , rueck = N */ zurueck() ; turnRight() ; kara.move(); turnRight(); return 1; } else { /* keine Makromarkierung vorhanden */ zurueck() ; turnRight() ; kara.move(); turnRight(); return 0; } } } } // end ruecknummerXFFF //-------------------------------------------------------------------- void makroZurueckXFFF() { // kein freier Makronachbar , also Makro-zurueck System.out.println("makroZurueckXFFF()"); this.makroBlockiereXFFF(); // pre: in Richtung Nord auf SW this.vorwaerts = false; // System.out.println("ruecknummerXFFF = " + ruecknr); switch (ruecknr) { case 0: System.out.println("Fehler case 0 in makroBlockiereXFFF, ruecknr = " + ruecknr); // Fehler keine Makromarkierung break; // end case 0 case 1: /* rueck=N */ turnRight(); kara.move(); turnLeft(); kara.move(); // XM^MM if (!kara.treeFront()) { kara.move(); karaTeilPos = "SE"; karaRichtung = "N"; makrofeldSeite = "Rechts"; } // auf Rueckfeld rechts else { abschluss(); } // fertig = true; Rueckmarsch unmoeglich break; // end case 1 case 2: /* rueck=E*/ turnRight(); kara.move(); if (!kara.treeFront()) { kara.move(); karaTeilPos = "SE"; karaRichtung = "N"; makrofeldSeite = "Rechts"; } // auf Rueckfeld rechts else { turnLeft(); kara.move(); turnRight(); if (!kara.treeFront()) {kara.move(); makrofeldSeite = "Links"; } // auf Rueckfeld links else { abschluss(); } // fertig = true; Rueckmarsch unmoeglich } break; // end case 2 case 3: turnRight(); if (!kara.treeRight()) { turnRight(); kara.move(); karaTeilPos = "SE"; karaRichtung = "N"; makrofeldSeite = "Rechts"; } // auf S-Rueckfeld rechts else { kara.move(); turnRight(); if (!kara.treeFront()) { kara.move(); karaTeilPos = "SW"; karaRichtung = "N"; makrofeldSeite = "Links"; }// auf Rueckfeld links else { abschluss(); } // fertig = true; Rueckmarsch unmoeglich } break; // end case 3 case 4: if (!kara.treeLeft()) { turnLeft(); kara.move(); karaTeilPos = "SW"; karaRichtung = "N"; makrofeldSeite = "Links";} // auf Rueckfeld links else { abschluss(); } // fertig = true; Rueckmarsch unmoeglich break; // end case 4 } // end switch } // end makroZurueckXFFF // --------------------------------------------------------------------------- void makroBlockiereXFFF() { // blockiert das momentane Makrofeld // vorausgesetzte Position und End-Position: // karaTeilPos = "SW" & Typ XFFF & karaRichtung = "N" // Anfangstyp: X(F|M)(F|M)^(F|M) , Endtyp: XMMM this.markiere(); turnRight(); kara.move(); this.markiere(); turnLeft(); kara.move(); this.markiere(); this.zurueck(); turnRight(); kara.move(); turnRight(); } // end makroBlockiereXFFF // ------------------------------------------------------------------------- public void makroSchrittXFFF() { // in N auf SW System.out.println("+++ makroSchrittXFFF +++"); this.ruecknr = ruecknummerXFFF() ; // System.out.println("ruecknummerXFFF = " + ruecknr); switch (ruecknr) { case 0: System.out.println("Fehler ruecknr=0 in makroSchrittXFFF"); break; case 1: /* XMFF, rueck = N */ if ( ankunftsRichtung == "N") { turnLeft(); // vor westlichem NachbarMakrofeld if (!this.betretungsversuchLinks()) // West-Makrofeld unten { // West-MakrofeldUnten markiert oder blockiert. XFF>F turnLeft(); makroZurueckXFFF(); } } // end ankunft N else if ( ankunftsRichtung == "W") { this.turn(); // vor suedlichem NachbarMakrofeld links if (!this.betretungsversuchRechts()) { // Sued-Makrofeld links markiert oder blockiert. XFF^F turnRight(); kara.move(); turnRight(); if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { turnLeft(); kara.move(); if (!this.betretungsversuchLinks()) // West-Makrofeld unten { turnLeft(); makroZurueckXFFF(); } } } } // end ankunft W else if ( ankunftsRichtung == "S") { turnRight(); kara.move(); turnLeft(); kara.move(); turnRight(); // vor oestlichem NachbarMakrofeld if (!this.betretungsversuchLinks()) // Ost-Makrofeld oben { // XFF kara.move(); turnLeft(); kara.move(); // vor noerdlichem NachbarMakrofeld if (!this.betretungsversuchRechts()) // Nord-Makrofeld rechts { kara.move(); turnRight(); kara.move(); turnRight(); makroZurueckXFFF(); } } } // end ankunft N else if ( ankunftsRichtung == "W") { turnRight(); kara.move(); turnRight(); // vor suedlichem NachbarMakrofeld rechts if (!this.betretungsversuchLinks()) { // XFFF^ turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { turnLeft(); if (!this.betretungsversuchLinks()) // West-Makrofeld unten { kara.move(); turnLeft(); kara.move(); if (!this.betretungsversuchRechts()) // Nord-Makrofeld rechts { // karaTeilPos = "NE"; karaRichtung = "S"; kara.move(); turnRight(); kara.move(); turnRight(); makroZurueckXFFF(); } } } } } // end ankunft W else if (ankunftsRichtung == "N") { makroZurueckXFFF(); } else // Fehler { System.out.println("Fehler in makroSchrittXFFF, case 2"); } break; // end case 2 // ----------------------------------------------------------------------- case 3: /* XFMM, rueck = S */ if ( ankunftsRichtung == "S") { turnRight(); kara.move(); // vor oestlichem NachbarMakrofeld unten if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { turnRight(); kara.move(); turnRight(); if (!this.betretungsversuchLinks()) // Ost-Makrofeld oben { // XFF kara.move(); turnLeft(); kara.move(); if (!this.betretungsversuchRechts()) // Nord-Makrofeld rechts { turnLeft(); if (!this.betretungsversuchLinks()) // Ost-Makrofeld oben { turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { // karaTeilPos = "SE"; karaRichtung = "W"; kara.move(); turnRight(); makroZurueckXFFF(); } } } } } // end ankunft N else if (ankunftsRichtung == "W") { makroZurueckXFFF(); } else // Fehler { System.out.println("Fehler in makroSchrittXFFF, case 3"); } break; // end case 3 // ----------------------------------------------------------------------- case 4: /* XFMF, rueck = W */ if ( ankunftsRichtung == "W") { this.turn(); // vor suedlichem NachbarMakrofeld if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { // XF^FF turnRight(); kara.move(); turnRight(); // karaTeilPos = "SE"; karaRichtung = "S"; if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { turnLeft(); kara.move(); turnRight(); makroZurueckXFFF(); } } } // end ankunft W else if ( ankunftsRichtung == "S") { turnRight(); kara.move(); // vor oestlichem NachbarMakrofeld unten if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { // XFFF< turnRight(); kara.move(); turnRight(); if (!this.betretungsversuchLinks()) // Ost-Makrofeld oben { turnLeft(); kara.move(); if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { makroZurueckXFFF(); } } } } } // end ankunft S else if ( ankunftsRichtung == "E") { turnRight(); kara.move(); turnLeft(); kara.move(); // vor noerdlichem NachbarMakrofeld if (!this.betretungsversuchRechts()) // Nord-Makrofeld { // XFvFF turnLeft(); // karaTeilPos = "NE"; karaRichtung = "E"; if (!this.betretungsversuchLinks()) // Ost-Makrofeld oben { turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { turnLeft(); if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { // karaTeilPos = "SE"; karaRichtung = "N"; turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { makroZurueckXFFF(); } } } } } } // end ankunft E else if (ankunftsRichtung == "N") { makroZurueckXFFF(); } else // Fehler { System.out.println("Fehler in makroSchrittXFFF, case 4"); System.out.println("ankunftsRichtung =" + ankunftsRichtung); } break; // end case 4 } // end switch } // end makroSchrittXFFF // --------------------------------------------------------------------------- // Typ des Makrofeldes "XXFF" // --------------------------------------------------------------------------- public int ruecknummerXXFF() { // stellt fuer markiertes Makrofeld vom Typ XXFF // in Position SW , N die Rueckmarschrichtung fest; '1:N' kommt nicht vor // 0: undef, 1 : N, 2 : E, 3 : S, 4 : W // Voraussetzung: normierte Position if (kara.onLeaf()) { /* XXM^? */ turnRight(); kara.move(); if (kara.onLeaf()) /*XXMM>, rueck = S */ { zurueck() ; turnRight() ; return 3; } else {/*XXMF>, rueck = W */ zurueck() ; turnRight() ; return 4; } } else { /* XXF^?*/ turnRight(); kara.move(); if (kara.onLeaf()) { /* XXFM> , rueck = E */ zurueck() ; turnRight() ; return 2; } else { /* XXFF> */ { /* keine Makromarkierung vorhanden */ zurueck() ; turnRight() ; return 0; } } } } // end ruecknummerXXFF //-------------------------------------------------------------------- public void makroBlockiereXXFF() { // blockiert das momentane Makrofeld // merkt die rueckmarschrichtung in rueckRichtung // Makromarkierung vorausgesetzt // vorausgesetzte Position und End-Position: // karaTeilPos = "SW" & Typ XXFF & karaRichtung = "N" ,frueher E // Anfangstyp: XX(F|M)^(F|M) , Endtyp: XXMM if (kara.onLeaf()) { // rueck W oder S turnRight(); kara.move(); if (kara.onLeaf()) { /* this.rueckRichtung = "S" ; */ } else { kara.putLeaf(); /* this.rueckRichtung = "W" ; */ } this.zurueck(); turnRight(); } else { // rueck = E kara.putLeaf(); /* this.rueckRichtung = "E" ; */ } } // end makroBlockiereXXFF // ------------------------------------------------------------------------- public void makroZurueckXXFF() { // kein freier Makronachbar , also Makro-zurueck this.makroBlockiereXXFF(); // pre: in Richtung Nord auf SW this.vorwaerts = false; // System.out.println("ruecknummerXXFF = " + ruecknr); switch (ruecknr) { case 0: System.out.println("Fehler case 0 in makroBlockiereXXFF, ruecknr = " + ruecknr); // Fehler keine Makromarkierung break; // end case 0 case 1: System.out.println("Fehler case 1 (unzulaessige Rueckrichtung) in makroBlockiereXXFF, ruecknr = " + ruecknr); // Fehler falsche Makromarkierung break; // end case 1 case 2: /* rueck=E */ turnRight(); kara.move(); if (!kara.treeFront()) { kara.move(); karaTeilPos = "SE"; karaRichtung = "N"; makrofeldSeite = "Rechts"; } // auf Rueckfeld rechts else { abschluss() ; // fertig = true; // Rueckmarsch unmoeglich } break; // end case 2 case 3: /* rueck=S */ turnRight(); if (!kara.treeRight()) { turnRight(); kara.move(); karaTeilPos = "SE"; karaRichtung = "N"; makrofeldSeite = "Rechts"; } // auf S-Rueckfeld links else { kara.move(); if (!kara.treeRight()) { turnRight(); kara.move(); karaTeilPos = "SW"; karaRichtung = "N"; makrofeldSeite = "Links"; } // auf Rueckfeld rechts else { abschluss() ; // fertig = true; } // Rueckmarsch unmoeglich } break; // end case 3 case 4: if (!kara.treeLeft()) { turnLeft(); kara.move(); karaTeilPos = "SW"; karaRichtung = "N"; makrofeldSeite = "Links";} // auf Rueckfeld links else { abschluss() ; // fertig = true; // Rueckmarsch unmoeglich } break; // end case 4 } // end switch } // end makroZurueckXXFF // --------------------------------------------------------------------------- public void makroSchrittXXFF() { // in N auf SW, Klammer1 System.out.println("+++ makroSchrittXXFF +++"); this.ruecknr = ruecknummerXXFF() ; switch (ruecknr) { case 0: System.out.println("Fehler ruecknr=0 in makroSchrittXXFF"); break; case 1: /* XXFF, rueck = N */ System.out.println("Fehler ruecknr=1 = Nord in makroSchrittXXFF"); break; case 2: /* XMFM, rueck = E */ if ( ankunftsRichtung == "E") { makroZurueckXXFF(); } // end ankunft E else if ( ankunftsRichtung == "N") { turnLeft(); // vor westlichem NachbarMakrofeld if (!this.betretungsversuchLinks()) // West-Makrofeld unten { // West-MakrofeldUnten markiert oder blockiert. XXF>M turnLeft(); // karaTeilPos = "SW"; karaRichtung = "N"; makroZurueckXXFF(); } } // end ankunft N else if ( ankunftsRichtung == "W") { turnRight(); kara.move(); turnRight(); // vor suedlichem NachbarMakrofeld rechts if (!this.betretungsversuchLinks()) { // XXFF^ turnLeft(); kara.move(); turnLeft(); // karaTeilPos = "SW"; karaRichtung = "S"; if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { turnLeft(); if (!this.betretungsversuchLinks()) // West-Makrofeld unten { turnLeft(); makroZurueckXXFF(); } } } } // end ankunft W else if (ankunftsRichtung == "S") { System.out.println("Fehler in makroSchrittXXFF, case 2 ankunft=S"); } else // Fehler { System.out.println("Fehler in makroSchrittXXFF, case 2 ankunft falsch"); } break; // end case 2 // -------------------------------------------------------------- case 3: /* XFMM, rueck = S */ if ( ankunftsRichtung == "S") { System.out.println("Fehler in makroSchrittXXFF, case 3 ankunft=S"); } // end ankunft S else if ( ankunftsRichtung == "E") { turnRight(); kara.move(); // vor oestlichem NachbarMakrofeld unten if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { kara.move(); turnRight(); // karaTeilPos = "SW"; karaRichtung = "N"; makroZurueckXXFF(); } } // end ankunft E else if ( ankunftsRichtung == "N") { turnLeft(); // vor westlichem NachbarMakrofeld if (!this.betretungsversuchLinks()) // West-Makrofeld unten { // West-MakrofeldUnten markiert oder blockiert. XXF>F kara.move(); // karaTeilPos = "SE"; karaRichtung = "E"; { if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { // karaTeilPos = "SE"; karaRichtung = "W"; kara.move(); turnRight(); // karaTeilPos = "SW"; karaRichtung = "N"; makroZurueckXXFF(); } } } } // end ankunft N else if (ankunftsRichtung == "W") { makroZurueckXXFF(); } else // Fehler { System.out.println("Fehler in makroSchrittXXFF, case 3"); } break; // end case 3 // ----------------------------------------------------------------------- case 4: /* XFMF, rueck = W */ if ( ankunftsRichtung == "W") { this.turn(); // vor suedlichem NachbarMakrofeld if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { // XXF^F turnRight(); kara.move(); turnRight(); // karaTeilPos = "SE"; karaRichtung = "S"; if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { turnLeft(); kara.move(); turnRight(); makroZurueckXXFF(); } } } // end ankunft W else if ( ankunftsRichtung == "S") { // Fehler System.out.println("Fehler in makroSchrittXXFF, case 4, ankunft=S"); } // end ankunft S else if ( ankunftsRichtung == "E") { turnRight(); kara.move(); if (!this.betretungsversuchRechts()) // Ost-Makrofeld unten { turnLeft(); if (!this.betretungsversuchLinks()) // Sued-Makrofeld rechts { // karaTeilPos = "SE"; karaRichtung = "N"; turnLeft(); kara.move(); turnLeft(); if (!this.betretungsversuchRechts()) // Sued-Makrofeld links { // karaTeilPos = "SW"; karaRichtung = "N"; makroZurueckXXFF(); } } } } // end ankunft E else if (ankunftsRichtung == "N") { makroZurueckXXFF(); } else // Fehler { System.out.println("Fehler in makroSchrittXXFF, case 4"); } break; // end case 4 } // end switch } // end makroSchrittXXFF Klammer1 // --------------------------------------------------------------------------- // // makrofeldTyp = "XAFX" ; // -------------------------------------------------------------------- public void makroSchrittXAFX() { // normiert in N auf SW, System.out.println("+++ makroSchrittXAFX +++"); if (vorwaerts) { if (ankunftsSeite == "Links") // im normierten Fall gleichbedeutend mit (ankunftsRichtung == "N") { turnLeft(); // karaRichtung = "W"; // vor westlichem NachbarMakrofeld links if (!this.betretungsversuchLinks()) // West-Makrofeld untersuchen { /* XAF>X */ vorwaerts = false; markiere() ; turnRight() ; // if (leafOrTreeFront()) // Rückmarsch unmöglich if (kara.treeFront()) // Rückmarsch unmöglich; 6.11.01 { abschluss() ; // fertig } else { kara.move(); // karaRichtung = "S" makrofeldSeite = "Rechts"; karaTeilPos = "NW"; } } return ; } else /* ankunftsSeite == "Rechts" , ankunftsRichtung == "E" */ { turn(); if (!this.betretungsversuchRechts()) /* XA(F|M)^X */ { vorwaerts = false; markiere() ; turnLeft(); // if (leafOrTreeFront()) // Rückmarsch unmöglich if (kara.treeFront()) // Rückmarsch unmöglich; 6.11.01 { abschluss() ; // fertig } else { kara.move(); // karaRichtung = "W" makrofeldSeite = "Links"; karaTeilPos = "SE"; } } return ; } } // ende vorwaerts else /* rueckwaerts */ { if (kara.onLeaf()) { abschluss() ; return ; // fertig } else { kara.putLeaf(); if (ankunftsRichtung == "N") { turnLeft(); // if (leafOrTreeFront()) // Rückmarsch unmöglich if (kara.treeFront()) // Rückmarsch unmöglich; 6.11.01 { abschluss() ; // fertig } else { kara.move(); // karaRichtung = "W" makrofeldSeite = "Links"; karaTeilPos = "SE"; } } else { /* ankunftsRichtung = E */ turn(); // if (leafOrTreeFront()) // Rückmarsch unmöglich if (kara.treeFront()) // Rückmarsch unmöglich; 6.11.01 { abschluss() ; // fertig } else { kara.move(); // karaRichtung = "S" makrofeldSeite = "Rechts"; karaTeilPos = "NW"; } } return ; } } // ende rueckwaerts } // end makroSchrittXAFX // ------------------------------------------------------------------------- // Druckmaus-Teil public void phase1() { // o.B.d.A. Vorbedingung fuer Verifikation: // karaRichtung = "N" while (!kara.onLeaf()) { // Phase 1 nicht fertig while (!kara.treeFront()) { // Nord frei kara.move() ; } // Nordmauer erreicht if (kara.treeLeft()) { // N und W Mauern kara.putLeaf() ; if (kara.treeRight()) { turnRight(); if (kara.treeRight()) /* eingemauert */ // X // XMX // X abschluss(); // fertig = true ; else { turnRight(); kara.move(); if (kara.treeLeft()) // MXF>X { // makrofeldTyp = "XXMF"; makrofeldTypnummer = 3 ; } else { /* MXFF> makrofeldTyp = "XFMF"; */ makrofeldTypnummer = 5 ; } this.zurueck(); turn(); karaTeilPos = "NW"; karaRichtung = "S"; makrofeldSeite = "Rechts"; } } else { /* fertig mit Startphase */ // makrofeldTyp = "X?MF"; Typ 3 oder 5 // makrofeldTypnummer = 5 ; entfernt 6.12. turnRight(); karaTeilPos = "SW"; karaRichtung = "E"; makrofeldSeite = "Rechts"; } } // end Fall N und W Mauer else { // weiter nach W turnLeft() ; kara.move() ; while (kara.treeRight() & !kara.treeFront()) kara.move() ; if (!kara.treeRight()) {turnRight(); // weiter nach N suchen } else { // N und W Mauern und NE Mauer, XXFF makrofeldTypnummer = 3 ; karaTeilPos = "SW"; karaRichtung = "E"; makrofeldSeite = "Rechts"; // fertig mit phase 1 } } } //END while System.out.println("+++ Ende phase1 +++"); printSituation(); } // end phase1 // --------------------------------------------------------------------------- public void phase2() { System.out.println("+++ Beginn von phase2 +++"); vorwaerts = true ; while (!fertig) { // Kara befindet sich auf einem Makrofeld, // die Situation wird beschrieben durch: // fertig: Absuchen vollständig beendet // vorwaerts: Kara ist in Vorwärtsphase des Algorithmus // (vorwaerts spielt nur bei Typ 2 eine Rolle) // karaRichtung, karaTeilPos, makrofeldSeite : // Positionsbeschreibung auf Makrofeld // ankunftsrichtung, ankunftsPos, ankunftsSeite : Ankunftsposition // makrofeldTyp :siehe Report (keine Variable des Programms) // charakterisiert durch makrofeldTypnummer // das Makrofeld ist mit der Rückmarsch-Richtung makromarkiert // odere unmarkiert // wenn es ein freies NachbarMakrofeld gibt, so betrete dies // und makromarkiere, falls es nicht vom Typ 2 ist // Fallunterscheidung nach Typ des Makrofeldes // Normiere Position auf Makrofeld normierePosition() ; System.out.println("+++ in phase2 nach normierePosition() +++"); printSituation(); this.makroSchritt(); System.out.println("+++ in phase2 nach makroSchritt +++"); printSituation(); }// END while !fertig } // end phase2 // ------------------------------------------------------------------------- public void makroSchritt() { // // bestimme makrofeldTypnummer und mache Fallunterscheidung // this.berechneMakrofeldTypnummer(); // bereits in normierePosition enthalten switch (makrofeldTypnummer) { case 1: /* XM^4 */ System.out.println("makrofeldTypnummer 1 Fehler in makroSchritt") ; fertig = true; break; case 2: /* (X|M)XXF */ System.out.println("makrofeldTypnummer 2 X(X|F)FX"); makroSchrittXAFX() ; break; case 3: /* XXFF */ System.out.println("makrofeldTypnummer 3 XXFF"); makroSchrittXXFF(); break; case 5: /* XFFF */ System.out.println("makrofeldTypnummer 5 XFFF"); makroSchrittXFFF(); break; case 6: /* FFFF */ System.out.println("makrofeldTypnummer 6 FFFF"); makroSchrittFFFF(); break; } // end switch makrofeldTypnummer } // end makroSchritt // // :END DEFINE YOUR METHODS // --------------------------------------------------------------------------- public void myProgram() { // ------------------------------------------------------------------------- // START OF YOUR MAIN PROGRAM: this.fertig = false; // Suche geeignetes Start-Makrofeld this.phase1() ; // Simuliere M4' auf Makrofeldern this.phase2() ; abschluss() ; // Ende Simulation von Druckmaus4' // :END OF YOUR MAIN PROGRAM // ------------------------------------------------------------------------- } // myProgram // } // Druckmaus //