Bestimmte Zeichen in der DOS-Konsole farbig machen



  • cout << "\t\t\t 17\t\t  16\t\t   15\n";     //Beschriftung
    cout<<"\t\t\t";
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    cout << i_x_y_AFeld[7][1];      //Punkt 17
    for (i=0;i<=15;i++)
    cout<<c_WStrich;
    cout << i_x_y_AFeld[6][1];      //Punkt 16
    for (i=0;i<=15;i++)
    cout << c_WStrich;
    cout << i_x_y_AFeld[5][1];      //Punkt 15
    cout << "\n";
    

    Es geht um den obigen Quelltext. Es ist ein Teil eines Spieles (Mühle) und beispielsweise in der Zeile "cout<<i_x_y_AFeld[7][1];" wird entweder eine 0, 1, oder 2 ausgegeben. Die Null möchte ich farblich lassen wie sie normal ausgegeben wird, aber die 1 soll z. B. grün und die 2 z. B. rot ausgegeben werden.

    Ich habe schon versucht, die Farbe zu ändern. Aber so wie der Befehl "SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);" in der Zeile darüber steht, wird das komplette Spielfeld eingefärbt.

    Wie schaffe ich es, dass der Befehl nur für die Zeile darunter gilt und dass zusätzlich entsprechend 0, 1, oder 2 eine andere Farbe gewählt wird?



  • Du musst es direkt nach der farbigen Ausgabe wieder auf nicht-farbige Ausgabe (also auf die vorher eingestellte Farbe) zurückstellen.

    MfG SideWinder



  • Okay danke, das hat schon mal funktioniert.

    Aber ich weiß leider nicht, welche Zahl im Array steht (wie gesagt entweder 0, 1 oder 2). Wie kann ich eine bestimmte Farbe entsprechend einer bestimmten Zahl einstellen lassen?



  • switch(i_x_y_AFeld[7][1])
    {
        case 0: ... break;
        case 1: ... break;
        case 2: ... break;
    }
    

    Damit das nicht komplett unübersichtlich wird mach besser sowas wie eine setFarbe-Funktion (falls du schon Funktionen kennst).

    MfG SideWinder



  • Also Funktionen kenne ich bereits, auch wie man ein Array an Funktionen übergibt.

    Aber in diese Farbe-Funktion müssen ja mehrere switch-case-Anweisungen hintereinander rein (für jedes Mühle-Feld, auf dem ein Spielstein liegen kann eine).
    Nur wird bei mir bis jetzt nicht die jeweils richtige switch-case-Anweisung für das entsprechende Mühle-Feld angesprungen:

    void fn_Farbe (int i_x_y_AFeld[][4])
    {
    switch(i_x_y_AFeld[5][1])
    	{
    	case 0:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    		break;
    	case 1:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    		break;
    	case 2:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    		break;
    	}
    	switch(i_x_y_AFeld[6][1])
    	{
    	case 0:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    		break;
    	case 1:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    		break;
    	case 2:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    		break;
    	}
    	switch(i_x_y_AFeld[7][1])
    	{
    	case 0:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    		break;
    	case 1:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    		break;
    	case 2:
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    		break;
    	}
    }
    
    cout<<"\t\t\t 17\t\t  16\t\t   15\n";      //Beschriftung
    	cout<<"\t\t\t";
    	fn_Farbe(i_x_y_AFeld);
    	cout << i_x_y_AFeld[7][1];       //Punkt 17
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    	for (i=0;i<=15;i++)
    	cout << c_WStrich;
    
    	fn_Farbe(i_x_y_AFeld);
    	cout << i_x_y_AFeld[6][1];     //Punkt 16
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    	for (i=0;i<=15;i++)
    	cout << c_WStrich;
    
    	fn_Farbe(i_x_y_AFeld);
    	cout << i_x_y_AFeld[5][1];       //Punkt 15
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    	cout << "\n";
    

    Wie schaffe ich es jetzt, dass z. B. für "cout << i_x_y_AFeld[7][1];" zuvor auch genau in "switch (i_x_y_AFeld[7][1])" gesprungen wird?
    Genau das funktioniert nämlich auch bei den anderen Array-Felder noch nicht richtig.



  • Du musst diese Zahl (7,6,5) auch via Parameter übergeben. Am besten stoppst du an dieser Stelle etwas mit deinem Dame-Spiel und kümmerst dich um dein Theoriewissen im Bereich:

    - Arrays
    - Funktionen
    - Zusammenspiel dieser beiden 😉

    MfG SideWinder



  • Ich hab das Problem jetzt erstmal etwas anders gelöst. Für jedes Spielfeld habe ich eine einzige Variable mit einer jeweils anderen Zahl deklariert, die dann immer entsprechend dem Funktionsaufruf in die Funktion mitgegeben wird und das entsprechende Spielfeld mit der richtigen Farbe versieht:

    void fn_Farbe (int *ptr_i_Farbe, int i_x_y_AFeld[][4])
    {
        if(*ptr_i_Farbe==6)
    	{
    		switch(i_x_y_AFeld[6][1])
    		{
    		case 0:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
    			break;
    		case 1:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    			break;
    		case 2:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    			break;
    		}
    	}
    	if(*ptr_i_Farbe==7)
    	{
    		switch(i_x_y_AFeld[7][1])
    		{
    		case 0:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
    			break;
    		case 1:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    			break;
    		case 2:
    			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    			break;
    		}
    	}
    }
    
    cout<<"\t\t\t 17\t\t  16\t\t   15\n";      //Beschriftung
    	cout<<"\t\t\t";
    	i_Farbe=7;
    	fn_Farbe(&i_Farbe, i_x_y_AFeld);
    	cout << i_x_y_AFeld[7][1];        //Punkt 17
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
    	for (i=0;i<=15;i++)
    	cout << c_WStrich;
    	i_Farbe=6;
    	fn_Farbe(&i_Farbe, i_x_y_AFeld);
    	cout << i_x_y_AFeld[6][1];          //Punkt 16
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
    	for (i=0;i<=15;i++)
    	cout << c_WStrich;
    

    Es ist vielleicht nicht unbedingt die eleganteste Lösung, aber es funktioniert und außerdem muss das Projekt Anfang nächster Woche abgegeben werden. ^^



  • Probier mal, der Übersichtlichkeit halber, das ganze in mehrere Funktionen zu untergliedern:

    void SetColor(int color)
    {
        SetConsoleTextAttribute(..., color);
    }
    
    int GetColor()
    {
       GetConsoleTextAttributes() etc.
       // oder was es auch immer da gibt
    
       return colorWhatever;
    }
    
    void WriteValue(int value)
    {
        int oldColor = GetColor();
        int color;
    
        switch (value)
        {
        case 1:
            color = FOREGROUND_RED;
            break;
        case 2:
            color = FOREGROUND_GREEN;
            break;
        default:
            color = oldColor;
            break;
        }
    
        SetColor(color);
        cout << character;
        SetColor(oldColor);
    }
    

    Und dann schreibst du an den Stellen, wo die eigentliche Ausgabe kommt, nur noch:

    WriteValue(i_x_y_AFeld[6][1]);
    

    In dem Fall musst du SetConsoleTextAttribute im gesamten Code nur einmal aufrufen. Auch hast du das switch nur einmal drin. Und du musst auch keine Arrays an Funktionen übergeben.



  • Super Tipp, danke (dass ich da nur nicht gleich drauf gekommen bin... 😉 ). Ich hab das ganze jetzt ein wenig anders realisiert, aber wie ich finde ganz gut hinbekommen:

    void fn_Farbe (int i_Spielstein, int i_x_y_AFeld[][4], int i_x, int i_y)
    {
        switch (i_Spielstein)
        {
        case 1:
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
            break;
        case 2:
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
            break;
        default:
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
            break;
        }
    
    	cout << i_x_y_AFeld[i_x][i_y];
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
    }
    

    Der Aufruf sieht dann beispielsweise so aus:

    fn_Farbe(i_x_y_AFeld[7][1], i_x_y_AFeld, i_x=7, i_y=1);
    


  • Die ungarische Notation wird heutzutage kaum noch verwendet/aus der Mode. Tue dir selbst einen Gefallen und lasse sie Weg. Nimm stattdessen aussagekräftige eindeutige Bezeichnungen.

    Meine Meinung ist natürlich subjektiv.


Anmelden zum Antworten