Der Weg durch den Irrgarten

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Xeon
Beiträge: 24
Registriert: So Dez 17, 2017 4:10 pm

Der Weg durch den Irrgarten

Beitrag von Xeon » Mo Sep 09, 2019 2:23 pm

Hallo zusammen

Habe wieder ein Problem oder ob es überhaupt eins ist?
Hier der Link: http://openbook.rheinwerk-verlag.de/c_v ... 5110704913

Hier der Code:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef __unix__
   #define clrscr() printf("\x1B[2J")
#elif __BORLANDC__ && __MSDOS__
   #include <conio.h>
#elif __WIN32__ || _MSC_VER
#define clrscr() system("cls")
#else
   #define clrscr() printf("clrscr() - Fehler!!\n")
#endif

#define HINDERNISSE 100

char spielfeld[15][50];

void createspielfeld(void) {
   int i, j, x, y;
   for(i=0, j=0; j < 50; j++)
      spielfeld[i][j] = '#';

   for(i=1 ;i < 15; i++)
      for(j=0;j<50;j++) {
         if(j==0 || j==49)
            spielfeld[i][j] = '#';
         else
            spielfeld[i][j] = ' ';
         if(i==13 && j==48)
            spielfeld[i][j] = 'O';
      }
      for(i=14,j=0;j<50;j++)
         spielfeld[i][j] = '#';

      for(i=0;i<=HINDERNISSE;i++) {
         x=rand()%14;
         y=rand()%48;
         if(x<15&&y<50 && x>0&&y>0)
            spielfeld[x][y] = '*';

      }

   spielfeld[1][1]=' ';
}

void showspielfeld(void) {
   int i, j;
   clrscr();
   for(i=0; i < 15; i++)
      for(j=0;j<50;j++) {
         printf("%c",spielfeld[i][j]);
         if(j==49)
            printf("\n");
      }
}

int step(int x, int y, int xalt, int yalt) {
   printf("<ENTER>");  getchar();
   if(spielfeld[x][y] == 'O') { /* Sind wir am Ziel? */
      spielfeld[x][y] = 'C';
      spielfeld[xalt][yalt] = ' ';
      showspielfeld();
      printf("Mister C ist zu Hause!\n");
      exit (EXIT_SUCCESS);
   }
   else if(spielfeld[x][y] == ' ') {
      spielfeld[x][y] = 'C';
      spielfeld[xalt][yalt] = ' ';
      showspielfeld();
      /* ... nach rechts */
      if( y+1<49 && spielfeld[x][y+1] !='*' &&
          yalt!=y+1 && step(x,y+1,x,y) )
         return 1;
      /* ... nach unten */
      else if( x+1<14 && spielfeld[x+1][y] !='*' &&
               xalt!=x+1 && step(x+1,y,x,y) )
         return 1;
      /* ... nach oben */
      else if( x-1>0 && spielfeld[x-1][y] !='*' &&
               xalt!=x-1 && step(x-1,y,x,y) )
         return 1;
      /* ... nach links */
      else if( y-1>0 && spielfeld[x][y-1] !='*' &&
               yalt!=y-1 && step(x,y-1,x,y) )
         return 1;
   }
 return 0;
}


int main(void) {
   createspielfeld();
   step(1,1,1,1);
   return EXIT_SUCCESS;
}
Meine Frage bei der step Funktion: Ich verstehe die Logik nicht wie ich zum den return 1; Werten komme.
Komme mir blöd vor wenn ich so oft Fragen stelle.

Danke im Voraus!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8499
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Der Weg durch den Irrgarten

Beitrag von Xin » Mo Sep 09, 2019 2:48 pm

Xeon hat geschrieben:
Mo Sep 09, 2019 2:23 pm
Meine Frage bei der step Funktion: Ich verstehe die Logik nicht wie ich zum den return 1; Werten komme.
Der Quellcode ist falsch kommentiert und den Aufbau finde ich auch... ähh... "interessant".

So wie ich das sehe gibt es nur einen Grund return 1 zu erreichen: Wenn ein step-Aufruf zuvor return 1 zurück gibt.
Da das nie passiert, da das Programm bei Erfolg mittels exit() abgebrochen wird, ist es vollkommen egal, was das Programm zurück gibt. Wichtig ist nur, dass es bei Misserfolg in den else-Zweig kommt, also 0 zurück gibt, damit es im then-Part nicht 1 zurückgibt.

Kurz: man hätte ich sich den then-Part auch schenken können.
Da es niemals zum then part kommen kann, sondern immer nur zum else Part, könnte man sich auch sparen, daraus eine Abfrage zu machen.

Code: Alles auswählen

      y+1<49 && spielfeld[x][y+1] !='*' && yalt!=y+1 && step(x,y+1,x,y);
      x+1<14 && spielfeld[x+1][y] !='*' && xalt!=x+1 && step(x+1,y,x,y);
      x-1>0 && spielfeld[x-1][y] !='*' && xalt!=x-1 && step(x-1,y,x,y) );
      y-1>0 && spielfeld[x][y-1] !='*' && yalt!=y-1 && step(x,y-1,x,y) );
Wenn man doch eine Abfrage reinmacht, könnte man sich aufgrund der Rekursivität auch den Rückgabewert von step schenken, der hier nur benutzt wird, damit das Ding in den Ausdruck mit den && reinpasst.

Code: Alles auswählen

      if( y+1<49 && spielfeld[x][y+1] !='*' && yalt!=y+1 ) step(x,y+1,x,y);
      if( x+1<14 && spielfeld[x+1][y] !='*' && xalt!=x+1 ) step(x+1,y,x,y);
      if( x-1>0 && spielfeld[x-1][y] !='*' && xalt!=x-1 ) step(x-1,y,x,y) );
      if( y-1>0 && spielfeld[x][y-1] !='*' && yalt!=y-1 ) step(x,y-1,x,y) );
Wenn das Programm immernoch identisch funktioniert, hat der Autor den Quellcode sinnlos verkompliziert.
Wenn nicht, dann habe ich den Quellcode auch nicht verstanden. :lol:
Xeon hat geschrieben:
Mo Sep 09, 2019 2:23 pm
Komme mir blöd vor wenn ich so oft Fragen stelle.
Du scheinst Dich sehr an dem Buch entlang zu hangeln.
Ich würde Dir raten, das Buch zu rate zu ziehen, wenn Du was für Dein Programm wissen willst. Es nutzt Dir meiner Meinung nach weniger, wenn Du alles lernst, aber nichts davon je benutzt hast.

Das Buch von Jürgen Wolf ist ziemlich als 'schlecht' verschrien. Ich kenne es nicht wirklich, wüsste bei dem Quelltext aber auch nicht, wie ich das widerlegen sollte.

Das Forum ist dafür da, dass man Fragen stellen kann. Wenn sich andere nicht trauen oder nichts lernen, soll das nicht Dein Problem sein.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten