Mein TicTacToe-Programm - Wer Lust hat schaue drüber (Warnung: relativ viel Quelltext)



  • Abend!

    Hab mein TicTacToe Programm fertig geschrieben (für Windows Konsole).

    Würde mich freuen, wenn jemand mit mehr Erfahrung als ich nen Blick drauf wirft und Kritik übt.

    Es sind wie man sieht ne Menge Zeilen: Wer kein bock drauf hat, braucht nicht weiter lesen. Kann ich auch verstehen 😉

    Das Programm ist erstmal nur für zwei menschliche Spieler ausgelegt, in Zukunft soll es noch nen Singleplayer gegen den Computer(KI) geben.

    Das Programm ist unterteilt in:

    Hauptprogramm main.c
    Unterprogramm anzeigen.c
    Unterprogramm spielzug.c
    Funktion test_voll.c
    Funktion test_gewonnen.c

    Hier die Quelltexte (dürft ihr natürlich gerne kopieren und kompilieren):

    main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    
    int main(void)
    {
      int spielfeld[3][3];
      int zeile,spalte;
      int wahl;
      int voll, gewonnen;
      int spieler = 1;      // Spieler 1 beginnt
    
      /*Initialisierung bzw Zurücksetzen des Spielfelds*/
      do {        
              for(zeile=0;zeile<3;zeile++)
              {
                   for(spalte=0;spalte<3;spalte++)
                   {
                       spielfeld[zeile][spalte]=0;
                   }
              } 
    
          /*Ausgabe Begrüßungsmeldung und Hauptmenü*/
          printf("\nWillkommen zu TicTacToe!\n\n");
          printf("[1] Spielen\n");
          printf("[2] Beenden\n\n");
    
          /*Warten auf Eingabe Auswahl, Fehleingaben abfangen*/
          do{
                 wahl = getch() - 48;                
    
              /*Auswerten der Auswahl*/                   
                 switch (wahl)
                 {
                        case 1: printf("\nAuf gehts!!");                             // Spiel beginnt, wenn Auswahl 1 
                                sleep(1000);
    
                                do {                                                 
                                    anzeigen(spielfeld, spieler);                    // Unterprogramm bildet aktuelle Spielfeld-Matrix ab
    
                                    spielzug(spielfeld,spieler);                     // Unterprogramm fordert Spieler auf, sein Kreuz/Kreis zu setzen
    
                                    gewonnen = test_gewonnen(spielfeld,spieler);     // Funktion testet, ob Spieler gewonnen hat
    
                                    voll = test_voll(spielfeld);                     // Funktion testet, ob Spielfeld-Matrix voll ist
    
                                    if ( gewonnen == 1 )                             // Entsprechende Bildschirmausgabe bei Sieg
                                    {
                                         anzeigen(spielfeld,spieler);
                                         printf(" Das Spiel ist vorbei!!");
                                         sleep(2000);
                                         anzeigen (spielfeld,spieler);
                                         printf(" Der Gewinner ist: ");
                                         sleep(2000);
                                         printf("Spieler %d !", spieler);
                                         sleep(5000);
                                    }    
    
                                    else if ( voll == 1 && gewonnen == 0 )           // Entsprechende Bildschirmausgabe bei Unentschieden
                                    {
                                         anzeigen(spielfeld,spieler);
                                         printf(" Das Spiel ist unentschieden!");
                                         sleep(5000);
                                    }     
    
                                    else if ( voll == 0 && gewonnen == 0 )           // Falls Spiel noch läuft, ist der jeweils andere Spieler dran
                                    {
                                         switch(spieler)
                                         {
                                                case 1: spieler = 2;                 // Wenn Spieler 1 dran war, ist jetzt Spieler 2 am Zug
                                                break;
                                                case 2: spieler = 1;                 // Wenn Spieler 2 am Zug war, ist Spieler 1 wieder dran
                                                break;
                                         }
                                    }
    
                               } while (! (voll == 1 || gewonnen ==1) );             // Schleife läuft solange, bis jemand gewinnt oder das Spiel unentschieden ist
    
                               system("cls");
                               break;
    
                      case 2: printf("\nAuf Wiedersehen!\n");                        // wenn Auswahl 2, verabschiedet sich das Programm
                              sleep(2000);
                              break;
    
                      default: printf("Bitte dr""\x81""cke 1 oder 2!\n"); 
                               break;
                }
              } while( ! (wahl == 1 || wahl == 2) );    
          } while ( ! ( wahl == 2 ) );                                               // wenn Auswahl nicht 2 war und das Spiel vorbei ist, fängt das Programm von vorne an
    
      return 0;
    }
    

    anzeigen.c

    /*Formatierte Bildschirmausgabe der spielfeld-Matrix*/
    
    void anzeigen(int spielfeld[3][3], int spieler)
    {
           int zeile,spalte;
    
           system("cls");
           printf("_______________________________\n");
           printf("\n\n\t1\t2\t3\n\n\n");                 // Angabe der Spalten
    
           for( zeile = 0; zeile < 3; zeile++ )
           {   
               printf("  %i\t",zeile+1);                  // Angabe der Zeilen 
    
               for( spalte = 0; spalte < 3; spalte++ )           
                  {              
                      switch( spielfeld[zeile][spalte] )
                      {
                           case 0: printf("-\t");       // wenn Eintrag in der Matrix 0 ist, hat kein Spieler sein Kreu/Kreis gesetzt, ein - wird abgebildet
                                   break;
    
                           case 1: printf("X\t");       // Wenn Eintrag in der Matrix 1 ist, hat Spieler 1 sein Kreuz gesetzt, ein X wird abgebildet
                                   break;
    
                           case 2: printf("O\t");       // Wenn Eintrag in der Matrix 2 ist, hat Spieler 2 sein Kreis gesetzt, ein O wird abgebildet
                                   break;                               
                      }
                  }
    
                  printf("\n\n\n\n");             
           }
    
            printf("_______________________________\n\n");
            printf(" Spieler (%d) ist an der Reihe\n",spieler);         // Programm zeigt an, welcher Spieler am Zug ist
            printf("_______________________________\n\n");       
    
            return;
      }
    

    spielzug.c

    /*Aktueller Spieler setzt seinen Eintrag in die Spielfeldmatrix*/
    void spielzug(int spielfeld[3][3], int spieler)
    {      
           int zeile,spalte;
    
           do{
                  do{                  
                      sleep(500);          
                      printf(" Zeile: ");          //Aufforderung, Zeile anzugeben
    
                      zeile = getch()-48;          // Eingabe der gewünschten Zeile
                      printf("%d",zeile);                  
    
                      if (zeile < 1 || zeile > 3)          // Eventuelle Fehleingaben abfangen und formatierte Fehlermeldung ausgeben
                      {
                         anzeigen(spielfeld,spieler);
                         printf(" Bitte nur 1, 2 oder 3 eingeben!"); // Fehlermeldung erscheint für 1,5 Sekunden
                         sleep(1500);
                         anzeigen(spielfeld,spieler);
                      }
    
                  } while ( !(zeile >= 1 && zeile <= 3) );          // Schleife läuft solange, bis Eingabe korrekt
    
                  do{                      
                      sleep(500);
                      printf("\tSpalte: ");          // Aufforderung, Spalte anzugeben
    
                      spalte = getch()-48;           // Eingabe der gewünschten Spalte
                      printf("%d",spalte);
    
                      if (spalte < 1 || spalte > 3)     // Eventuelle Fehleingaben abfangen und formatierte Fehlermeldung ausgeben
                      {
                         anzeigen(spielfeld,spieler);
                         printf(" Bitte nur 1, 2 oder 3 eingeben!");  // Fehlermeldung erscheint für 1,5 Sekunden
                         sleep(2000);
                         anzeigen(spielfeld,spieler);
                         printf(" Zeile: ");
                         printf("%d",zeile);
    
                      }
                  } while ( !(spalte >= 1 && spalte <= 3) );        // Schleife läuft solange, bis Eingabe korrekt
    
                  if (spielfeld[zeile-1][spalte-1] != 0)            // Falls Eintrag nicht möglich, da Feld schon belegt, formatierte Fehlermeldung ausgeben
                  {
                      anzeigen(spielfeld,spieler);
                      printf(" Das Feld ist bereits belegt!");      // Fehlermeldung erscheint für 2 Sekunden
                      sleep(2000);
                      anzeigen(spielfeld,spieler);
                  }
    
           } while (! ( spielfeld[zeile-1][spalte-1] == 0) ); // Schleife läuft so lange, bis die Eingabe korrekt und das Feld belegbar ist
    
           spielfeld[zeile-1][spalte-1] = spieler;   // Das Feld wird mit entsprechendem Eintrag in der Spielfeld Matrix vom jeweiligen Spieler belegt
    
           sleep(500);
    
    }
    

    test_voll.c

    /*Überprüfung, ob Spielfeld voll ist, wenn ja return 1; wenn nein return 0; */
    
    int test_voll(int spielfeld[3][3])
    {
           int zeile, spalte;
    
           for (zeile = 0; zeile < 3; zeile++)
           {
               for (spalte = 0; spalte < 3; spalte++)
               {
                   if ( spielfeld[zeile][spalte] == 0 )
                      return 0;  
               }
           }             
        return 1; 
    }
    

    test_gewonnen.c

    /*Überprüfung, ob der aktuelle Spieler gewonnen hat*/
    
    int test_gewonnen(int spielfeld[3][3], int spieler)
    {
        int zeile, spalte;
        int treffer = 0;
    
        /*Überprüfung der Zeilen*/
    
        for (zeile = 0; zeile < 3; zeile++)
        {                
            for ( spalte = 0; spalte < 3; spalte++)
            {
                if ( spielfeld[zeile][spalte] == spieler )
                   treffer = treffer + 1;
                else
                    break;
            }
    
            if ( treffer== 3 )
               return 1;
            else
                treffer = 0;
        }
    
        /*Überprüfung der Spalten*/
    
        for (spalte = 0; spalte < 3; spalte++)
        {                
            for ( zeile = 0; zeile < 3; zeile++)
            {
                if ( spielfeld[zeile][spalte] == spieler )
                   treffer = treffer + 1;
                else
                    break;
            }
    
            if ( treffer == 3 )
               return 1;
            else
                treffer = 0;
        }
    
        /*Überprüfung der Diagonalen links oben -> rechts unten*/
    
        for (zeile = 0; zeile < 3; zeile++)
        {
            spalte = zeile;
    
            if ( spielfeld[zeile][spalte] == spieler )
               treffer = treffer + 1;
            else
                break;           
        }
    
        if ( treffer == 3 )
           return 1;
        else
           treffer = 0;
    
        /*Überprüfung der Diagonalen links unten -> rechts oben*/    
    
        for ( spalte = 0; spalte < 3 ; spalte++)
        {
            zeile = 2 - spalte;
    
            if ( spielfeld[zeile][spalte] == spieler )
               treffer = treffer + 1;
            else
                break;
        }
    
        if ( treffer == 3 )
            return 1;
        else
            treffer = 0;         
    
        return 0;
    }
    

    Also für diejenigen, die sich den Quelltext angetan haben: Was ist eure Meinung?
    Wo kann ich was verbessern/sauberer programmieren?



  • Auf die Schnelle sieht der Code fuer mich gut aus.
    Du hast aber relativ viele magische Zahlen im Code. Wenn du mit ein paar Defines die Zeiten spezifizieren koenntest, dann haettest du auch etwas davon. Bei der Drei, die haeufig austaucht wuerde ich mich jedoch weniger stoeren, da es immernoch Tic Tac Toe ist.

    zeile = getch()-48;
    

    Ist zwar gut lesbar, ich persoenlich finde aber folgendes schoener (ist aber mein persoenlicher Geschmack):

    zeile = getch()-'0';
    
    treffer = treffer + 1;
    

    Bzw.:

    treffer++;
    

    sind vermutlich auch eher Geschmackssachen. Letzteres kann man aber schneller lesen und erfassen.



  • Danke für die Hinweise, ArneMax.

    Hab jetzt statt

    zeile = getch()-48;
    printf("%d",zeile);
    

    nur noch

    zeile = getche()-'0';
    

    Spart mir ein paar Zeilen und ist übersichtlicher.

    Auch

    treffer++;
    

    habe ich übernommen.

    Für die Zeiten hab ich folgende defines verwendet:

    #define kurz 500
    #define mittel 2000
    #define lang 5000
    

    Wenn jemandem noch was auffällt bitte posten.

    Aus Verbesserungsvorschlägen kann ich häufig großen Nutzen ziehen.



  • - bis auf 'wahl' alle Variablen in die do-Schleife ziehen (so lokal wie möglich)
    - int spielfeld[3][3] = {0}; statt Schleifen-Initialisierung
    - const bei Funktionsparameterzeigern wo möglich verwenden
    - keine integer-defines, besser enum mit Großbuchstaben-Namen enum {KURZ=500,LANG=2000...}
    - auf deutsche Umlaute bzw. extended ASCII in Strings verzichten
    - ...



  • main:

    Ich würde ein eindimensionales Array wählen statt des zweidimensionalen.
    Und zwar

    int spielfeld[10]
    

    , und es werden nur die Plätze 1 bis 9 benutzt, die 0 bleibt unbenutzt,
    Also die [1] ist links unten, die [5] in der Mitte und so, um genauer zu sein: http://www.computer-woerterbuch.de/wbuch/1274/ziffernblock2.jpg

    Das

    /*Initialisierung bzw Zurücksetzen des Spielfelds*/
    

    sollte sicherlich eine Funktion werden, hat ja schon seinen Sinn, wenn man einen sprechenden Kommentar zu einigen Zeilen Code sagen kann.

    Hauptmenu und Spielablauf sind zweierlei. Kanns das Erledigen eines Spieles auch auslagern in eine Funktion.

    int wahl;
    wahl = getch() - '0';
    case 1:
    

    Wozu? Willst mit wahl nicht rechnen! Was währe denn wahl*wahl+5*wahl-9? wahl ist ein eingelesener Tastendruck!

    int wahl;
    wahl=getch();
    case '1';
    
    if ( gewonnen == 1 )
    else if ( voll == 1 && gewonnen == 0 )
    else if ( voll == 0 && gewonnen == 0 )
    

    sieht komuscg aus, auf gewonnen==0 mußt Du da doch gar nicht mehr testen.

    switch(spieler)
                                         {
                                                case 1: spieler = 2;                 // Wenn Spieler 1 dran war, ist jetzt Spieler 2 am Zug
                                                break;
                                                case 2: spieler = 1;                 // Wenn Spieler 2 am Zug war, ist Spieler 1 wieder dran
                                                break;
                                         }
    

    Es gibt ein nettes Idiom hierfür.

    spieler=1+2-spieler;
    
    while (! (voll == 1 || gewonnen ==1) );
    

    Aha, die Info lag innen schon vor. Evtl besser, eine Endlosschleife zu starten

    for(;;)
    

    und an passenden Stellem mit break rausgehen. Und nicht break nehmen, sondern return, zu diesem Behufe die Spielfunktioin auslagern.

    switch( spielfeld[zeile][spalte] )
                      {
                           case 0: printf("-\t");       // wenn Eintrag in der Matrix 0 ist, hat kein Spieler sein Kreu/Kreis gesetzt, ein - wird abgebildet
                                   break;
    
                           case 1: printf("X\t");       // Wenn Eintrag in der Matrix 1 ist, hat Spieler 1 sein Kreuz gesetzt, ein X wird abgebildet
                                   break;
    
                           case 2: printf("O\t");       // Wenn Eintrag in der Matrix 2 ist, hat Spieler 2 sein Kreis gesetzt, ein O wird abgebildet
                                   break;                              
    
    anzeigen:
    
    printf("%c\t",spielfeld[zeile][spalte]["-XO"]);
    

    https://ideone.com/8LvylD

    spielzug:

    zeile = getch()-'\0';
    

    Ja, hier ist int gemeint im Gegensatz zu in der main.

    do{                  
                      sleep(500);          
                      printf(" Zeile: ");          //Aufforderung, Zeile anzugeben
    
                      zeile = getch()-48;          // Eingabe der gewünschten Zeile
                      printf("%d",zeile);                  
    
                      if (zeile < 1 || zeile > 3)          // Eventuelle Fehleingaben abfangen und formatierte Fehlermeldung ausgeben
                      {
                         anzeigen(spielfeld,spieler);
                         printf(" Bitte nur 1, 2 oder 3 eingeben!"); // Fehlermeldung erscheint für 1,5 Sekunden
                         sleep(1500);
                         anzeigen(spielfeld,spieler);
                      }
    
                  } while ( !(zeile >= 1 && zeile <= 3) );          // Schleife läuft solange, bis Eingabe korrekt
    
                  do{                      
                      sleep(500);
                      printf("\tSpalte: ");          // Aufforderung, Spalte anzugeben
    
                      spalte = getch()-48;           // Eingabe der gewünschten Spalte
                      printf("%d",spalte);
    
                      if (spalte < 1 || spalte > 3)     // Eventuelle Fehleingaben abfangen und formatierte Fehlermeldung ausgeben
                      {
                         anzeigen(spielfeld,spieler);
                         printf(" Bitte nur 1, 2 oder 3 eingeben!");  // Fehlermeldung erscheint für 1,5 Sekunden
                         sleep(2000);
                         anzeigen(spielfeld,spieler);
                         printf(" Zeile: ");
                         printf("%d",zeile);
    
                      }
                  } while ( !(spalte >= 1 && spalte <= 3) );        // Schleife läuft solange, bis Eingabe korrekt
    

    Soooo viel Code genau doppelt! Das sollte mehrfach ausgelagert werden.

    int test_voll(int spielfeld[3][3])
    {
           int zeile, spalte;
    
           for (zeile = 0; zeile < 3; zeile++)
           {
               for (spalte = 0; spalte < 3; spalte++)
               {
                   if ( spielfeld[zeile][spalte] == 0 )
                      return 0;  
               }
           }            
        return 1;
    }
    

    Gut. Wobei bei meinem eindimensionalen Array keine verschachtelten der Schleifen nötig wären.

    int test_gewonnen(int spielfeld[3][3], int spieler)
    {
        int zeile, spalte;
        int treffer = 0;
    
        /*Überprüfung der Zeilen*/
    
        for (zeile = 0; zeile < 3; zeile++)
        {                
            for ( spalte = 0; spalte < 3; spalte++)
            {
                if ( spielfeld[zeile][spalte] == spieler )
                   treffer = treffer + 1;
                else
                    break;
            }
    
            if ( treffer== 3 )
               return 1;
            else
                treffer = 0;
        }
    
        /*Überprüfung der Spalten*/
    
        for (spalte = 0; spalte < 3; spalte++)
        {                
            for ( zeile = 0; zeile < 3; zeile++)
            {
                if ( spielfeld[zeile][spalte] == spieler )
                   treffer = treffer + 1;
                else
                    break;
            }
    
            if ( treffer == 3 )
               return 1;
            else
                treffer = 0;
        }
    
        /*Überprüfung der Diagonalen links oben -> rechts unten*/
    
        for (zeile = 0; zeile < 3; zeile++)
        {
            spalte = zeile;
    
            if ( spielfeld[zeile][spalte] == spieler )
               treffer = treffer + 1;
            else
                break;          
        }
    
        if ( treffer == 3 )
           return 1;
        else
           treffer = 0;
    
        /*Überprüfung der Diagonalen links unten -> rechts oben*/    
    
        for ( spalte = 0; spalte < 3 ; spalte++)
        {
            zeile = 2 - spalte;
    
            if ( spielfeld[zeile][spalte] == spieler )
               treffer = treffer + 1;
            else
                break;
        }
    
        if ( treffer == 3 )
            return 1;
        else
            treffer = 0;        
    
        return 0;
    }
    

    Sehr viel ähnlicher Code! Aber es ist nicht einfach, eine Ähnlichkeit auszunutzen.
    Ich würde wohl anstreben, eine Funktion zu bekommen, die mit Startpunkt und Richtung arbeitet, vielleicht

    int test3(int spielfeld[3][3],int startx,int starty,int richtungx,int richtungy);
    
    int test_gewonnen(int spielfeld[3][3], int spieler){
       /*Überprüfung der Zeilen*/
       for (zeile = 0; zeile < 3; zeile++)
          if(test3(spielfeld,zeile,0,0,1))
             return 1;
       /*Überprüfung der Zeilen*/
       for (spalte = 0; spalte < 3; spalte++)
          if(test3(spielfeld,0,spalte,1,0))
             return 1;
       /*Überprüfung der Diagonalen links oben -> rechts unten*/
       if(test3(spielfeld,0,2,1,-1))
          return 1;
       /*Überprüfung der Diagonalen links unten -> rechts oben*/
       if(test3(spielfeld,0,0,1,1))
          return 1;
       return 0;
    }
    

    Geht auch eindimenional, nur immer http://www.computer-woerterbuch.de/wbuch/1274/ziffernblock2.jpg anschauen.

    //Irgendwie fühlen sich Schleifen komisch an, wenn sie genau dreimal durchlaufen. 
    int test_gewonnen(int spielfeld[10], int spieler){
       /*Überprüfung der Zeilen*/
       if(test3(spielfeld,1,1)) return 1;
       if(test3(spielfeld,4,1)) return 1;
       if(test3(spielfeld,7,1)) return 1;
       /*Überprüfung der Spalten*/
       if(test3(spielfeld,1,3)) return 1;
       if(test3(spielfeld,2,3)) return 1;
       if(test3(spielfeld,3,3)) return 1;
       /*Überprüfung der Diagonalen links oben -> rechts unten*/
       if(test3(spielfeld,7,-2)) return 1;
       /*Überprüfung der Diagonalen links unten -> rechts oben*/
       if(test3(spielfeld,1,4)) return 1;
       return 0;
    }
    

    oder

    //(Irgendwie fühlen sich Schleifen komisch an, wenn sie genau dreimal durchlaufen.) hoch zwei
    int test_gewonnen(int spielfeld[10], int spieler){
       /*Überprüfung der Zeilen*/
       if(test3(spielfeld,1,2,3)) return 1;
       if(test3(spielfeld,4,5,6)) return 1;
       if(test3(spielfeld,7,8,9)) return 1;
       /*Überprüfung der Spalten*/
       if(test3(spielfeld,1,4,7)) return 1;
       if(test3(spielfeld,2,5,8)) return 1;
       if(test3(spielfeld,3,6,9)) return 1;
       /*Überprüfung der Diagonalen links oben -> rechts unten*/
       if(test3(spielfeld,7,5,3)) return 1;
       /*Überprüfung der Diagonalen links unten -> rechts oben*/
       if(test3(spielfeld,1,5,9)) return 1;
       return 0;
    }
    


  • Hey vielen Dank für euere Mühe! Konnte durch die Beiträge wieder einiges neues lernen.

    volkard schrieb:

    Ich würde ein eindimensionales Array wählen statt des zweidimensionalen.

    Ist eine super Idee, vereinfacht den Code ungemein.
    Werd aber vorerst bei der Matrixschreibweise bleiben, weil mir dieses Programm später als Referenzprogramm dienen soll (für 4gewinnt).

    volkard schrieb:

    Ich würde wohl anstreben, eine Funktion zu bekommen, die mit Startpunkt und Richtung arbeitet.

    Ja, in diese Richtung sollte ich es auch versuchen. (würde mir später beim Programmieren von 4gewinnt sicherlich helfen)

    Ein Verbesserungsvorschlag bzgl. anzeigen.c hat mich doch ziemlich verwirrt:

    printf("%c\t",spielfeld[zeile][spalte]["-XO"]);
    

    Woher genau weiß die Funktion, wann welches Zeichen zu setzen ist? Ich verstehe nicht, wie printf diese ["-XO"] Klammer auswertet, finde leider auch nichts dazu.

    Auch bei einem Vorschlag von Wutz bin ich mir nicht ganz sicher:

    Wutz schrieb:

    - const bei Funktionsparameterzeigern wo möglich verwenden

    Da ich mich mit Zeigern noch nicht so gut auskenne, werd ich mich erstmal noch einlesen müssen.
    Geht es in die richtige Richtung, wenn ich mich hierfür insbesondere mit call by reference auseinandersetze?

    Ansonsten sind alle anderen Vorschläge nachvollziehbar für mich. Werd mich mal ans überarbeiten machen. Danke nochmal.



  • ser_u schrieb:

    printf("%c\t",spielfeld[zeile][spalte]["-XO"]);
    

    Woher genau weiß die Funktion, wann welches Zeichen zu setzen ist? Ich verstehe nicht, wie printf diese ["-XO"] Klammer auswertet, finde leider auch nichts dazu.

    Das ist ein fieses Ding von volkard.
    Folgendes:

    int array[5];
    array[3];
    

    Ich hoffe du weißt, dass array[3] nichts anderes bedeutet als *(array + 3).
    Und das wird auch genauso übersetzt. Deswegen kann man auch schreiben:

    3[array];
    

    Das wird zu:

    *(3 + array);
    

    Und dementsprechend geht auch:

    0["Hallo Welt"];
    

    Das ist dasselbe wie:

    "Hallo Welt"[0];
    

    Also das erste Zeichen.
    Du hast nun:

    spielfeld[zeile][spalte]["-XO"]
    // dasselbe wie
    (spielfeld[zeile][spalte])["-XO"]
    // dasselbe wie
    "-XO"[spielfeld[zeile][spalte]]
    

    Und das ist einfach das x-te Zeichen von diesem String, wobei x die Zahl ist, die in spielfeld[zeile][spalte] drin steht. Bei 0 ist das '-', bei 1 'X', bei 2 'O'; also das, was du willst.



  • Interessant, kommt einem so vor wie das Umformen eines mathematischen Terms.

    Ich sollte mich wirklich mehr mit der Theorie von Arrays/Pointern auseinandersetzen.

    Danke für die schnelle Erklärung, sehr nachvollziehbar dargestellt!


Anmelden zum Antworten