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



  • 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.



  • ja ich habs so verglichen if(x.pos==x.pos+1).
    Also so in der Art. Wie würdet ihr es machen? Und wie ändern ich dann den inhalt?
    MFG



  • Also der Vergleich wird immer falsch sein - wenn, dann solltest du die Array-Inhalte miteinander vergleichen.



  • Du könntest die Farbe direkt mit
    ReadConsoleOutputAttribute
    aus der Konsole lesen, entsprechend das Zeichen mit
    ReadConsoleOutputCharacter
    Zum Setzen gibt es analoge Funktionen, deren Name mit Write beginnt.



  • if (iar[pos.X][pos.Y] == ..)
    ..

    Aber dein Code sieht ehrlich gesagt schrecklich aus, räum da mal auf! 🙂



  • So, habs jetzt nach dem Vorschlag von cooky451 gemacht. Teilweise funktioniert es aber es setzt dann auch auf andersfarbige ein leerzeichen. Deshalb glaub ich das er beim vergleich nicht die farbe vergleicht.
    Schaut so inetwa aus:

    if(iar[pos.X][pos.Y]==iar[pos.X+1][pos.Y])
                             {
                             printf(" ");
                             }
    if(iar[pos.X][pos.Y]==iar[pos.X-1][pos.Y])
                             {
                             printf(" ");
                             }
    

    Und wie stell ich es jetzt an dass er dann die ganze reihe kontrolliert? Sollt ich dann jeden wert abfragen?

    MFG



  • Was ist da das Problem?

    for( 1. Feld bis letztes Feld; Feld++)
    ...



  • ja er soll nur die nebeneinanderliegenden löschen, nciht alle auf dem Spielfeld.
    Ein beispiel für mein Programm wäre hilfreicher.
    Danke


Anmelden zum Antworten