Anfänger mit Array-Blackout



  • Moin Erstmal.

    Ich schreibe gerade ein kleines Maze über mehrere Ebenen. Das Programm läuft ohne Fehler. Nach diversen Haare raufen. 😃

    Doch Leider scheitere ich an einer sache das, das ich keine verschiedenen sogenate "Geheimgänge" abfragen kann.

    static int Karte[3][5][5] = {{
    //map0
    {0113,0124,0124,0124,0112},
    {0123,0101,0101,0101,0121},
    {0223,0101,0501,0101,0121},
    {0123,0101,0101,0101,0121},
    {0114,0122,0122,0122,0111}},
    //map1
    {{0113,0124,0124,0124,0112},
    {0123,0101,0101,0101,0221},
    {0123,0101,0601,0101,0121},
    {0123,0101,0101,0101,0121},
    {0114,0122,0122,0122,0111}},
    //map2
    {{0113,0124,0124,0124,0112},
    {0123,0101,0101,0101,0121},
    {0223,0101,0401,0101,0121},
    {0123,0101,0101,0101,0221},
    {0114,0122,0122,0122,0311}}};
    
    .
    .
    .
    
    // Map Verweise Laufrichtung
    void zeigeRaum(int,int)
    {
      bool Vorn = false; bool Hinten = false; bool Links = false; bool Rechts = false; bool Exit = false; bool Geheimgang = false;
    
       cout<<"\n";
      //Verweise komplett geschrieben.
       switch(Karte[Map][X][Y])    
        {
        case 0101: KK(); Vorn = true; Hinten = true; Links = true; Rechts = true; break;
        case 0401: KKO(); Vorn = true; Hinten = true; Links = true; Rechts = true; Oben = true; break;
        case 0501: KKU(); Vorn = true; Hinten = true; Links = true; Rechts = true; Unten = true; break;
        case 0601: KKOU(); Vorn = true; Hinten = true; Links = true; Rechts = true; Oben = true; Unten = true; break;
        case 0111: OL(); Vorn = true; Links = true; break;
        case 0112: OR(); Vorn = true; Rechts = true; break;
        case 0113: UR(); Hinten = true; Rechts = true; break;
        case 0114: UL(); Hinten = true; Links = true; break;
        case 0121: TKO(); Vorn = true; Links = true; Rechts = true; break;
        case 0122: TKL(); Vorn = true; Hinten = true; Links = true; break;
        case 0123: TKU(); Hinten = true; Links = true; Rechts = true; break;
        case 0124: TKR(); Vorn = true; Hinten = true; Rechts = true; break;
        case 0221: TKOG(); Vorn = true; Links = true; Rechts = true; Geheimgang = true; break;
        case 0223: TKUG(); Hinten = true; Links = true; Rechts = true; Geheimgang = true; break;
        case 0311: OLE(); Vorn = true; Links = true; Exit = true; break;
        default: cout<<"\n\nFehler in der Karte.\n\n"<<endl; 
            cout<<"Enter um fortzufahren."<<endl; 
            _getch(); 
        }
    
      cout<<"\n";
    
        if (Vorn == true)       {cout<<"nach Vorn           - W"<<endl;}
        if (Hinten == true)     {cout<<"nach Hinten         - S"<<endl;}
        if (Links == true)      {cout<<"nach Links          - A"<<endl;}
        if (Rechts == true)     {cout<<"nach Rechts         - D"<<endl;}
        if (Oben == true)       {cout<<"nach Oben           - Q"<<endl;}
        if (Unten == true)      {cout<<"nach Unten          - Y"<<endl;}
        if (Exit == true)       {cout<<"Exit                - E"<<endl;}
        if (Geheimgang == true) {cout<<"zum Geheimgang      - G"<<endl;} 
      cout<<"Deine Auswahl: "; 
    
    	unsigned ch = _getch();
        if (ch == 0xE0)
    	  ch = _getch(); else ch=ch;
    
        switch(ch)    {
          case 'W': case 'w': if (Vorn == true) Y--; break;
          case 'S': case 's': if (Hinten == true) Y++; break;      
          case 'A': case 'a': if (Links == true) X--; break;
          case 'D': case 'd': if (Rechts == true) X++; break;
          case 'Q': case 'q': if (Oben == true) Map--; break;
          case 'Y': case 'y': if (Unten == true) Map++; break;
          case 'G': case 'g': if (Geheimgang == true) Map=1; X=1; Y=1; break; //<---- das einzigste was bis jetzt läuft, leider nur einweg :{
          case 'E': case 'e': if (Exit == true) X=25; cout<<"\nEXIT"<<endl; _getch(); break; // Überlauf zum Rausspringen
          default: cout<<"\n\nKeine g\x81ltige Eingabe.\n\n"<<endl; cout<<"Enter um fortzufahren."; _getch();
        };
    }
    

    Die 4-stellige Zahl stellt den Weg dar, diese wird vom Programm ausgewertet nach Laufrichtung(w,a,s,d), Ebene Wechsel (q,y), Grafikanzeige mit Ascii und als Hilfs-Map ausgewertet.

    Jetzt zu meinem Problem. 😕
    Ich möchte mehrere Geheimgänge fest installieren.

    Ich möchte eine Funktion, die bei auswahl prüft wo stehe ich und wo kann ich hin. Ich habe schon diverse versuche unternommen(else/if, if/then, switch). Leider nicht mit erfolg. Vielleicht habe ich auch nur ein denkfehler. 😮

    Leider kann mir das große Orakel(google) leider auch nicht weiterhelfen im bezug auf "springen in arrays" mein Englich is auch nicht besonders.

    Danke für eure Tips.

    MfG Grendowod



  • Moin!
    Du wirst schon beim programmieren festgestellt haben, dass Dein System schnell an Grenzen stößt und relativ ungeeignet ist als Ausgangspunkt für ein größeres Spiel.

    Wenn ich Deine Frage richtig verstanden habe, geht es im Grunde darum, dass Du eine Technik suchst, die Wege zwischen zwei Räumen Deines Mazes ermöglicht, die im Array nicht nebeneinander liegen.

    Mein Vorschlag wäre, dafür eine map zu benutzen - eine Struktur, in die Du auf der einen Seite einen Raum eingibst und dafür auf der anderen Seite den Raum rausbekommst zu dem ein evtl. vorhandener Geheimgang geht.

    Mit ein wenig Anpassungen hier und da kannst Du Die Idee sicher integrieren.

    Du musst auch nicht gleich alles verstehen - insbesondere die Zeilen 18-21 sind kryptisch - ich habe mir allerdings Mühe gegeben "lesbar" zu schreiben.
    Verständnisfragen sind natürlich sehr willkommen.

    #include <iostream>
    #include <map>
    #include <tuple> // std::tie
    
    // ein Raum in Deinem Spiel mit den entspr. Positionsangaben
    struct room{
      int map, x, y;
    };
    
    // einen Raum ausgeben
    std::ostream& operator<<(std::ostream& out, const room& r){
      return out << "(m:" << r.map << ", x:" << r.x << ", y:" << r.y << ')';
    }
    
    // die Geheimgaenge sind eine Abbildung Startraum -> Enderaum
    using passages_t =  std::map<room, room>;
    
    // ein Helferlein - jetzt kann ich Raeume vergleichen (raumA < raumB)
    bool operator<(const room& x, const room& y){
      return std::tie(x.map, x.x, x.y) < std::tie(y.map, y.x, y.y);
    }
    
    // Alle Geheimgaenge
    const passages_t& get_secret_passages(){
      static passages_t p = {
        {room{0,0,2}, room{2,0,2}},
        {room{2,0,2}, room{0,0,2}},
        {room{1,4,1}, room{2,4,3}},
        {room{2,4,3}, room{1,4,1}}
      };
      return p;
    }
    
    // Gibt es einen Geheimgang aus dem Raum r?
    bool has_secret_passage(const room& r){
      return get_secret_passages().count(r)!=0u;
    }
    
    // Dieser Typ signalisiert, wenn man einen Geheimgang benutzen will, wo keiner ist
    // im weiteren weitestgehend ignoriert
    struct no_sec_pass{};
    
    // Benutz den Geheimgang aus Raum r
    // gibt den neuen Raum zurueck
    const room& use_secret_passage(const room& r){
      if(!has_secret_passage(r))
        throw no_sec_pass{};
      return get_secret_passages().find(r)->second;
    }
    
    // und alles zusammen
    int main(){
      using namespace std;
      room current = room{0,0,2};
      cout << "using passage from: " << current << '\n';
      if(has_secret_passage(current))
        current = use_secret_passage(current);
      cout << "Now in room: " << current
    	    << "\nGoing back...\n";
      current = use_secret_passage(current);
      cout << "Now in room: " << current << '\n';
    }
    

    Cheers!



  • Ich würde sogar noch einen Schritt weiter gehen als Furble Wurble und die Verbindungen zwischen zwei Räumen als Objekt abbilden. Die map als Lookup Tabelle sollte auch eine Liste von Verbindungen zurückgeben, damit ist es möglich, dass zwei Räume durch mehr als eine Möglichkeit verbunden sind (z.b. normale Tür und zusätzlich Geheimgang).


Anmelden zum Antworten