Brauche Hilfe bei Bakterien Kultur (Array Aufgabe) :)



  • Kurze Frage in der Aufgabe wird verlangt ein 11x11 Feld anzulegen mit Leerzeichen und am Anfang ein Strich am Ende der Zeile. Also die Ausgabe der Matrix funktioniert einwandfrei. Das nächste ist eine Eingabe. Mit den Koordinaten die man übergibt, ist das der Mittelpunkt eines 3x3 Feldes.... Ich verstehe nicht wie ich das schaffen soll mit einer Schleife. Also in der "Theorie" ist ja klar ich will boden[posY-2][posX-2] bis boden[posY][posX] damit das 3x3 Feld dann da ist. So einzeln alle 9 Befehle aufschreiben klappt, aber wie würde ich das in einer Schleife machen? 😃

    #include<stdio.h>
    
    void eingabe (int boden[11][11]); //Prototypen
    void ausgabe (int boden[11][11]);
    
    int main (void)
    {
    	int boden[11][11], i, j, posY, posX;
    
    	for (i = 0; i < 11; i++) //Anlegen des leeren Feldes
    	{
    		for (j = 0; j < 11; j++)
    		{
    			boden[i][j] = ' ';
    		}
    	}
    	printf("\n--- Bakterienkultur ---\n");
    	printf("Wo soll sich der Mittelpunkt, der Bakterienkultur befinden? (x, y)");
    	scanf("%d, %d", &posY, &posX);
    	eingabe(boden);
    	ausgabe(boden);
    
    	return 0;
    }
    
    void ausgabe (int boden[11][11]) //Ausgabe des Feldes
    {
    	int i, j;
    	printf("\n");
    	for (i = 0; i < 11; i++)
    	{
    		printf("|");
    		for (j = 0; j < 11; j++)
    		{
    			printf("%c", boden[i][j]);
    		}
    		printf("|\n");
    	}
    }
    
    void eingabe (int boden[11][11], int posY, int posX)
    {
    	for (posY -= 2; posY < posY+3; posY++)
    	{
    		for (posX -= 2; posX < posX+3; posX)
    		{
    			boden[posY][posX] = '*';
    		}
    	}
    }
    

    Also wie kann ich die Eingabe vernünftig machen? Das Sie mir im Endeffekt das hier errechnet und printet:

    boden[posY-2][posX-2] = '*';
    boden[posY-2][posX-1] = '*';
    boden[posY-2][posX] = '*';
    boden[posY-1][posX-2] = '*';
    boden[posY-1][posX-1] = '*';
    boden[posY-1][posX] = '*';
    boden[posY][posX-2] = '*';
    boden[posY][posX-1] = '*';
    boden[posY][posX] = '*';
    


  • Du brauchst in der Schleife schon eine vernünftige Grenze.

    saschokkk schrieb:

    for (posY -= 2; posY < posY+3; posY++)
    

    Hier veränderst du posY in jedem Durchlauf. Das hat auch Auswirkungen auf das posY+3, da dies jedesmal neu berechnet wird.

    for (y = -1; y <= 1; y++)  // oder was immer du da haben willst
        {
            for (posX -= 2; posX < posX+3; posX) // auch anpassen
            {
                boden[posY+y][posX+x] = '*';
            }
        }
    

    Die Deklaration (Prototyp) und der Aufruf von eingabe passt nicht zur Definition.



  • Ups ja das habe ich noch nicht gefixt gehabt 😃 Mir ging es um die Schleife erstmal 🙂 Aber so haut das dann hin?

    Kannst du mir den "Hintergrund" erklären warum diese Schleife hinhaut wann sie wie gezählt wird



  • Die Schleifenbedingung wird vor jedem Durchlauf geprüft.
    Und posY < posY+3 ist für jedes posY wahr. (Mal abgesehen von den möglichen Bereichsüberläufen bei der realen Implementation auf einem Computer)



  • Ne ich hatte nach deiner gefragt, aber jetzt erkannt mir hat dieser Schritt gefehlt posX und posY gar nicht zuverändern sondern das von diesen zahlen zb +y aber da -2 ist bewirkt es ganz genau das was ich wollte. Weiß nicht warum ich nicht drauf gekommen bin 😃 Danke schon mal. Ich schreibe nachher noch eine Frage bezüglich dieser Aufgabe 😉



  • Sooo kann noch mal jemand über den Code rüber gucken, ich habe ein wenig kommentiert wo meine Probleme liegen 🙂 Danke schon mal im voraus! 😉

    #include<stdio.h>
    
    void eingabe (int boden[11][11], int posY, int posX); //Prototypen
    void ausgabe (int boden[11][11]);
    int bakterien_zaehlen (int boden[11][11]);
    int nachbarn_zaehlen (int boden[11][11], int posY, int posX);
    
    int main (void)
    {
    	int boden[11][11], i, j, posY, posX;
    
    	for (i = 0; i < 11; i++) //Anlegen des leeren Feldes
    	{
    		for (j = 0; j < 11; j++)
    		{
    			boden[i][j] = ' ';
    		}
    	}
    	printf("\n--- Bakterienkultur ---\n");
    	printf("Wo soll sich der Mittelpunkt, der Bakterienkultur befinden? (x, y)");
    	scanf("%d, %d", &posY, &posX);
    	eingabe(boden, posY, posX);
    	ausgabe(boden);
    	bakterien_zaehlen(boden);
    	nachbarn_zaehlen(boden, posY, posX);
    
    	return 0;
    }
    
    void ausgabe (int boden[11][11]) //Ausgabe des Feldes
    {
    	int i, j;
    	printf("\n");
    	for (i = 0; i < 11; i++)
    	{
    		printf("|");
    		for (j = 0; j < 11; j++)
    		{
    			printf("%c", boden[i][j]);
    		}
    		printf("|\n");
    	}
    }
    
    void eingabe (int boden[11][11], int posY, int posX) // Eingabe des Mittelpunkts vom Zell Haufen
    {
    	int i, j;
    
    	for (i = -2; i < 1; i++)
    	{
    		for (j = -2; j < 1; j++)
    		{
    			if ( (posY+i) < 0) posY+i = 10; // Warum funktioniert das nicht? Der Ausdruck muss ein änderbarer Value sein, steht da.
    											// Die Idee ist es wenn man an einen Randpunkt kommt mit dem MP dann sollen die anderen
    			boden[posY+i][posX+j] = '*';	// nicht im Nirvana landen sondern einfach auf der anderen Seite.
    
    		}
    	}
    }
    
    int bakterien_zaehlen (int boden[11][11]) // Zählt das gesamte Feld nach lebenden Zellen ab, lebend heißt *
    {
    	int i, j, counter = 0;
    
    	for (i = 0; i < 11; i++)
    	{
    		for (j = 0; j < 11; j++)
    		{
    			if (boden[i][j] == '*')
    				counter++;
    		}
    	}
    	printf("\n\nEs leben %d Bakterien\n\n", counter);
    	return counter;
    }
    
    int nachbarn_zaehlen (int boden[11][11], int posY, int posX) // Prüft um die jeweilige Zelle ihre Nachbarfelder ob es sich um lebende Zellen handelt
    {															 // Hier bezieht sich aber der Mittelpunkt mit ein, wie kann ich den noch loswerden? 	
    	int i, j, n_counter = 0;								 // Also kann man diese Schleife laufen lassen, aber genau einen Wert rausnehmen? Ohne zu tricksen?
    															 // Weil ich könnte ja ganz blöd gesagt counter-1 rechnen im printf Befehl, doch das wäre glaube ich nicht wirklich der Sinn
    	for (i = -2; i < 1; i++)
    	{
    		for (j = -2; j < 1; j++)
    		{
    			if (boden[posY+i][posX+j] == '*')
    				n_counter++;
    		}
    	}
    	printf("\n\nDie Zelle hat %d lebende Nachbarn\n\n", n_counter);
    	return n_counter;
    }
    


  • saschokkk schrieb:

    if ( (posY+i) < 0) posY+i = 10; // Warum funktioniert das nicht?

    Weil posY+i keine Variable ist.

    saschokkk schrieb:

    Hier bezieht sich aber der Mittelpunkt mit ein, wie kann ich den noch loswerden?

    Indem du mittels if den Mittelpunkt-Fall auslässt.



  • Über die Grenzen kannst du mit dem Modulo-Operator % gehen:

    boden[(posY+i) % 11][(posX+j) % 11] = '*';
    


  • Ich habe das mal so umgearbeitet, klappen tut es 😃 aber wäre das auch "richtig/logisch"? Also nicht dass ich irgendein Kniff verwendet habe, denn für mich klingt das sinnvoll:

    void eingabe (int boden[11][11], int posY, int posX) // Eingabe des Mittelpunkts vom Zell Haufen
    {
    	int i, j, hilf_posY, hilf_posX;
    
    	for (i = -2; i < 1; i++)
    	{
    		for (j = -2; j < 1; j++)
    		{
    			hilf_posY = posY+i;
    			hilf_posX = posX+j;
    
    			if ( (posY+i) < 0) hilf_posY = 10; 
    			if ( (posY+i) > 10) hilf_posY = 0;
    			if ( (posX+j) < 0) hilf_posX = 10;
    			if ( (posX+j) > 10) hilf_posX = 0;
    
    			boden[hilf_posY][hilf_posX] = '*';	
    		}
    	}
    }
    

    Ich habe jetzt einfach Hilfsvariablen gemacht und joa ich finde das klappt 🙂 Also es sind dann immer 9 Sternchen gerne mal überall 😃 Aber alles richtig, nur für den Fall 0,0 Als Zellmittelpunkt kommen nur noch 4 Sternchen raus, erkennt jemand den Grund? 😉

    Und hier die überarbeitete Nachbarfunktion:

    int nachbarn_zaehlen (int boden[11][11], int posY, int posX) // Prüft um die jeweilige Zelle ihre Nachbarfelder ob es sich um lebende Zellen handelt
    {															 	
    	int i, j, n_counter = 0;								 
    
    	for (i = -2; i < 1; i++)
    	{
    		for (j = -2; j < 1; j++)
    		{
    			if (boden[posY+i][posX+j] == '*') n_counter++;
    
    		}
    	}
    	if (boden[posY][posX] == '*') n_counter--;
    	printf("\n\nDie Zelle hat %d lebende Nachbarn\n\n", n_counter);
    	return n_counter;
    }
    

    Das man einfach NACH der Schleife sagt, hey für den Fall des betrachteten Punktes, wenn der lebend ist (ist er ja automatisch dank der Eingabe Funktion) wird der Zähler um eins dann abgezogen 🙂



  • saschokkk schrieb:

    ... nur für den Fall 0,0 Als Zellmittelpunkt kommen nur noch 4 Sternchen raus, erkennt jemand den Grund? 😉

    Das if ( (posY+i) < 0) hilf_posY = 10; gilt für jedes posY+i . Also auch für -1 und -2. Doch du setzt den neuen Wert immer auf 10.

    Was soll denn jetzt dein Mittelpunkt sein? Ist 0,0 überhaupt gültig?
    Beim Mittelpunkt würde ich die Schleife von -1 bis +1 laufen lassen und nicht von -2 bis 0.

    Aber das ist deine Definition. Aber dann halte dich daran.



  • Warum denn von -1 bis +1? Ich meine wenn ich jetzt per Eingabe in eine 11x11 Feld meinen Mittelpunkt setze mit den Koordinaten 7,7 dann soll doch mein Mittelpunkt in echt bei 6,6 landen, weil doch Arrays mit dem Index 0 anfangen und nur bis 10 gehen. Deswegen soll wenn ein Sternchen sozusagen unter 0 ist gleich auf die andere Seite des Feldes kommen, was doch 10 wäre oder was sehe ich grade falsch? 🙂 Deswegen -2 bis 0, denn -1,-1 ist sozusagen der Mittepunkt und dann die anderen drum herum.

    Bitte korregiere mich wenn ich hier Müll erzähle 🙂 Nur in einer ähnlichen Aufgabe in der Vorlesung hatten wir das genau so gemacht. Dort war es mit nur einer Koordinate und dann gabs ein array[posY][posX-1] und die wurden eingelesen. Weil wenn ich zwei einlese, lande ich doch auf dem 3ten Platz.



  • Trenne die Angaben für den Nutzer von denen im Programm.

    Wenn der Nutzer ein Feld von 1 bis 11 sehen soll, dann ist das OK.
    Aber dann rechne die Werte vor der weiteren Benutzung um.

    0123456789A
    0
    1 ***
    2 *x*
    3 ***
    4
    

    Der Mittelpunkt ist bei 2,2. Was gibt der Nutzer ein?

    Und wenn als Koordinate -1 raus kommt, dann landest du bei 10.
    Bei -2 landest du bei 9. Oder kurz: bei 11+posY+i



  • Perfekt Danke! 🙂 Das ist es gewesen 😃


Anmelden zum Antworten