[GELÖST] Anzahl von zufälligen Farben definieren



  • CStoll schrieb:

    Was genau hast du denn eigentlich vor?

    In der Konsole hast du afaik genau eine aktive Farbe - und in der werden die nächsten Ausgaben erledigt. Wenn du etwas buntest ausgeben willst, mußt du selber dafür sorgen, daß vor jeder Ausgabe die richtige Farbe eingestellt wird.

    Ich seh schon - hier besteht Klärungsbedarf.

    Das Ziel ist es, ein Spiel zu Programmieren, welches dem Spiel SameGame ähnelt.

    Folgendes habe ich schon (main.cpp, module.h & module.cpp):

    main.cpp (Hauptmenü):

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    #include "module.h"
    
    int main(int argc, char *argv[])
    {  
        int ieingabe;
        int ibeenden;
        int ilaenge,ihoehe,ifarben;
    
        printf("Hauptmenue:\n\n\n");
    
        printf("Waehlen Sie aus, was Sie tun moechten:\n\n");
        printf("1 - Neues Spiel \n");
        printf("2 - Spiel laden\n");
        printf("3 - Beenden\n\n");
    
        printf("Was moechten Sie tun?: ");
        scanf("%i",&ieingabe);
    
        switch(ieingabe)
        {
                        case 1:
    
                             spielfeld(ilaenge,ihoehe,ifarben);
                             break;
    
                        case 2:
                             printf("Spiel laden.");
                             getch();
                             break;
    
                        case 3:
                             printf("Sind Sie sicher, dass Sie das Spiel beenden wollen?\n");
                             printf("1 - Ja\n");
                             printf("2 - Nein\n\n");
                             scanf("%i",&ibeenden);
    
                             if(ibeenden==1)
                             {
                                           return EXIT_SUCCESS;
                             }
    
                             if(ibeenden==2)
                             {
                                           system("cls");
                                           system("PAUSE");
                             }  
    
        }
    
      getch();   
    }
    

    module.h:

    //Header der Module für das Spiel
    
    void spielfeld(int,int,int);
    

    module.cpp:

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    
    void spielfeld(int ilaenge, int ihoehe, int ifarben)
    {
         int iposition1,iposition2;
    
         printf("Geben Sie die Laenge des Spielfelds ein: ");    //Anweisung zur Angabe der Spielfeldbreite
         scanf("%i",&ilaenge);
         printf("Geben Sie die Hoehe des Spielfelds ein: ");     //Anweisung zur Angabe der Spielfeldhöhe
         scanf("%i",&ihoehe);
         printf("Wieviele Farben wollen Sie verwenden?");
         scanf("%i",&ifarben);
    
         system("cls");                                           //Clear Screen - Vorbereitung für das Spiel
    
         iposition2 = 0;                                          //Spielfelderzeugung beginnt
    
         while(iposition2<ihoehe)
         {
    
         iposition1 = 0;
    
         while(iposition1<ilaenge)
          {
           printf(" X");     ///////////////////////////////////////////
           iposition1++;    
          } 
    
         printf("\n\n");
         iposition2++;  
         }                                                       //Spielfelderzeugung beendet
    
    }
    

    Es wird beim Spielstart abgefragt, wie hoch und breit das Spielfeld sein soll (besteht aus x). Es wird an der Stelle mit den Haufen /// erstellt.
    Davor gibt es eine Frage, wieviel Farben man verwenden will. Wenn man jetzt z.B. 5 Farben eingibt, soll eine Funktion 5 Farben definieren und dann die X die erstellt werden zufällig in den 5 Farben färben.

    Es soll also nicht nach einem bestimmten Algorythmus gehen, sondern jedes mal einfach nur irgendwie in einer der 5 Farben färben. Ich denke mal, dass man dazu eine Schleife um den Bereich mit printf("x"); legen muss, um jedes mal die Farbe zu ändern. Nur wie das jetzt funktionieren soll mit jedes mal eine zufällige Farbe raussuchen, weiß ich nicht.

    Vielleicht ist das ein wenig verständlicher.

    MfG



  • Du hast doch schon eine Schleife um das printf() - vor dem Aufruf kannst du dir per rand() eine Farbe aussuchen und setzen (da ist SetConsoleTextAttribute() schon richtig). Die in Frage kommenden Farben würde ich in einem Array verwalten und dann nur noch den Index auf dieses Array auswürfeln.

    (PS: Wenn du die Farben weiterverwenden willst, solltest du sie auch intern speichern und nicht nur ausgeben)



  • CStoll schrieb:

    Die in Frage kommenden Farben würde ich in einem Array verwalten und dann nur noch den Index auf dieses Array auswürfeln.
    )

    Ja, aber ich kann ja nicht entscheiden, ob sie in Frage kommen, wenn Sie vom PC immer automatisch generiert werden.

    Habe es jetzt mal ein wenig anders gelöst(ist ein separates Programm, was die Farbauswahl und die Felderzeugung gleichzeitig wiedergibt:

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    
    using namespace std;
    
    void farbe(int ianzahl, int ianzahl2)
    {
         HANDLE hConsole;
         hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
         printf("Wieviele Farben sollen verwendet werden? ");    //Anzahl der Farben
         scanf("%i",&ianzahl);
         ianzahl2 = ianzahl;
    
         int iposition1,iposition2,ilaenge,ihoehe;
    
         printf("Geben Sie die Laenge des Spielfelds ein: ");    //Anweisung zur Angabe der Spielfeldbreite
         scanf("%i",&ilaenge);
         printf("Geben Sie die Hoehe des Spielfelds ein: ");     //Anweisung zur Angabe der Spielfeldhöhe
         scanf("%i",&ihoehe);
    
         system("cls");                                           //Clear Screen - Vorbereitung für das Spiel
    
         iposition2 = 0;                                          //Spielfelderzeugung beginnt
    
         while(iposition2<ihoehe)
         {
         iposition1 = 0;
    
         while(iposition1<ilaenge)
         {
    
         for(ianzahl=0;ianzahl<ianzahl2;ianzahl++)
         {
    
         SetConsoleTextAttribute(hConsole, rand()%15); ///////////////////////
    
         }
         printf("X ");   
         iposition1++;    
         }
         printf("\n\n");
         iposition2++;  
         }  
    }
    
    int main(int argc,char *argv[])
    {
        int ianzahl,ianzahl1;
        1;
        farbe(ianzahl,ianzahl1);
        getch();
    }
    

    Das einzige, was ich hier noch ändern will, ist das hinter dem rand() bei der markierten Stelle, ianzahl steht. Aber wie krieg ich die da hin? Wenn ich ianzahl da einfach hinschreib, schmiert das Programm einfach ab 😃



  • xkeks93x schrieb:

    CStoll schrieb:

    Die in Frage kommenden Farben würde ich in einem Array verwalten und dann nur noch den Index auf dieses Array auswürfeln.
    )

    Ja, aber ich kann ja nicht entscheiden, ob sie in Frage kommen, wenn Sie vom PC immer automatisch generiert werden.

    Praktisch kannst du mit der Konsole afaik nur 16 Farben darstellen, die kannst du auch in ein Array packen. Bei der Ausgabe ist das auch die Maximalzahl der möglichen Farben, die du ausgeben kannst.

    Das einzige, was ich hier noch ändern will, ist das hinter dem rand() bei der markierten Stelle, ianzahl steht. Aber wie krieg ich die da hin? Wenn ich ianzahl da einfach hinschreib, schmiert das Programm einfach ab 😃

    Was für einen Wert gibst du denn ein? Und was sagt der Debugger?

    PS: Die Parameter der Funktion machen recht wenig Sinn - die Funktion überschreibt die Werte sofort mit Nutzer-Eingaben und das aufrufende Programm bekommt nichts von den lokalen Änderungen mit (Stichwort: call-by-value).



  • CStoll schrieb:

    Was für einen Wert gibst du denn ein? Und was sagt der Debugger?

    Die Zeile sieht so aus:

    SetConsoleTextAttribute(hConsole, rand()%ianzahl);
    

    Der Debugger sagt gar nichts, aber das Programm schmiert ab, sobald ich ianzahl einen Wert zugewiesen hab (mit scanf).

    PS: Die Parameter der Funktion machen recht wenig Sinn - die Funktion überschreibt die Werte sofort mit Nutzer-Eingaben und das aufrufende Programm bekommt nichts von den lokalen Änderungen mit (Stichwort: call-by-value).
    

    Wenn ich erlich bin, weiß ich gerade gar nicht, was du gerade meinst^^ Ich kann gerade mal das nötigste Schulwissen und bin nicht gerade der Profi in dem Bereich.



  • xkeks93x schrieb:

    CStoll schrieb:

    Was für einen Wert gibst du denn ein? Und was sagt der Debugger?

    Die Zeile sieht so aus:

    SetConsoleTextAttribute(hConsole, rand()%ianzahl);
    

    Der Debugger sagt gar nichts, aber das Programm schmiert ab, sobald ich ianzahl einen Wert zugewiesen hab (mit scanf).

    Was ich sagen wollte - welchen Wert gibst du ein, wenn dich das Programm danach fragt? Und an welcher Stelle schmiert das Programm ab?

    PS: Die Parameter der Funktion machen recht wenig Sinn - die Funktion überschreibt die Werte sofort mit Nutzer-Eingaben und das aufrufende Programm bekommt nichts von den lokalen Änderungen mit (Stichwort: call-by-value).

    Wenn ich erlich bin, weiß ich gerade gar nicht, was du gerade meinst^^ Ich kann gerade mal das nötigste Schulwissen und bin nicht gerade der Profi in dem Bereich.

    Du weißt schon, was Parameter sind?
    Normalerweise würde es Sinn machen, wenn das Hauptprogramm die Spielfeld-Einstellungen (Größe und Farb-Anzahl) selber ermittelt und dann an die Funktion übergibt. Die Funktion arbeitet dann mit einer Kopie der übergebenen Werte, so daß das Hauptprogramm es auch nicht mitbekommen würde, wenn du die Parameter änderst.
    Genauso macht es Sinn, wenn eine Funktion die Nutzer-Eingaben abfragt und über Parameter an das Hauptprogramm weitergibt - aber dann verwendet man Referenz-Parameter ( int& wert ).

    In der Konstellation, die du dort hast, verwendest du die Parameter wie lokale Variablen - die übergebenen Werte werden ignoriert und die lokal eingelesenen Werte gehen am Ende der Funktion verloren.



  • CStoll schrieb:

    Was ich sagen wollte - welchen Wert gibst du ein, wenn dich das Programm danach fragt? Und an welcher Stelle schmiert das Programm ab?

    Ich gebe immer verschiedene Zahlen ein. Ist halt 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15. Eine von denen. Und nachdem ich Enter gedrückt habe kommt einfach "Projekt1.exe funktioniert nicht mehr".

    CStoll schrieb:

    Du weißt schon, was Parameter sind?
    Normalerweise würde es Sinn machen, wenn das Hauptprogramm die Spielfeld-Einstellungen (Größe und Farb-Anzahl) selber ermittelt und dann an die Funktion übergibt. Die Funktion arbeitet dann mit einer Kopie der übergebenen Werte, so daß das Hauptprogramm es auch nicht mitbekommen würde, wenn du die Parameter änderst.
    Genauso macht es Sinn, wenn eine Funktion die Nutzer-Eingaben abfragt und über Parameter an das Hauptprogramm weitergibt - aber dann verwendet man Referenz-Parameter ( int& wert ).

    In der Konstellation, die du dort hast, verwendest du die Parameter wie lokale Variablen - die übergebenen Werte werden ignoriert und die lokal eingelesenen Werte gehen am Ende der Funktion verloren.

    Könnte ich doch im Prinzip ganz einfach ändern, wenn ich die printf-s in die mainfunction setze und den rest einfach in dem Modul lasse oder?



  • xkeks93x schrieb:

    CStoll schrieb:

    Was ich sagen wollte - welchen Wert gibst du ein, wenn dich das Programm danach fragt? Und an welcher Stelle schmiert das Programm ab?

    Ich gebe immer verschiedene Zahlen ein. Ist halt 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15. Eine von denen. Und nachdem ich Enter gedrückt habe kommt einfach "Projekt1.exe funktioniert nicht mehr".

    Dann liegt das Problem wohl schon bei den Eingaben - auch wenn ich dort keinen Fehler sehe.

    btw, du verwendest doch C++ (zumindest sehe ich dort <iostream> und <cstdlib>) - also kannst du auch cin und cout für die Ein/Ausgaben verwenden.

    CStoll schrieb:

    Du weißt schon, was Parameter sind?
    Normalerweise würde es Sinn machen, wenn das Hauptprogramm die Spielfeld-Einstellungen (Größe und Farb-Anzahl) selber ermittelt und dann an die Funktion übergibt. Die Funktion arbeitet dann mit einer Kopie der übergebenen Werte, so daß das Hauptprogramm es auch nicht mitbekommen würde, wenn du die Parameter änderst.
    Genauso macht es Sinn, wenn eine Funktion die Nutzer-Eingaben abfragt und über Parameter an das Hauptprogramm weitergibt - aber dann verwendet man Referenz-Parameter ( int& wert ).

    In der Konstellation, die du dort hast, verwendest du die Parameter wie lokale Variablen - die übergebenen Werte werden ignoriert und die lokal eingelesenen Werte gehen am Ende der Funktion verloren.

    Könnte ich doch im Prinzip ganz einfach ändern, wenn ich die printf-s in die mainfunction setze und den rest einfach in dem Modul lasse oder?

    Ja, das würde Sinn machen.



  • CStoll schrieb:

    Dann liegt das Problem wohl schon bei den Eingaben - auch wenn ich dort keinen Fehler sehe.

    Gelöst.

    Vorher:

    SetConsoleTextAttribute(hConsole, rand()%ianzahl);
    

    Nachher:

    SetConsoleTextAttribute(hConsole, rand()%ianzahl2+1);
    

    Lag vermutlich daran, dass ianzahl durch die for-Schleife im Gegensatz zu ianzahl2 die ganze Zeit verändert wurde. Das +1 ist dabei, weil im Fall 0 die Schrift schwarz und so auf dem Konsolenhintergrund nicht zu sehen wäre(Ich weiß, BgColor könnte man auch ändern aber warum kompliziert, wenns auch einfach geht 😃 ).

    CStoll schrieb:

    btw, du verwendest doch C++ (zumindest sehe ich dort <iostream> und <cstdlib>) - also kannst du auch cin und cout für die Ein/Ausgaben verwenden.

    Unser Lehrer hat es uns so beigebracht, deswegen hab ich es so gemacht.

    CStoll schrieb:

    Ja, das würde Sinn machen.

    Hat auch funktioniert 😃

    Code:

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    
    using namespace std;
    
    void farbe(int ianzahl, int ianzahl2, int ilaenge, int ihoehe,int iposition1, int iposition2)
    {
         HANDLE hConsole;
         hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
         ianzahl2 = ianzahl;
    
         system("cls");                                           //Clear Screen - Vorbereitung für das Spiel
    
         iposition2 = 0;                                          //Spielfelderzeugung beginnt
    
         while(iposition2<ihoehe)
         {
         iposition1 = 0;
    
         while(iposition1<ilaenge)
         {
         for(ianzahl=0;ianzahl<ianzahl2;ianzahl++)
         {
         SetConsoleTextAttribute(hConsole, rand()%ianzahl2+1); ///////////////////////     
         }
         printf("X ");  
         iposition1++;    
         }
         printf("\n\n");
         iposition2++;  
         }  
    }
    
    int main(int argc,char *argv[])
    {
        int iposition1,iposition2,ilaenge,ihoehe,ianzahl,ianzahl1,ianzahl2;
    
        printf("Geben Sie die Laenge des Spielfelds ein: ");    //Anweisung zur Angabe der Spielfeldbreite
        scanf("%i",&ilaenge);
        printf("Geben Sie die Hoehe des Spielfelds ein: ");     //Anweisung zur Angabe der Spielfeldhöhe
        scanf("%i",&ihoehe);
        printf("Wieviele Farben sollen verwendet werden? ");    //Anzahl der Farben
        scanf("%i",&ianzahl);
    
        farbe(ianzahl,ianzahl2,ilaenge,ihoehe,iposition1,iposition2);
        getch();
    }
    

    In das Spiel integriert:

    main.cpp:

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    #include "module.h"
    #include <windows.h>
    
    int main(int argc, char *argv[])
    {  
        int ieingabe;
        int ibeenden;
        int ilaenge,ihoehe,ifarben;
        int ianzahl,ianzahl2;
        int iposition1,iposition2;
    
        do
        {                            
        printf("Hauptmenue:\n\n\n");
    
        printf("Waehlen Sie aus, was Sie tun moechten:\n\n");
        printf("1 - Neues Spiel \n");
        printf("2 - Spiel laden\n");
        printf("3 - Beenden\n\n");
    
        printf("Was moechten Sie tun?: ");
        scanf("%i",&ieingabe);
    
        switch(ieingabe)
        {
                        case 1:
                                 printf("Geben Sie die Laenge des Spielfelds ein: ");    //Anweisung zur Angabe der Spielfeldbreite
                                 scanf("%i",&ilaenge);
                                 printf("Geben Sie die Hoehe des Spielfelds ein: ");     //Anweisung zur Angabe der Spielfeldhöhe
                                 scanf("%i",&ihoehe);
                                 printf("Wieviele Farben sollen verwendet werden? ");    //Anzahl der Farben
                                 scanf("%i",&ianzahl);
    
                                 spielfeld(ianzahl,ianzahl2,ilaenge,ihoehe,iposition1,iposition2);
    
                                 break;
    
                        case 2:
                                 printf("Spiel laden.");  //Wird noch gemacht
                                 getch();
                                 break;
    
                        case 3:
                                 printf("Sind Sie sicher, dass Sie das Spiel beenden wollen?\n");
                                 printf("1 - Ja\n");
                                 printf("2 - Nein\n\n");
                                 scanf("%i",&ibeenden);
    
                                 if(ibeenden==1)
                                 {
                                           return EXIT_SUCCESS;
                                 }
    
                                 if(ibeenden==2)
                                 {
                                           system("cls");
                                           system("PAUSE");
                                 }  
    
        }
    
        getch();
    
        }
        while(1); //Ende do-Schleife
    }
    

    module.h:

    //Header der Module für das Spiel
    
    void spielfeld(int,int,int,int,int,int);
    

    module.cpp:

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    #include <windows.h>
    
    void spielfeld(int ianzahl, int ianzahl2, int ilaenge, int ihoehe,int iposition1, int iposition2)
    {
    
         HANDLE hConsole;
         hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
         ianzahl2 = ianzahl;
    
         system("cls");                                           //Clear Screen - Vorbereitung für das Spiel
    
         iposition2 = 0;                                          //Spielfelderzeugung beginnt
    
         while(iposition2<ihoehe)
         {
         iposition1 = 0;
    
         while(iposition1<ilaenge)
         {
         for(ianzahl=0;ianzahl<ianzahl2;ianzahl++)
         {
         SetConsoleTextAttribute(hConsole, rand()%ianzahl2+1); ///////////////////////     
         }
         printf("X ");  
         iposition1++;    
         }
         printf("\n\n");
         iposition2++;  
         }  
    }
    


  • Du mußt aber nur die Variablen als Parameter übergeben, die du wirklich von außen mit Werten füllen willst. Zählvariablen kannst du genausogut lokal in der Funktion definieren, die sie benötigt.

    PS: Welchen Sinn hat eigentlich die Schleife in Zeile 25 bis 28? Du überschreibst n-mal die Consolenfarbe, ohne zwischendurch etwas auszugeben.

    PPS: Frag doch mal deinen Lehrer, welche Sinn seiner Meinung nach die Anweisung #include <iostream> hat 😃



  • CStoll schrieb:

    Du mußt aber nur die Variablen als Parameter übergeben, die du wirklich von außen mit Werten füllen willst. Zählvariablen kannst du genausogut lokal in der Funktion definieren, die sie benötigt.

    Was meinst du damit? Hast du mir ein Beispiel?
    //edit: Ach, du meinst z.B. iposition, weil die nich in der main benötigt wird?

    CStoll schrieb:

    PS: Welchen Sinn hat eigentlich die Schleife in Zeile 25 bis 28? Du überschreibst n-mal die Consolenfarbe, ohne zwischendurch etwas auszugeben.

    Ups, war nicht beabsichtigt 😃

    CStoll schrieb:

    PPS: Frag doch mal deinen Lehrer, welche Sinn seiner Meinung nach die Anweisung #include <iostream> hat 😃

    Jo, werde ich machen. Aber ich benutze Bloodshed Dev-C++, da is bei einer Console-Application oben schon automatisch

    #include <iostream>
    

    drin.



  • xkeks93x schrieb:

    CStoll schrieb:

    Du mußt aber nur die Variablen als Parameter übergeben, die du wirklich von außen mit Werten füllen willst. Zählvariablen kannst du genausogut lokal in der Funktion definieren, die sie benötigt.

    Was meinst du damit? Hast du mir ein Beispiel?
    //edit: Ach, du meinst z.B. iposition, weil die nich in der main benötigt wird?

    Genau so etwas meinte ich.



  • Ok, also danke für die HIlfe! Hast mir echt weitergeholfen! 🙂 👍


Anmelden zum Antworten