/*---------------------------------------------------------------------- Programm : hamster.c Autor : Michael Feist erstellt : 12.2.98 letzte Änd : 15.6.98 Beschreibung: Hamster-Steuerprogramm ----------------------------------------------------------------------*/ #include #include #include #include "hamster.h" #include "extds.h" /* externe Datenstrukturen: Stapel und Schlange */ #define maximalschrittzahl (120-6/durchschn_korn) /* Formel zur Berechnung der maximalen Entfernung des Hamsters vom Ursprung */ /*globale Variablen*/ int ges_schritt=0; /* insgesamt beim Erforschen zurückgelegter Weg */ int ges_korn=0; /* Gesamtkornzahl */ int durchschn_korn=12;/* durchschnittliche Körnerzahl pro Feld (nötig für Maximalschrittzahl) */ int alt_best=0; /*letzter Rückweg */ unsigned char feld[HMS_MAXXEXT*2][HMS_MAXYEXT*2]; /* Array für Infos zu jedem einzelnen Feld */ unsigned char kurz[HMS_MAXXEXT*2][HMS_MAXYEXT*2]; /* Array zum Speichern des kürzesten Weges */ p_stack stapel,st2; /* 2 Stapelspeicher (Zeiger) (siehe ExtDS.h)*/ p_queue rest; /* Zeiger auf eine Schlange */ int maxschritt=0; /* maxschritt >= aktuelle Enfernung vom Ursprung */ /*------Prototypen-der-verwendeten Funktionen--------Beschreibung-der-Funktionen---------*/ void drehen(HAMSTER *hms,int richtung); /* in bestimmte Himmelsrichtung drehen (optisch ansprechend!) */ void reste_testen (); /* Test, ob ehemals zu weit entfernte Felder jetzt auf kürzerem Weg erreichbar sind */ void umsehen(HAMSTER *hms); /* Erkundung des aktuellen Feldes sowie "Hineinschauen in benachbarte unbekannte Felder */ void umdrehen(HAMSTER *hms); /* zweimal rechtsdrehen */ unsigned char feld_vorn (HAMSTER *hms); /* Rückgabe aller bekannten Eigenschaften des Feldes vorm Hamster */ int kurzer_weg (int alt_x,int alt_y,int x,int y); /* Berechnung des kürzesten Wegs zwischen zwei Punkten (im erforschten Teil des Labyrinths) Ergebnis im Array 'kurz' */ int test_kreuz(int x,int y); /* Rückgabe vieviele unbekannte Richtungen ein Feld noch hat */ int naechste_richtung (int x, int y); /* wertet Array 'kurz' aus und gibt nächste Richtung gemäß kurzem Weg zurück */ void wegbringen (HAMSTER *hms); /* Aufnehmen aller Körner auf akt. Feld, ggf. wegbringen*/ void wegbringen2 (HAMSTER *hms); /* Körner wegbringen, falls ein Feld voll ist (HMS_MAXCORN (255)) */ int schritt_noetig (int x,int y,int ri,int look); /* Test, ob geplanter Schritt nötig ist. Vielleicht ist das Feld ja ringsherum schon erforscht oder der Weg zu lang.*/ void gehe_zu (HAMSTER *hms,int nx,int ny); /* Hamster geht auf kürzestem Weg zum angegebenen Punkt */ void hole (HAMSTER *hms,int *x_param,int *y_param); /* liefert Koordinaten des nächsten abzuarbeitenden Feldes */ int entfernung (int x, int y); /* Bestimmung des Abstandes des Feldes (x,y) vom Ursprung ohne Berücksichtigung der Wände */ void suche(HAMSTER *hms); /* Haupfunktion zur rekursiven Suche */ void hms_ctrl (HAMSTER *hms); /* Initialisierung und Aufruf von 'suche' */ /*---------------------------------------------------------------------- Funktionen ----------------------------------------------------------------------*/ void drehen(HAMSTER *hms,int richtung) /* Funktion: in bestimmte Himmelsrichtung drehen (optisch ansprechend!) Übergabe: Hamsterzeiger, Zielrichtung */ { int alt=hms_dir(hms); /* momentane Richtung */ if (richtung==alt+1||(!richtung&&alt==3)) hms_turn(hms,HMS_LEFT); /* if-Teil, falls eine Drehung nach links nötig */ else /* sonst rechtsrum drehen... */ while (hms_dir(hms)!=richtung) hms_turn(hms,HMS_RIGHT); /*...bis gewünschte Richtung erreicht */ } /*---------------------------------------------------------------------*/ void reste_testen () /* Funktion: Test, ob ehemals zu weit entfernte Felder jetzt auf kürzerem Weg erreichbar sind ggf. Koordinaten aus 'rest' auf Stapel sichern */ { int x,y,weg; p_queue save=create_queue(); /* neue Schlange zum "umschichten" */ if (empty_queue(rest)) return; /* Rücksprung, falls Resteschlange leer */ weg=kurzer_weg(2*HMS_MAXXEXT,2*HMS_MAXYEXT,HMS_MAXXEXT,HMS_MAXYEXT); /* Entfernung jedes erforschten Punktes vom Ursprung ermitteln (in 'kurz') */ while (!empty_queue (rest)) /* alle Koordinaten aus 'rest' */ { x=pop_queue(rest); /* x und y lesen */ y=pop_queue(rest); if (kurz[x+HMS_MAXXEXT][y+HMS_MAXYEXT]>=maximalschrittzahl) /*immer noch zu weit weg? */ { push_queue(save,x); /* ja -> Koordinaten wieder in Warteschlange */ push_queue(save,y); } else { feld[x+HMS_MAXXEXT-1][y+HMS_MAXYEXT]&=127; /* nein -> Nachbarfelder wieder zum Erforschen "freigeben" */ feld[x+HMS_MAXXEXT+1][y+HMS_MAXYEXT]&=127; feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT-1]&=127; feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT+1]&=127; push_stack (stapel,x); /* Punkt auf Stapel, später Rückkehr hierher */ push_stack (stapel,y); } } delete_queue(rest); /* geleerte Schlange löschen */ rest=save; /* neue 'rest'-Schlange ist 'save' */ } /*---------------------------------------------------------------------*/ void umsehen(HAMSTER *hms) /* Funktion: Erkundung des aktuellen Feldes sowie "Hineinschauen in benachbarte unbekannte Felder Übergabe: Hamsterzeiger */ { int x,y,z=3,wert=durchschn_korn; hms_pos (hms,&x,&y); x+=HMS_MAXXEXT; y+=HMS_MAXYEXT; /* x und y "positiv machen" */ ges_schritt++; /* ein weiterer Schritt auf unbekanntes Gebiet */ ges_korn+=hms_corn(hms); /* Gesamtkörnerzahl erhöhen */ if (ges_schritt>50) durchschn_korn=(int)(ges_korn/ges_schritt+.5); /* Körnerdurchschnitt nach 50 Schritten erstmals berechnen */ if (!durchschn_korn) durchschn_korn=1; /* sonst Division durch Null in 'holen' */ feld[x][y]|=16; /* 16 -> Feld untersucht */ for (;z;z--) /* 3 Durchläufe */ { if (hms_look(hms)!=HMS_WALL) /* keine Wand... */ { switch (hms_dir(hms)) /* welche Richtung momentan? */ { case HMS_SOUTH: /* Süden */ feld[x][y]&=254; /* Wand im Süden löschen (0-tes Bit (Wert:1)) */ feld[x][y-1]&=251;break; /* Nordwand des Feldes unterhalb des akt. Feldes löschen */ case HMS_EAST: /* Osten */ feld[x][y]&=253; /*analog zu 'HMS_SOUTH' */ feld[x+1][y]&=247;break; case HMS_NORTH: /* Norden */ feld[x][y]&=251; feld[x][y+1]&=254;break; case HMS_WEST: /* Westen */ feld[x][y]&=247; feld[x-1][y]&=253;break; } } if (!(feld_vorn(hms)&16)) /* Feld vorn noch nicht betreten? */ { /* wenn ja --> Hineinschauen */ wert=0; if (hms_look(hms)==HMS_CORN) wert=64; /* 6.Bit (Wert:64) entspricht: Korn liegt auf Feld */ switch (hms_dir(hms)) /* welche Richtung? */ { case HMS_SOUTH: feld[x][y-1]|=wert;break; /* Erkenntnis in 'feld' sichern */ case HMS_EAST: feld[x+1][y]|=wert;break; case HMS_NORTH: feld[x][y+1]|=wert;break; case HMS_WEST: feld[x-1][y]|=wert;break; } } if (z==2) umdrehen(hms); /* in drei verschieden Richtungen drehen */ else hms_turn(hms,HMS_LEFT); } reste_testen (); /* ein neues Feld erkundet --> ein zu langer Weg könnte jetzt kürzer sein */ } /*---------------------------------------------------------------------*/ void umdrehen (HAMSTER *hms) /* Funktion: zweimal rechtsdrehen Übergabe: Hamsterzeiger */ { hms_turn (hms,HMS_RIGHT); hms_turn (hms,HMS_RIGHT); } /*---------------------------------------------------------------------*/ unsigned char feld_vorn (HAMSTER *hms) /* Funktion: Versuch, das Feld vorm Hamster zu beschreiben; Übergabe: Hamsterzeiger Rückgabe: bitweise kodierte Eigenschaften des Feldes vorm Hamster 0, falls unbekannt */ { int x,y; hms_pos (hms,&x,&y); /* Koordinaten des aktuellen Feldes */ switch (hms_dir(hms)) { case HMS_SOUTH: y--; break; /* akt. Koordinaten entsprechend Richtung verändern */ case HMS_EAST: x++; break; case HMS_NORTH: y++; break; case HMS_WEST: x--; } return feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]; /* Rückgabe */ } /*---------------------------------------------------------------------*/ int kurzer_weg (int alt_x,int alt_y,int x,int y) /* Funktion: Berechnung des kürzesten Wegs zwischen zwei Punkten (im erforschten Teil des Labyrinths) Übergabe: Koordinaten des aktuellen Feldes und des Zielfeldes (jeweils positiv, absolut) Rückgabe: Weglänge, Abstände vom Zielpunkt im Array 'kurz' */ { int v1=0,v2,schrittzahl=1; p_queue schlange = create_queue(); /* leere Schlange erzeugen */ for (;v1 dann noch einmal */ } /*---------------------------------------------------------------------*/ void wegbringen2 (HAMSTER *hms) /* Funktion: Körner wegbringen, falls ein Feld voll ist (HMS_MAXCORN (255)) (vereinfachte 'wegbringen'-Funktion) Übergabe: Hamsterzeiger */ { int x,y,alt_x,alt_y; int schritte; hms_pos(hms,&x,&y); alt_x=x; alt_y=y; schritte=kurzer_weg (x+HMS_MAXXEXT,y+HMS_MAXYEXT,HMS_MAXXEXT,HMS_MAXYEXT); /* kürzesten Rückweg berechnen */ while (x||y) /* solange nicht im Ursprung */ { drehen (hms,naechste_richtung(x+HMS_MAXXEXT,y+HMS_MAXYEXT)); /* Rückweg */ hms_move(hms); hms_pos(hms,&x,&y); if (!(feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]&16)) /* Feld unerforscht? */ { umsehen (hms); if (test_kreuz(x+HMS_MAXXEXT,y+HMS_MAXYEXT)||hms_corn(hms)) { push_stack(stapel,x); push_stack(stapel,y); } } if (test_kreuz(x+HMS_MAXXEXT,y+HMS_MAXYEXT)||hms_corn(hms)) break; /* Kornfeld oder Kreuzung? */ } hms_drop(hms,HMS_MAXLOAD); /* abladen */ if (x||y) feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]|=64; if (hms_corn(hms)==HMS_MAXCORN) /* dieses Feld auch wieder voll? */ { hms_take(hms,HMS_MAXLOAD); wegbringen2(hms); } } /*---------------------------------------------------------------------*/ int schritt_noetig (int x,int y,int ri,int look) /* Funktion: Test, ob geplanter Schritt nötig ist. Vielleicht ist das Feld ja ringsherum schon erforscht oder der Weg zu lang. Übergabe: absolute Koordinaten des Feldes, Blickrichtung, Aussicht Rückgabe: bool'scher Ausdruck */ { int temp_x=x-HMS_MAXXEXT,temp_y=y-HMS_MAXYEXT; /* relative Koordinaten in temp */ switch (ri) /* relative Koordinaten des zu untersuchenden Feldes ermitteln */ { case HMS_SOUTH: temp_y--; break; case HMS_EAST: temp_x++; break; case HMS_NORTH: temp_y++; break; default: temp_x--; } if (maxschritt+1>=maximalschrittzahl) /* Rückweg zu lang? */ { maxschritt=kurzer_weg (x,y,HMS_MAXXEXT,HMS_MAXYEXT); /* Rückweg (maxschritt) genau berechnen */ if (maxschritt>=maximalschrittzahl||(maxschritt+1==maximalschrittzahl && look!=HMS_CORN)) /* Rückweg immernoch zu lang oder auf letztem "rentablen" Feld kein Korn */ { feld[temp_x+HMS_MAXXEXT][temp_y+HMS_MAXYEXT]|=128; /* Feld als zu weit entfernt markieren */ push_queue (rest,x-HMS_MAXXEXT); /* dieses Feld für späteren Test in Warteschlange */ push_queue (rest,y-HMS_MAXYEXT); return 0; /* Abbruch (Schritt nicht nötig) */ } } if ((ri==HMS_SOUTH && feld[x ][y-2]&16 && feld[x-1][y-1]&16 && feld[x+1][y-1]&16) || (ri==HMS_EAST && feld[x+1][y+1]&16 && feld[x+1][y-1]&16 && feld[x+2][y ]&16) || (ri==HMS_NORTH && feld[x ][y+2]&16 && feld[x-1][y+1]&16 && feld[x+1][y+1]&16) || (ri==HMS_WEST && feld[x-1][y+1]&16 && feld[x-2][y ]&16 && feld[x-1][y-1]&16)) /* falls folgendes Feld von drei bekannten Feldern umgeben ist, sind alle Informationen für dieses Feld vorhanden */ { if (feld[temp_x+HMS_MAXXEXT][temp_y+HMS_MAXYEXT]&64) { push_stack(stapel,temp_x); /* Koordinaten sichern, falls Korn darauf */ push_stack(stapel,temp_y); } feld[temp_x+HMS_MAXXEXT][temp_y+HMS_MAXYEXT]|=16; /* Feld kann als erkundet angesehen werden */ reste_testen(); /* Test, ob zu weit entfernte Punkte jetzt näher am Ursprung sind */ return 0; /* Abbruch, kein Schritt nötig */ } return 1; /* sonst, Schritt ist nötig */ } /*---------------------------------------------------------------------*/ void gehe_zu (HAMSTER *hms,int nx,int ny) /* Funktion: Hamster geht auf kürzestem Weg zum angegebenen Punkt Übergabe: Hamsterzeiger, neue Koordinaten (relativ, d.h. so wie von hms_pos zurückgegeben */ { int x,y,weg; hms_pos(hms,&x,&y); if (x==nx&&y==ny) return; /* Abbruch, falls Ziel gleich aktuellem Feld (Abfrage nur, um unnötigen Aufruf von 'kurzer_weg' zu vermeiden) */ weg=kurzer_weg (x+HMS_MAXXEXT,y+HMS_MAXYEXT,nx+HMS_MAXXEXT,ny+HMS_MAXYEXT); /* kurzen Weg in 'kurz' speichern */ while (x!=nx||y!=ny) /* so lange gehen, bis Zielpunkt erreicht */ { drehen (hms,naechste_richtung (x+HMS_MAXXEXT,y+HMS_MAXYEXT)); /* entsprechend 'kurz' drehen */ hms_move(hms); /* gehen */ hms_pos(hms,&x,&y); } } /*---------------------------------------------------------------------*/ void hole (HAMSTER *hms,int *x_param,int *y_param) /* Funktion: Koordinaten des als nächstes abzuarbeitenden Feldes zurückgeben Übergabe: Hamsterzeiger, Adressen auf zwei Integerzahlen (für die neuen Koordinaten */ { int x,y,akt_x,akt_y,best_x=0,best_y=0; float weg,best=0; unsigned char kurz_punkt [HMS_MAXXEXT*2][HMS_MAXYEXT*2]; /* Array analog zu 'kurz' zum Speichern der Entfernung beliebiger Felder von einem best. Feld */ p_stack save=create_stack(); /* einen weiteren Stapel erzeugen */ hms_pos(hms,&akt_x,&akt_y); kurzer_weg (2*HMS_MAXXEXT,2*HMS_MAXYEXT,akt_x+HMS_MAXXEXT,akt_y+HMS_MAXYEXT); /* Aufruf von 'kurzer_weg' mit unerreichbarem Punkt --> jedem bekannten Feld wird ein Abstand zum aktuellen Feld zugeordnet */ for (x=0;x<2*HMS_MAXXEXT;x++) /* Umspeichern von 'kurz' in 'kurz_punkt' */ for (y=0;y<2*HMS_MAXYEXT;y++) kurz_punkt[x][y]=kurz[x][y]; kurzer_weg (2*HMS_MAXXEXT,2*HMS_MAXYEXT,HMS_MAXXEXT,HMS_MAXYEXT); /* erneut 'kurzer_weg' mit unerreichbarem Feld --> aber diesmal Abstand vom Ursprung */ y=pop_stack(stapel); /* erstes Tupel vom Stapel holen */ x=pop_stack(stapel); if (empty_stack(stapel)) /* falls nur ein Feld auf Stapel, dieses zurückgeben */ { *x_param=x; *y_param=y; maxschritt=kurz[x+HMS_MAXXEXT][y+HMS_MAXYEXT]-1; /* Maxschritt für neues Feld setzen */ return; /* Rücksprung */ } push_stack (save,x); /* akt. Koordinaten sichern */ push_stack (save,y); while (!empty_stack(stapel)) /* gesamten Stapel durchlaufen */ { /* optimaler Punkt sollte so weit wie möglich vom Ursprung entfernt, aber so nah wie möglich am akt. Feld sein (die Nähe hat Priorität (Quadrat und +2)) */ weg=(float)(kurz[x+HMS_MAXXEXT][y+HMS_MAXYEXT])/(float)(2+kurz_punkt[x+HMS_MAXXEXT][y+HMS_MAXYEXT]*kurz_punkt[x+HMS_MAXXEXT][y+HMS_MAXYEXT]); if (weg>=best) {best=weg; best_x=x; best_y=y;} /* falls optimaleres Feld gefunden, dieses merken */ y=pop_stack(stapel); /* nächstes Feld vom Stapel testen */ x=pop_stack(stapel); push_stack (save,x); /* akt. Koordinaten sichern */ push_stack (save,y); } while (!empty_stack (save)) /* alle Koordinaten außer den optimalen wieder zuück auf den Stapel */ { y=pop_stack(save); x=pop_stack(save); if (x!=best_x || y!=best_y) { push_stack(stapel,x); push_stack(stapel,y); } } *x_param=best_x; /* optimale Koordinaten zurückliefern */ *y_param=best_y; maxschritt=kurz[x+HMS_MAXXEXT][y+HMS_MAXYEXT]-1; /* maxschritt entsprechend diesen Koordinaten */ delete_stack(save); /* Sicherungs-Stapel löschen */ } /*---------------------------------------------------------------------*/ int entfernung (int x, int y) /* Funktion: Bestimmung des Abstandes des Feldes (x,y) vom Ursprung ohne Berücksichtigung der Wände Übergabe: relative Koordinaten des Feldes Rückgabe: Abstand mit Priorität auf diagonale Felder */ { return abs(x)+abs(y)+abs(abs(x)-abs(y)); } /*---------------------------------------------------------------------*/ void suche (HAMSTER *hms) /* Funktion: Haupfunktion zur rekursiven Suche Übergabe: Hamsterzeiger */ { int ri,x,y,x_abs,y_abs; int best_dir=32000,richt=4; int nord=1,ost=1,sued=1,west=1; hms_pos(hms,&x,&y); if(!(feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]&16)) /* falls akt. Feld vorher noch nicht betreten, dieses jetzt untersuchen */ umsehen (hms); ri=test_kreuz(x+HMS_MAXXEXT,y+HMS_MAXYEXT); /* Anzahl der von diesem Feld ausgehenden unerforschten Nachbarfelder */ if (ri>1||hms_corn(hms)) /* falls mehr als eine Richtung oder Körner auf dem Feld, Rückkehr zu diesem Feld nötig --> Koordinaten auf Stapel */ { push_stack(stapel,x); push_stack(stapel,y); } if (ri) /* falls keine Sackgasse... */ { x_abs=x+HMS_MAXXEXT; /* Absolutwerte für übersichtlichere Funktionsaufrufe */ y_abs=y+HMS_MAXYEXT; nord=entfernung(x,y+1); /* zuerst dem Ursprung möglichst nahe Felder erforschen (für besseren Rückweg) */ ost =entfernung(x+1,y); west=entfernung(x-1,y); sued=entfernung(x,y-1); if (!(feld[x_abs][y_abs-1]&144 || feld[x_abs][y_abs]&1)) /* falls Feld im Süden unerforscht, nicht zu weit weg und keine Wand dazwischen... */ { best_dir=sued; richt=HMS_SOUTH;} /* zunächst Süden als optimale Erkundungsrichtung annehmen */ if (!(feld[x_abs][y_abs+1]&144 || feld[x_abs][y_abs]&4)) /* falls Feld im Norden unerforscht, nicht zu weit weg und keine Wand dazwischen... */ if (nord<=best_dir) /* wenn außerdem nördl. Feld dichter am Ursprung, dann Norden als beste Richtung annehmen */ { best_dir=nord; richt = HMS_NORTH;} if (!(feld[x_abs+1][y_abs]&144 || feld[x_abs][y_abs]&2)) /* analog */ if (ost<=best_dir) { best_dir=ost; richt = HMS_EAST;} if (!(feld[x_abs-1][y_abs]&144 || feld[x_abs][y_abs]&8)) if (west<=best_dir) { best_dir=west; richt = HMS_WEST;} switch (richt) /* absolute Koordinaten entsprechen nächster Richtung verändern */ { case HMS_SOUTH: y_abs--;break; case HMS_EAST: x_abs++;break; case HMS_NORTH: y_abs++;break; case HMS_WEST: x_abs--; } best_dir=kurzer_weg(x_abs,y_abs,HMS_MAXXEXT,HMS_MAXYEXT); /* realen Abstand des nächsten Feldes vom Ursprung ermitteln */ if (alt_best>=best_dir && hms_corn(hms)) /* falls Annäherung an Ursprung und Körner auf akt. Feld */ { wegbringen (hms); /* diese Körner mitnehmen */ gehe_zu (hms,x,y); /* zum Ausgangsfeld zurück */ } else /* falls Entfernung vom Ursprung */ if (ri>1||hms_corn(hms)) /* Körner auf geeignetem Feld (auf das sowieso zurückgekehrt werden muß) ablegen */ { hms_drop (hms,HMS_MAXLOAD); if (hms_corn(hms)) feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]|=64; } alt_best = best_dir; /* Merken des aktuellen Rückwegs für nächsten Schritt */ drehen (hms,richt); /* jetzt in berechnete Richtung drehen */ if (schritt_noetig(x+HMS_MAXXEXT,y+HMS_MAXYEXT,hms_dir(hms),hms_look(hms))) { /* wenn Schritt wirklich nötig ist, diesen tun */ maxschritt++; hms_move (hms); suche(hms); /* vom aktuellen Feld aus erneut Suche starten */ } } /* hier landet das Programm, wenn die Suche in einer Sackgasse endet oder keine unbekannten Felder angrenzen */ while (!empty_stack(stapel)) /* alle Punkte, zu denen zurückgekehrt werden muß, abarbeiten */ { hole (hms,&x,&y); /* Koordinaten des günstigsten Feldes holen */ if (feld[x+HMS_MAXXEXT][y+HMS_MAXYEXT]&64) /* Korn auf diesem Feld? */ { gehe_zu(hms,x,y); wegbringen(hms); /* Körner aufnehmen von diesem Feld */ } if (test_kreuz(x+HMS_MAXXEXT,y+HMS_MAXYEXT)) /* unerforschte Richtungen von diesem Feld ausgehend? */ { gehe_zu(hms,x,y); suche(hms); /* Suche von diesem Feld aus beginnend starten */ } } } /*---------------------------------------------------------------------*/ void hms_ctrl (HAMSTER *hms) /* Funktion: Initialisierung und Aufruf von 'suche' Übergabe: Hamsterzeiger */ { int x,y; stapel=create_stack(); /* Stapel erzeugen für Felder, auf die zurückgekehrt werden muß */ rest=create_queue(); /* Schlange für zunächst zu weit vom Ursprung entfernte Felder */ for (x=0;x