15*15 Spielfeld mit Arrays. Einzelne Rauslöschen und nachrücken



  • Hi,
    bin gerade dabei ein kleines Spiel zu Schreiben. Es soll ein 15*15 Spielfeld sein mit einem Zeichen mit einer random farbe. Mit dem Cursor soll man auswählen können und dann das zeichen löschen. Ich habe shcon das Spielfeld und auch den Cursor. Das Spielfeld habe ich mit einem Array erstellt (iar[15][15])

    Meine Frage an euch lautet jetzt:

    Wie kann ich ein Zeichen löschen?
    Wie "rückt" das zeichen drüber nach, bzw von recht?

    Über Hilfe wäre ich sehr dankbar, versuche es shcon seit paar Tagen, komme aber nicht auf die Lösung.

    Mit freundlichen Grüßen
    printf(Hallo Welt)



  • Das geht mit Standardmitteln nicht, willste nach WinAPI, Linux oder DOS verschoben werden? 😃



  • Du mußt von der Startposition aus bis zum Rand des Arrays durchgehen und jedes Element um ein Feld nach vorne schieben (anschließend die Randposition mit einem "nicht belegt"-Marker kennzeichnen).



  • ich weiß leider nicht genau was sie meinen. Was vielleicht nützlich für sie wäre. Ich arbeite mit Dev++ und auf Windows.

    MFG



  • Hast du dich schon einmal intensiver mit Arrays un Schleifen beschäftigt? Wenn nicht, wäre das eine gute Gelegenheit.

    Hier nur ein Ansatz, wie man das Problem im eindimensionalen Fall lösen könnte:

    int array[SIZE];
    //mit Werten füllen
    
    int pos = user_selection();
    for( ; pos+1<SIZE; ++pos)
      array[pos] = array[pos+1]; // Felder zusammenrücken
    array[SIZE-1] = -1;          // Randfeld als "frei" markieren
    


  • printf(Hallo Welt) schrieb:

    Wie kann ich ein Zeichen löschen?
    Wie "rückt" das zeichen drüber nach, bzw von recht?

    Ein Zeichen kannst du löschen, indem du z.B. ein Leerzeichen reinschreibst(oder ein Zeichen, das dem Hintergrund bzw. einem leeren Feldelement entspricht).
    Ein Nachrücken erreichst du durch Umkopieren der Array-Inhalte.

    Grüße,
    B.B.



  • printf(Hallo Welt) schrieb:

    Wie kann ich ein Zeichen löschen?

    Meinst du in der Konsole oder im Array?



  • printf(Hallo Welt) schrieb:

    Ich arbeite ... auf Windows.

    Unter Windows könntest Du das zum Beispiel so machen:

    #include <windows.h>
    
    SetCursorVisible(BOOL v)
    {
    	CONSOLE_CURSOR_INFO ci;
    
    	GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
    
    	ci.bVisible = v;
    
    	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ci);
    }
    
    DruckSimpleText(int x, int y, char const *text)
    {
    	COORD target;
    	DWORD written;
    
    	target.X = x;
    	target.Y = y;
    
    	WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), text,
    											strlen(text),
    											target, &written);
    }
    
    ClearScreen(void)
    {
    	CONSOLE_SCREEN_BUFFER_INFO csbi;
    	COORD target;
    	DWORD written;
    
    	target.X = 0;
    	target.Y = 0;
    
    	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    	FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ',
    											csbi.dwSize.X * csbi.dwSize.Y,
    											target, &written);
    }
    
    SetWindowExt(int x, int y)
    {
    	SMALL_RECT sr_window;
    	COORD      extension;
    
    	sr_window.Left    = 0;
    	sr_window.Top     = 0;
    	sr_window.Right   = x - 1;
    	sr_window.Bottom  = y - 1;
    
    	extension.X = x;
    	extension.Y = y;
    
    	SetConsoleWindowInfo (GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &sr_window);
    	SetConsoleScreenBufferSize (GetStdHandle(STD_OUTPUT_HANDLE), extension);
    }
    
    int main()
    {
    	int i;
    
    	SetWindowExt(20, 20);
    	ClearScreen();
    	SetCursorVisible(FALSE);
    
    	DruckSimpleText(5, 5, "Hello World");
    
    	for(i = 0; i < 5; ++i)
    	{
    		Sleep(1000);
    		DruckSimpleText(11, 5, " ");
    		Sleep(1000);
    		DruckSimpleText(11, 5, "W");
    	}
    
    	SetCursorVisible(TRUE);
    
    }
    


  • Danke für die schnellen Antworten.
    Mein Problem ist jedoch, das ich euere Vorschläge nicht bei mir einbinden kann. Verstehe das Prinzip nicht.
    Vlt. könnt ihr mir zeigen wie ihr ein spielfeld erstellen würdet und dann mit den Pfeiltasten auswäheln und löschen könnt. Vlt. liegts einfach daran, dass ich das Spielfeld und den Cursor anders programmiert habe, wie ihr.

    Ich bedanke mich recht herzlich



  • wie wärs wenn du dein spielfeld mit cursor zeigst, denn die wahrscheinlichkeit ist groß das ganz andere ansätze kommen



  • Hier guckst du ein Feld mit Cursor erstellt mit Standardmitteln.
    Wie man Zeichen löschen oder verschieben kann wurde ja schon mehrfach erwähnt.
    Wenn du betriebssystem-spezifische Funktionen benutzt dann hast du mehr Möglichkeiten und das Ganze wird weniger hässlich. 😃

    Das Zeichen, das gerade den Cursor hat, wird groß dargestellt:

    #include <stdio.h>
    
    // Navigation durchs Feld mit den Tasten 2, 4, 6, 8.
    
    #define RECHTS 6
    #define LINKS 4
    #define OBEN 8
    #define UNTEN 2
    
    #define X 4
    #define Y 4
    
    char spielfeld[4][4]; 
    
    int xcurr, ycurr;
    
    void abwaehlen()
    {
    	spielfeld[ycurr][xcurr] += 32 ;
    }
    
    void auswaehlen()
    {
    	spielfeld[ycurr][xcurr] -= 32;
    }
    
    int bewege_cursor( int richtung )
    {
    	int xnew = -1, ynew = -1;
    	switch (richtung)
    	{
    		case RECHTS:
    			if( xcurr + 1 < X )
    				xnew = xcurr+1;
    		break;
    
    		case LINKS:
    			if( xcurr -1 > -1 )
    				xnew = xcurr-1;
    		break;
    
    		case OBEN:
    			if ( ycurr -1 > -1 )
    				ynew = ycurr -1;
    		break;
    
    		case UNTEN:
    			if ( ycurr + 1 < Y )
    				ynew = ycurr + 1;
    		break;
    	}
    
    	if ( xnew != -1 || ynew != -1 )
    	{
    		abwaehlen();
    		if ( xnew != -1 )
    			xcurr = xnew;
    		else 
    		   ycurr = ynew;
    		auswaehlen();
    		return 1; 
    	}
    	return 0;
    }
    
    void spielfeld_initialisieren( char c )
    {
    	int x, y;
    	for ( x=0; x<X; x++ )
    		for ( y=0; y<Y; y++ )
    			spielfeld[x][y] = c;
    
    	spielfeld[xcurr][ycurr] = c-32; // cursor auf zeichen 1 in zeile 1
    
    }
    
    void zeig_spielfeld()
    {
    	int x, y;
    	for ( x=0; x<X; x++ )
    	{
    		for ( y=0; y<Y; y++ )
    			putchar(spielfeld[x][y]);
    		putchar('\n');
        }
    }
    
    int main()
    {  
    	spielfeld_initialisieren('x');
    	zeig_spielfeld();
    	while(1)
    	{
    		int c = getchar()-48;
    		if( bewege_cursor(c) )
    			zeig_spielfeld();
    	}
    
    	return 0;
    }
    


  • Hi,
    danke für die Antworten. Leider kann ich mir euren Antworten nichts anfangen.
    Deshalb poste ich unten meinen bisherigen code. Ich hoffe ihr könnt mir helfen. Verbesserungsvorschläge sind erwünscht.
    Also das Problem ist wers schon vergessen hat, dass ich mit dem Cursor auswählen möchte und beim drücken von 'f' sollen die gleichen Farben die Angrenzen gelöscht werden und die oberen und seitlichen sollen Nachrücken.

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    #include <winuser.h> 
    #include <stdlib.h>
    using namespace std;
    
    int main(int argc, char *argv[])
    {   
        int iar[15][15];
        int ix,iy, ianzahl,iwert, iwelch,iwelch1,ipunkte, ineuwert;
        char c1;
    
        system("cls");
        HANDLE textfarbe;
        HANDLE hConsole;
        hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
        printf("Anzahl:\t");
        scanf("%i",&ianzahl);
    
        system("cls");
        srand(time(NULL));//Zufallsfarbe, beim Start  
    
        //Erstellung des Spielfeldes
        for(ix=0; ix<15; ix++)
        {
                  for(iy=0; iy<15; iy++)
    
                  {         
                            iar[ix][iy]=rand()%ianzahl+1;
                            SetConsoleTextAttribute(hConsole, iar[ix][iy]);
                            printf("#");
                  }         
                  printf("\n");    
        }
    
        printf("\n\n\n");
        printf("Aktuelle Punktzahl: %i\n",ipunkte);
        printf("Zum Speichern P druecken\n");       
        //Cursor Position
        COORD pos;
    
        unsigned int ipos;
    
        pos.X = 0; // x-Pos setzen
    
        pos.Y = 0; // y-Pos setzen
    
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
    
        SetConsoleTextAttribute(textfarbe, 7);
    
        ipos = getch();
    
        do
    
        {
    
        ipos = getch();   
    
        switch(ipos)
        {
                    case 'w':
                             if(pos.Y>=1)
                             {
                             pos.X = pos.X; // x-Position
                             pos.Y = pos.Y-1; // y-Position 
                             SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
                             }
                             else
                             {
                                 1;
                             }
                             break;
                             ipos=getch();
    
                    case 'a':
                             if(pos.X>=1)
                             {
                             pos.X = pos.X-1; // x-Position
                             pos.Y = pos.Y; // y-Position 
                             SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
                             }
                             else
                             {
                                 1;
                             }
                             break;
                    case 's':
                             if(pos.Y<=13)
                             {
                             pos.X = pos.X; // x-Position
                             pos.Y = pos.Y+1; // y-Position 
                             SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
                             }
                             else
                             {
                                 1;
                             }
                             break;
                    case 'd':
                             if(pos.X<=13)
                             {
                             pos.X = pos.X+1; // x-Position
                             pos.Y = pos.Y; // y-Position 
                             SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
                             }     
                             else
                             {
                                 1;
                             }    
                             break;
                    case'f':
    
        }   
    
        }while(true);
    
    }
    

    Vielen Dank



  • Verschiebe dieses bitte endlich mal jemand nach "DOS und Win32-Konsole".



  • printf(Hallo Welt) schrieb:

    Deshalb poste ich unten meinen bisherigen code.

    Soll das nun C werden (#include <stdlib.h>) oder C++ (#include <cstdlib>)?

    Und: Deinen Code kann ich nicht kompilieren, weder als C, noch als C++ - Code.
    Wenn Du Dich schon so auf Windows festlegst, solltest Du in diesem speziellen Fall darüber nachdenken, ob Du für die Ausgabe wirklich printf nehmen willst, oder nicht doch lieber die von mir weiter oben gepostete Funktion DruckSimpleText(int x, int y, char const *text), zumindest solange Du das Spielfeld manipulierst, sie übernimmt für Dich gleich die Positionierung an die richtige Stelle. Eine windowskonforme Funktion für system("cls") hatte ich Dir auch schon geliefert.

    So auf den ersten Blick sieht Deine Idee ja halbwegs vernünftig aus, Du willst die Tasten w a s d auswerten, und abhängig davon den Cursor verschieben ... wie gesagt, leider kann ich den Code nicht übersetzen, deswegen kann ich auch nicht viel mehr dazu sagen ...
    Edit: ... außer vielleicht noch, dass es natürlich Blödsinn ist, sich erst das Konsolenhandle prophylaktisch zu besorgen

    HANDLE hConsole;
        hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    

    und dann in der Folge bei Bedarf doch jedes Mal wieder
    [cpp]SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); [/cpp]
    aufzurufen ... aber wie gesagt, stell hier einen funktionierenden Code ein, dann ist die Chance größer, dass sich das jemand mal genauer ansieht.



  • Hi,
    bei mir läuft das Programm. Sonst könnt ichs ja ned testen.
    Eigentlich wollte ich es nur mit C programmieren, aber dies habe ich nicht geschafft, deshalb ist das so ein gemisch.
    Wie würdest du das programm erstellen?

    Danke im vorraus



  • Bei mir Läuft das erst nach folgenden Änderungen:

    #include <windows.h>
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    // using namespace std; // brauch man hier nicht
    
    int main(int argc, char *argv[])
    ...
    
    ...
    //                case'f': // entweder ergänzen oder auskommentieren
    

    Da man die C++ Header nicht braucht, weg damit.

    Du fragst aber noch eine Taste P ab?
    Die Farben dunkelblau auf schwarzem Hintergrund 😃

    MfG f.-th.



  • Ja die Taste P soll später zum speichern dienen, das funktioniert aber noch nicht. Habt ihr ideen zum Rauslöschen und nachrücken?

    MFG



  • Hast du denn schon alle Lösungsansätze, die dir hier empfohlen wurden getestet 😕

    Versuchen wir das noch mal - ein Lösungsansatz:
    Du siehst in der unteren Zeile nach ob alle Felder belegt sind.
    Wenn nicht, gehe in der Spalte nach oben bis du etwas findest - schreibe die Info des gefundenen Feldes nach unten auf das nicht belegte und schreibe wo das gefundene Feld war ein Leerfeld.
    So arbeitest du dich Zeile für Zeile nach oben.

    Bist du fertig schreibst du das ganze Array auf den Bildschirm.

    MfG f.-th.



  • Danke für den Lösungsvorschlag!! Diese Idee habe ich auch gehabt. Aber ich kann diese nicht Ausführen. Wie vergleiche ich die Zeichen bzw die Farbe? Mit einem normalen If geht das nicht. Und wie änder ich dann die Farbe bzw. machen ein Leerzeichen rein?

    Vielen Dank



  • Wieso geht das denn nicht mit einem if? Es sollte hoffentich klar sein, daß du nicht direkt mit den gemalten Farben vergleichst, sondern mit einem Array, wo die Werte untergebracht sind.


Anmelden zum Antworten