Frage zu Schachfeld / Spiel



  • Hallo,
    folgende aufgabe:
    Aufgabe 3 (*)
    Ein Schachbrett hat 8x8 Felder. Eine Dame kann beim Schach alle Felder erreichen, die auf der gleichen
    waagerechten, senkrechten oder diagonalen Linie stehen (siehe dazu auch die Abbildung unter
    http://de.wikipedia.org/wiki/Schach#Dame).
    Schreiben Sie ein Programm, das zunächst die Position einer Dame auf dem Schachbrett einliest. Ob
    sie dabei Array-freundliche Zahlenkoordinaten wie (0,5) verwenden oder „echte“ Schachkoordinaten
    wie (a6), ist Ihnen überlassen.
    Legen Sie nun in ein zweidimensionales Array an, das in geeigneter Weise drei Arten von Feldern
    unterscheidet: (1) das Feld, auf dem die Dame selbst steht, (2) Felder, die von der Dame erreicht
    werden können, und (3) Felder, die von der Dame nicht erreicht werden können.
    Geben Sie schließlich ein Bild des Schachbretts am Bildschirm aus. Wählen Sie dabei eine Darstellung,
    die einfach, aber übersichtlich ist (z.B. ein ‘X‘ für jedes erreichbare und ein ‘-‘ für jedes unerreichbare
    Feld, sowie ein ‘D‘ für die Dame selbst).

    Folgendes habe ich bis jetzt:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int schachfeld[8][8]={0};
        int i, j, spalte;
        char zeile, dame = 'D';
    
        for(i=0;i<8;i++)
        {
                            for(j=0;j<8;j++)
                            {
                            schachfeld[i][j];
                            }
        }
    
        printf("Bitte geben Sie die Position der Dame ein. Zunaechst die Zeile a-h: ");
        scanf("%c", &zeile);
    
        switch(zeile){
    
        case 'a': schachfeld[0][0];break;
        case 'b': schachfeld[1][0];break;
        case 'c': schachfeld[2][0];break;
        case 'd': schachfeld[3][0];break;
        case 'e': schachfeld[4][0];break;
        case 'f': schachfeld[5][0];break;
        case 'g': schachfeld[6][0];break;
        case 'h': schachfeld[7][0];break;
        }
    
        printf("Nun die Spalte 1-8: ");
        scanf("%d", &spalte);
    
        switch(spalte){
    
        case 1: schachfeld[zeile][0];break;
        case 2: schachfeld[zeile][1];break;
        case 3: schachfeld[zeile][2];break;
        case 4: schachfeld[zeile][3];break;
        case 5: schachfeld[zeile][4];break;
        case 6: schachfeld[zeile][5];break;
        case 7: schachfeld[zeile][6];break;
        case 8: schachfeld[zeile][7];break;
        }
    
        printf("Die Dame steht auf: %c%d\n", zeile, spalte);
    
        schachfeld[zeile][spalte-1] = dame;
    
        for(i=0;i<8;i++)
        {
                            for(j=0;j<8;j++)
                            {
                            schachfeld[i][j];
                                    if (schachfeld[zeile][spalte-1]=dame) printf("%c", schachfeld[i][j]);
                                    else printf("0");
                            }
        printf("\n");
        }
    
        return 0;
    }
    

    Das geht irgendwie nicht. Frage, wie bekomme ich zunächst mal die ANzeige hin mit dem "D" für die Dame auf dem Feld.



  • Du musst den ASCII Code der Eingabe in den zugehörigen Index umrechnen.
    Der Code für das kleine a ist z.B. 97, dein Array geht aber nur von Index 0 bis 8.
    Der andere Index muss ebenfalls umgerechnet werden, da du ja in der Auswahl 1-8 angibst. Wenn der Index umgerechnet ist, speicherst du das D an der entsprechenden Position im Array und gibst das Array in der Konsole aus.



  • Der Code ist egal, das geht auch besser:

    #include <ctype.h>  /* wegen toupper */
    int spalte, zeile;
    char zeichen;
    
    scanf(" %c", &zeichen);
    zeile = toupper(zeichen) -'A';
    

    Was immer du bei den case machen wolltest, es hat keine Auswirkung auf das Programm.
    Ob du nun schachfeld[0][0]; oder j; oder 4; schreibst, es macht: nichts

    Du solltest auch die spalte direkt nach der Eingabe umrechnen (also -1) und natürlich noch eine Bereichsüberprüfung machen.



  • DirkB schrieb:

    Der Code ist egal, das geht auch besser:

    Ja, der Code ist egal, wenn einem egal ist, was die Zeile

    DirkB schrieb:

    zeile = toupper(zeichen) -'A';
    

    bedeutet.
    Zum Nachvollziehen muss man jedoch wissen, dass Zeichen kodiert sind.

    DirkB schrieb:

    Du solltest auch die spalte direkt nach der Eingabe umrechnen (also -1)...

    Warum?



  • vfbf4n1893 schrieb:

    Das geht irgendwie nicht. Frage, wie bekomme ich zunächst mal die ANzeige hin mit dem "D" für die Dame auf dem Feld.

    Mach mal so (Für die Klugscheißer: Ich habe noch genug Hausaufgabe für den Abend übrig gelassen):

    #include <stdio.h>
    #include <stdlib.h>
    
    int main ( void )
    {
        // Eingabe
    
        char Dame[] = "d6";
        printf("Bitte geben Sie die Position der Dame ein (z.B. d6): ");
        scanf("%2s", Dame);
        int xx = Dame[0] - 'a';
        int yy = Dame[1] - '1';
    
        // Verarbeitung
    
        char S[8][8];
    
        for (int x=0; x<8; ++x)
        {
            for (int y=0; y<8; ++y)
            {
                if ((x == xx) && (y == yy)) S[x][y] = 'D';      // Dame
                else S[x][y] = '-';                             // nicht erreichbar
            }
        }
    
        // Ausgabe
    
        puts ("");
        for (int y=7; y>=0; --y)
        {
            printf ("%d | ",y+1);
            for (int x=0; x<8; ++x)
            {
                printf ("%c ",S[x][y]);
            }
            puts ("");
        }
        puts ("    ----------------");
        puts ("    a b c d e f g h");
    
        return 0;
    

    Der Code ist C99. Wenn Du Fehlermeldungen bekommst, dann kompiliere ihn als C++ (MSVC) oder gib dem Compiler den entsprechenden Schalter mit auf den Weg (GCC: -std=gnu99).

    viele grüße
    ralph



  • rkhb schrieb:

    Mach mal so (Für die Klugscheißer: Ich habe noch genug Hausaufgabe für den Abend übrig gelassen):

    ah, auch noch pampig werden der herr. mach mal weiter so, dann kannst du deine
    hausaufgaben bald ganz allein lösen 😃

    rkhb schrieb:

    for (int x=0; x<8; ++x)
        {
            for (int y=0; y<8; ++y)
            {
                if ((x == xx) && (y == yy)) S[x][y] = 'D';      // Dame
                else S[x][y] = '-';                             // nicht erreichbar
            }
        }
    

    die schleifen sind stuss. S[x][y] = 'D'; sollte das gleiche tun und
    else S[x][y] = '-'; ist auch stuss.



  • zeh proviech schrieb:

    ah, auch noch pampig werden der herr. mach mal weiter so, dann kannst du deine
    hausaufgaben bald ganz allein lösen 😃

    Häh? Ich habe diese Hausaufgabe ganz allein und vollständig gelöst, aber es war nicht meine Hausaufgabe.

    die schleifen sind stuss. S[x][y] = 'D'; sollte das gleiche tun und
    else S[x][y] = '-'; ist auch stuss.

    Weißt Du was: Du versuchst die Aufgabe zu lösen. Dann versuchst Du, soviel davon übrig zu lassen, dass die Frage des OP beantwortet wird. Oder kurz: Du versuchst ein lauffähiges Grundgerüst zu entwickeln. Zu guter Letzt eliminierst Du alle Gossenausdrücke wie "Stuss", "Quatsch" und dergleichen aus Deinem Wortschatz. Und dann reden wir weiter.

    viele grüße
    ralph



  • Big Brother the genuine schrieb:

    DirkB schrieb:

    Du solltest auch die spalte direkt nach der Eingabe umrechnen (also -1)...

    Warum?

    Damit die Indizes gleich behandelt werden. 😉
    zeile geht sonst von 0 bis 7.
    spalte dagegen von 1 bis 8.



  • #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int schachfeld[8][8]={0};
        int i, j, spalte, zeile, a;
        char dame = 'D';
    
        for(i=0;i<8;i++)
                            {
                            for(j=0;j<8;j++)
                            {
                            schachfeld[i][j];
                            }
                            }
    
        printf("Bitte geben Sie die Position der Dame ein. Zunaechst die Zeile 1-8: ");
        scanf("%d", &zeile);
    
        printf("Nun die Spalte 1-8: ");
        scanf("%d", &spalte);
        printf("Die Dame steht auf: Zeile: %d Spalte: %d\n", zeile, spalte);
    
       schachfeld[zeile-1][spalte-1] = 'D';
    
        ;
        for(i=0;i<8;i++)
        {
                            for(j=0;j<8;j++)
                            {
                            if (schachfeld[i][j] == schachfeld[zeile-1][spalte-1]) printf(" %c", dame);
                            else if (schachfeld[i] == schachfeld[zeile-1]) printf(" X");
                            else if (schachfeld[j] == schachfeld[spalte-1]) printf(" X");
    
                            else printf(" %d", schachfeld[i][j]);
                            }
        printf("\n");
        }
    
        return 0;
    }
    

    also ich bin nun so weit. es zeigt mir nun die Dame mit "D" auf dem Spielfeld an. Außerdem habe ich alle senkrechten und waagrechtenerreichbaren Felder für die Dame hinbekommen.
    Doch leider bekomme ich auf keine gescheite Formel, wie ich auf die diaagonalen Felder komme, wo die Dame erreichen kann. Wie bekomme ich das hin??? Habt ihr das Tipps für eine gescheite Formel?



  • Zeile 14 macht nichts. Gar nichts. Keine Auswirkung.

    Zeile 33 und 34 machen bestimmt nicht das, was du erwartest.

    schachfeld ist ein 2D-Array. Was soll denn dann schachfeld[zeile-1] mit nur einem Index sein?

    Zeile 32 macht auch etwas anderes.
    Du schaust da nach ob an der Stelle schachfeld[i][j] ein 'D' ist.
    Das hast du ja so in Zeile 25 reingeschrieben.

    Wenn du schon eine Variable für die Dame hast, dann nutze die auch. (Zeile 25)

    Schreib die eine Funktion, die einfach dein Schachfeld ausgibt. Mehr nicht.

    Füllen kannst du es woanders mit den 'X' und 'D'



  • vfbf4n1893 schrieb:

    Doch leider bekomme ich auf keine gescheite Formel, wie ich auf die diaagonalen Felder komme, wo die Dame erreichen kann. Wie bekomme ich das hin??? Habt ihr das Tipps für eine gescheite Formel?

    Man kann die Diagonalen des Schachbretts als Geraden mit der Steigung 1 und -1 betrachten. Durch das Damen-Feld können zwei solche Geraden verlaufen, deren allgemeine Geradengleichung so aussieht:
    y = m*x + b
    Mach doch erstmal deinen Code soweit klar mit einer Ausgabe etc. Z.B. so:

    #include <stdio.h>
    
    // Anzahl der Felder einer Spalte/Zeile.
    // Je nach Geschmack auch mit enum machbar.
    #define S 8
    #define Z 8
    // dito
    #define LE 218 // linke Ecke oben
    #define RE 191 // rechte Ecke oben
    #define LU 192 // linke Ecke unten
    #define RU 217 // rechte Ecke unten
    
    // Das Feld ließe sich auch als char feld [feldgroesse_x] schreiben und mit einem puts auf einmal ausgeben.
    void anzeige_feld ( char feld [ Z ] [ S ] )
    { 
    	int s, z;
    	puts ("    a b c d e f g h");
    	printf ( "  %c-----------------%c\n", LE, RE );
    	for ( z = Z-1; z >= 0; z-- ) {
    		printf ( "%d | ", z + 1 );
    		for ( s = 0; s < S; s++ ) {
    			printf ( "%c ", feld [ z ] [ s ] );
    		}
    		printf ( "| %d", z + 1 );
    		puts ("");
    	}
    	printf ( "  %c-----------------%c\n", LU, RU );
    	puts ("    a b c d e f g h\n");
    }
    
    void markiere_spielbereich_dame ( char feld [ Z ] [ S ], int z_dame, int s_dame  )
    {
    	int s, z;
    	// Senkrechter und waagerechter Spielbereich.
    	for ( z = 0; z < Z; z++ ) {
    		for ( s = 0; s < S; s++ ) {
    			if ( s == s_dame && z == z_dame  )
    				continue; // Überschreiben der Dame vermeiden.
    			if (( s == s_dame || z == z_dame )) // && ( s != s_dame || z != z_dame ) == !( s == s_dame && z == z_dame )
    				feld [ z ] [ s ] = 'X';
    		}
    	}
    	// Die Diagonalen des Spielfeldes sind Geraden mit der Steigung m = 1 und m = -1.
    	// Koordinatenursprung ist hier die linke untere Ecke.
    	// Allgemeine Geradengleichung: y = m*x + b. Setze z := y und s := x ergibt: z = m*s + b
    	// Umstellen nach b: b = z - m*s. 
    	// m ist positiv und negativ -> zwei b Werte -> zwei Geradengleichungen
    	// b1 = z - s mit m = 1
    	// b2 = z + s mit m = -1
    	// Die Koordinaten der Dame erfüllen die Gleichung:
    	// z_dame = 1 * s_dame + b1 
    	// Umstellen nach b1: b1 = z_dame - s_dame
    	// Also b1 = z - s = z_dame - s_dame (1)
    	// Die Koordinaten der Dame erfüllen auch die Gleichung:
    	// z_dame = -1 * s_dame + b2 -> b2 = z_dame + s_dame
    	// also b2 = z + s = z_dame + s_dame (2)
    
    	// Zusammengefasst gilt:
    	// z - s = z_dame - s_dame (1)
    	// z + s = z_dame + s_dame (2)
    
    	// Jetzt brauchst du nur noch alle Felder zu durchlaufen und prüfen, ob Gleichungen (1) und (2)
    	// erfüllt sind und entsprechend die 'X' setzen.
    }
    
    int main ( void )
    {
    	char feld [ Z ] [ S ] = { 0 };	
    	char dame = 'D';
    	// Das Einlesen der Position der Dame und die Umrechnung und die Prüfung der Koordinaten hab ich mir gespart.
    	int s = 4; // Spalte e als Arraykoordinate
    	int z = 5; // Zeile 6 als Arraykoordinate
    
    	feld [ z ] [ s ] = dame; // Die Dame wird aufs Feld gesetzt.
    	markiere_spielbereich_dame ( feld, z, s );
    	anzeige_feld ( feld ); // selbstredend...
    	return 0;
    }
    

Log in to reply