Aufgabe Ticketverkauf txt ausgaben wiederholen sich



  • Soll bei einer Übungsaufgabe eine Matrix erstellen die Zuschauerplätze anzeigt und die man besetzten kann. Das funktioniert alles, aber bei der Ausgabe in eine txt datei welche Plätze gekauft wurden wiederholen die sich immer. ZB wenn jeder Kunde einen Platz kauft
    Käufer 1 hat Reihe 1 Platz 1
    Käufer 2 hat Reihe 1 Platz 1
    Reihe 1 Platz 2 usw...
    hat jemand vielleicht einen Tipp was ich da machen könnte?

    #include <iostream>
    #include <fstream>
    using namespace std;
    int main()
    {
        bool Platz[12][16];
    
        for (int i = 0; i < 12; i++)
        {
            for (int j = 0; j < 16; j++)
            {
                Platz[i][j] = false;
            }
        }
    
        for (int kaeufer = 1; kaeufer <= 3; kaeufer++) // Schleife für drei verschiedene Käufer
        {
            cout << "Käufer " << kaeufer << endl; // Überschrift für den aktuellen Käufer
    
                int x = 0;
                cout << "Wie viele Plätze (max 20) möchten Sie kaufen? ";
                cin >> x;
                cout << "Reihe + Platznummer:" << endl;
    
                for (int j = 1; j <= x; j++)
                {
                    int y, z;
                    cin >> y >> z;
                    if (Platz[y - 1][z - 1])
                    {
                        j--; // Um Platzanzahl nicht zu veringern
                        cout << "Dieser Platz ist bereits belegt! ";
                    }
                    else
                    {
                        Platz[y - 1][z - 1] = true;
                    }
                    cout << endl; // Zeile runtergehen
                }
    
                for (int j = 0; j < 12; j++) // Zeile
                {
                    for (int n = 0; n < 16; n++) // Spalte
                    {
                        if (Platz[j][n])
                            cout << "#"; // Platz belegen
                        else
                            cout << "_";
                        if (n == 7)
                            cout << " "; // Nach Spalte 7 ein Leerzeichen einfügen für den Gang
                    }
                    cout << endl;
                }
    
                ofstream fout("kartenverkauf.txt", ios::app); // an Textdatei anhängen
                int o = 1;
                fout << "Käufer " << kaeufer << " hat folgende Plätze gekauft: " << endl;
    
                for (int j = 0; j < 12; j++)
                {
                    for (int n = 0; n < 16; n++)
                    {
                        if (Platz[j][n])
                        {
                            fout << o << ".: Reihe " << j + 1 << " Platz " << n + 1 << endl;
                            o++;
                        }
                    }
                }
            }    
        return 0;
    }
    


  • Öhhm, was ist die Eingabe, und wie soll(te) die Ausgabe genau sein? 😉



  • Bei Programmstart kann man angeben wie viele Tickets man kaufen will und dann angeben welche plätze, eine zahl für reihe und platz also zb 1 1 für Reihe 1 Platz 1
    Das wird dann nochmal visuel ausgegeben mit _Als Freie Felder und # als belegte
    Das soll sich dann ncoh widerholen für mehrere Kunden

    Dann soll noch in eine Textdatei erstellt werden in der Aufgeschrieben wird wer welche plätze gekauft hat zb
    Kunde1 hat folgende Plätze gekauft
    Reihe 1 Platz 1
    Reihe 1 Platz 2
    Kunde 2 hat
    Reihe 2 Platz 2
    reihe 2 Platz 3 usw.
    Hab aber das Problem das Alle plätze von Kunde 1 auch bei Kunde zwei angegeben werden



  • Ich würde dafür auf jeden Fall eine std::unordered_map verwenden, anstatt ein zweidimensionales bool-Array...

    Und dann musst du prüfen, ob ein Platz schon belegt ist, und in einem solchen Fall um 1 weitergehen. 😉

    Und ein "Zickzack"-Pfad wäre auch nicht schlecht (keiner möchte in der Ecke sitzen...) 😅



  • So sollte es auch funktionieren:

    #include <iostream>
    #include <iomanip>
    
    const int len_x = 12;
    const int len_y = 16;
    
    bool reservieren(int sitzplan[len_x][len_y], int anzahlPersonen, int sitzeProPerson)
    {
        int x = 0;
        int y = 0;
        int ticket_nr = 1;
        for (int person = 1; person <= anzahlPersonen; person++, ticket_nr++)
        {
            for (int sitz = 1; sitz <= sitzeProPerson; sitz++)
            {
                sitzplan[x][y] = ticket_nr;
                y++;
                if (y == len_y)
                {
                    x++;
                    if (x == len_x)
                    {
                        return false;
                    }
                    y = 0;
                }
            }
        }
        return true;
    }
    
    int main(int argc, char const *argv[])
    {
        int sitzplan[len_x][len_y] = {0};
        reservieren(sitzplan, 50, 3);
    
        for (int x = 0; x < len_x; x++)
        {
            for (int y = 0; y < len_y; y++)
            {
                std::cout << std::setw(2) << std::setfill('0') << sitzplan[x][y] << " ";
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    
    
    $ g++ Kino.cpp
    
    $ ./a.exe
    01 01 01 02 02 02 03 03 03 04 04 04 05 05 05 06
    06 06 07 07 07 08 08 08 09 09 09 10 10 10 11 11
    11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16
    17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22
    22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27
    27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32
    33 33 33 34 34 34 35 35 35 36 36 36 37 37 37 38
    38 38 39 39 39 40 40 40 41 41 41 42 42 42 43 43
    43 44 44 44 45 45 45 46 46 46 47 47 47 48 48 48
    49 49 49 50 50 50 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    
    

    0 ist unbelegt...

    Aber bitte... Suchmuster und eine "geeignete" Datenstruktur.



  • Hab jetzt noch einmal "etwas" Zeit darin investiert... Vermutlich sollte sich der Kinosaal nach folgendem Muster füllen:

    Animation langsam

    Animation schnell

    Die GIFs hab ich lokal mit JavaScript/node erstellt:

    main.js

    var { createCanvas, loadImage } = require("canvas");
    var GIFEncoder = require("gif-encoder-2");
    var { writeFile } = require("fs");
    
    let size = 400;
    let len_x = 12;
    let len_y = 16;
    let canvas = createCanvas(size, size);
    let ctx = canvas.getContext("2d");
    ctx.fillStyle = "#00FFFF";
    ctx.fillRect(0, 0, size, size);
    drawGridBorder();
    
    let encoder = new GIFEncoder(size, size);
    encoder.setDelay(400);
    encoder.start();
    encoder.addFrame(ctx);
    
    animate();
    
    encoder.finish();
    
    let buffer = encoder.out.getData();
    writeFile("example-slow.gif", buffer, (error) => {
      error ? console.log(error) : null;
    });
    
    function animate() {
      let intArr = [];
      for (let i = 0; i < len_y; i++) {
        intArr[i] = [];
        for (let j = 0; j < len_x; j++) {
          intArr[i][j] = 0;
        }
      }
      let color = "#FF00FF";
      a: for (let x = len_x / 2 - 1, y = 0, z = 0; y < len_y; x = len_x / 2 - 1, z = 0) {
        while (intArr[y][x] === 1) {
          x--;
          z++;
          if (x < 0) {
            x = 0;
            y++;
            if (y >= len_y) {
              break a;
            }
            break;
          }
        }
        intArr[y][x] = 1;
        drawAt(x, y, color);
    
        while (intArr[y][x] === 1) {
          x++;
          if (x >= len_x) {
            x = len_x - 1;
            y++;
            if (y >= len_y) {
              break a;
            }
            break;
          }
        }
        intArr[y][x] = 1;
        drawAt(x, y, color);
    
        if (z === 0) {
          y = 0;
          while (intArr[y][0] === 1) {
            y++;
            if (y >= len_y) {
              break a;
            }
          }
        } else {
          y++;
          if (y >= len_y) {
            y--;
            while (intArr[y][0] === 0) {
              y--;
              if (y < 0) {
                break a;
              }
            }
            y++;
          }
        }
      }
    }
    
    function drawAt(x, y, color) {
      let sizex = size / len_x;
      let sizey = size / len_y;
      ctx.fillStyle = color;
      ctx.fillRect(x * sizex, y * sizey, sizex, sizey);
      encoder.addFrame(ctx);
    }
    
    function drawGridBorder() {
      let sizex = size / len_x;
      let sizey = size / len_y;
      ctx.fillStyle = "#000000";
      for (let i = 0; i < len_x; i++) {
        ctx.fillRect(i * sizex, 0, 2, size - 2);
      }
      for (let i = 0; i < len_y; i++) {
        ctx.fillRect(0, i * sizey, size - 2, 2);
      }
    }
    
    

    Es ist nicht ausgeschlossen, das man das weiter vereinfachen könnte. Vielleicht ist das ja nützlich.



  • Jaa, es geht einfacher ... ^^

    var { createCanvas, loadImage } = require("canvas");
    var GIFEncoder = require("gif-encoder-2");
    var { writeFile } = require("fs");
    
    let size = 400;
    let len_x = 16; // Anzahl der Spalten
    let len_y = 12; // Anzahl der Zeilen
    let canvas = createCanvas(size, size);
    let ctx = canvas.getContext("2d");
    ctx.fillStyle = "#00FFFF";
    ctx.fillRect(0, 0, size, size);
    drawGridBorder();
    
    let encoder = new GIFEncoder(size, size);
    encoder.setDelay(250);
    encoder.start();
    encoder.addFrame(ctx);
    
    animate();
    
    encoder.finish();
    
    let buffer = encoder.out.getData();
    writeFile("example-2.gif", buffer, (error) => {
      error ? console.log(error) : null;
    });
    
    function animate() {
      let color = "#FF00FF";
    
      let intArr = [];
      for (let i = 0; i < len_y; i++) {
        intArr[i] = [];
        for (let j = 0; j < len_x; j++) {
          intArr[i][j] = 0;
        }
      }
    
      for (let y = 0; intArr[len_y - 1][len_x - 1] === 0; ) {
        if (y >= len_y) {
          y--;
          while (intArr[y][0] === 0) {
            y--;
            if (y < 0) {
              throw new Error("no solution");
            }
          }
          y++;
        }
        a: for (let x = len_x / 2 - 1; y < len_y; x = len_x / 2 - 1, y++) {
          if (intArr[y][x] === 0) {
            intArr[y][x] = 1;
            drawAt(x, y, color);
            intArr[y][x + 1] = 1;
            drawAt(x + 1, y, color);
            y = -1;
            continue a;
          }
    
          while (intArr[y][x] === 1) {
            x--;
            if (x < 0) {
              continue a;
            }
          }
          intArr[y][x] = 1;
          drawAt(x, y, color);
    
          while (intArr[y][x] === 1) {
            x++;
            if (x >= len_x) {
              continue a;
            }
          }
          intArr[y][x] = 1;
          drawAt(x, y, color);
        }
      }
    }
    
    function drawAt(x, y, color) {
      let sizex = size / len_x;
      let sizey = size / len_y;
      ctx.fillStyle = color;
      ctx.fillRect(x * sizex, y * sizey, sizex, sizey);
      encoder.addFrame(ctx);
    }
    
    function drawGridBorder() {
      let sizex = size / len_x;
      let sizey = size / len_y;
      ctx.fillStyle = "#000000";
      for (let i = 0; i < len_x; i++) {
        ctx.fillRect(i * sizex, 0, 2, size - 2);
      }
      for (let i = 0; i < len_y; i++) {
        ctx.fillRect(0, i * sizey, size - 2, 2);
      }
    }
    
    


  • Hier noch mit einer "schönen" Animationsgeschwindigkeitskurve... (y = 500 - 10.20833*x + 0.0531684*x^2).

    Ungefähr in diesen zeitlichen Abständen sollten in echt auch die Kinokarten verkauft werden. Es ist also realistisch: Am Anfang werden weniger Karten verkauft, in der Mitte viele und zum Schluss wieder weniger bzw. gar keine mehr...

    Animation 2



  • @TiltSchweiger

    Du brauchst eine Datenstruktur die sicherstellt, daß Reihennummer/Sitznummer und deren Zuordnung zu einem best. Kunden eindeutig ist. Z.B. so

    place [reihennummer][sitznummer] = 0;  // vor dem Verkauf
    place [reihennummer][sitznummer] = kundennummer; // verkauft
    

    MFG

    Edit: Und natürlich die entsprechenden Methoden dazu.



  • @TiltSchweiger Ich möchte ganz allgemein kommentieren:

    Stell dir vor, du hast mehr als einen Theathersaal oder mehr als eine Veranstaltung (z.B. weil die Veranstaltung drei Wochen lang in deinem Theater spielt). Wie würdest du das mit deinem Programm abbilden?

    => richtig, gar nicht. Und das ist auch das Hauptproblem.

    Erstelle eine Klasse, die den Theatersaal repräsentiert.

    Separiere die Benutzereingabe von der Theatersaal-Klasse! (dies ist besonders wichtig)

    Schreibe einen Test, der bestimmte Eingaben und Ausgaben automatisch testet (d.h. nicht über eine Ausgabedatei, die du dir manuell angucken musst).

    Dann benutze den Code für dein Zielprogramm.

    Dann noch ein paar kleine Dinge:

    bool Platz[12][16];
    
        for (int i = 0; i < 12; i++)
        {
            for (int j = 0; j < 16; j++)
            {
                Platz[i][j] = false;
            }
        }
    

    Du kannst 2d-Arrays einfach mit geschwungenen Klammern null-initialisieren (Value-Initialisierung):

    bool Platz[12][16] = {};
    

    Außerdem ist es schlecht, 12 und 16 einfach so überhall hart zu kodieren. Nimm Konstanten. Oder nimm einen std::vector von std::vector (Theater haben oft vorne weniger Sitze als in den hinteren Reihen). Oder du bleibst bei der jetzigen Stuktur und markierst Sitze z.B. als "gesperrt" (vielleicht steht ja auch irgendwo eine Säule rum) oder als "sichtbehindert". Das geht dann nicht mehr mit einem simplen bool - du bräuchtest dann eine Klasse, die die Platzeigenschaften modelliert. Die brauchst du aber sowieso, um die Kundennummer zu speichern. (die allereinfachste Lösung wäre hier ein int statt bool - 0 = frei, 1=Kunde 1, 2=Kunde 2 und so weiter - aber ein struct Platz { int kundennummer; bool isBelegt;} kostet ja nichts, zumal du dann leicht sowas wie isLoge, isSichtbehinert oder preiskategorie einbauen könntest)

    for (int j = 1; j <= x; j++)
    (...)
                        j--; // Um Platzanzahl nicht zu veringern
    

    Rat: manipuliere nie die Variable der for-Schleife! Das verwirrt nur. Nimm lieber eine while-Schleife, wenn du das tun musst. Wenn ich for mit index-Variable lese, gehe ich davon aus, dass die Iterationsvariable nur über den Kopf gesteuert werden (+ggf break oder continue).

    Dir fehlt außerdem ein Check, ob der Platz auch exisitert. (was passiert bei einer Eingabe von Reihe 1, Platz 30? Oder Reihe -2, Platz -999?)



  • @wob

    Ich wollte mit meinen Beispielen auch nur andeuten, wie es funktionieren könnte.

    Es ist richtig, das Ganze modular zu gestalten, und auf eine vernünftige Datenstruktur zu stellen.


Log in to reply