Vector in Array speichern


  • Mod

    Dein Fehler liegt nicht in der Verwendung von vector-Arrays an sich. Das ist kein Problem. Folglich machst du bei deren Verwendung irgendwas falsch.



  • SeppJ schrieb:

    Dein Fehler liegt nicht in der Verwendung von vector-Arrays an sich. Das ist kein Problem. Folglich machst du bei deren Verwendung irgendwas falsch.

    Nunja ich verwende mein Vector noch gar nirgends, ich deklariere ihn bloss im Header...

    Ich werde versuchen eine genauere Fehlermeldung rauszubekommen ^^



  • Samyboy schrieb:

    Nunja ich verwende mein Vector noch gar nirgends, ich deklariere ihn bloss im Header...

    Dann liegt es sicher nicht daran. Zeige doch mal etwas Code.

    Und es wäre gut, wenn du noch auf meine obere Frage eingehen könntest.



  • Nexus schrieb:

    Samyboy schrieb:

    Ich versuche gerade einen Vector mit Pointern zu meinem eigenen Objekt zu erstellen, diesen Vector packe ich in ein Array:

    Tönt kompliziert. Was willst du genau erreichen (was, nicht wie)?

    Nunja ich versuche alle meine Schachfiguren in ein Array von 2 Vectoren zu speichern (alle Weisse in m_allPieces[0] und alle Schwarzen in m_allPieces[1], weil WHITE und BLACK konstante 0 und 1 sind...)

    Danach möchte ich sie einzeln ansprechen können, um die Position herauszufinden und so weiter...

    Ich könnte natürlich mein "main-board" Array durchlaufen, aber da hab ich halt die Schwarzen und Weissen Figuren nicht getrennt...



  • Hab noch etwas herausgefunden, mein Programm stürzt nur ab, wenn ich 2 Objekte vom Typ Vector initialisiere, also z.B

    2 vector<Piece*>
    2 vector<Piece*>::iterator
    1 vector<Piece*> und 1 vector<Piece*>::iterator

    Hier mal meine Board Klasse, die betroffen ist:

    class Board {
        public:
            Board();
            ~Board();
    
            void Draw(sf::RenderWindow* window);
            bool MoveIsLegal(int move[2][2], unsigned int& player);
            void DoMove(int move[2][2]);
            void Reset();
            void AddPiece(Piece* piece, int position[2]);
            Piece* GetPosition(int position[2]);
    
            // std::vector<Piece*> GetThreateningPieces(int position[2]);
    
        private:
            Piece* m_board[8][8];
            std::vector<Piece*> m_allPiecesWhite;
            // std::vector<Piece*> m_allPiecesBlack; // Wenn das kein Kommentar ist stürzts ab!
            // std::vector<Piece*>::iterator iter;
            char m_boardWithLetters[8][8];
            void DeletePiece(int position[2], int color);
    };
    

    Wenn ich sonst noch Code zeigen soll, bitte sagen! Bin echt dankbar für jede Hilfe, bin jetzt schon etwa ne Stunde dran :p


  • Mod

    Das ist zwar grauenhaftes Design, aber an sich noch kein Fehler.

    Meine Glaskugel sagt aber, dass du bestimmt was falsch machst bei der Pointerfrickelei.

    Empfohlener Ansatz zur Problembehebung: Schmeiß alles weg. Überdenke dein Schachproblem. Mach ein neues, sauberes Design. -> Proft!



  • SeppJ schrieb:

    Das ist zwar grauenhaftes Design, aber an sich noch kein Fehler.

    Meine Glaskugel sagt aber, dass du bestimmt was falsch machst bei der Pointerfrickelei.

    Empfohlener Ansatz zur Problembehebung: Schmeiß alles weg. Überdenke dein Schachproblem. Mach ein neues, sauberes Design. -> Proft!

    Könnteste bitte konkret werden mit Design?

    Ich habe das Gefühl das ÜBERHAUPT NICHTS lesbar ist bei meinem Schachprogramm, und ans neu machen hab ich auch schon gedacht ^^


  • Mod

    Samyboy schrieb:

    Könnteste bitte konkret werden mit Design?

    Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?



  • SeppJ schrieb:

    Samyboy schrieb:

    Könnteste bitte konkret werden mit Design?

    Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?

    Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse 😃

    Und noch etwas, komischerweise kann ich einen Vector deklarieren, auch ohne #include <vector>? (trotzdem können nicht mehrere vectoren deklariert werden (auch nicht in einem Array z.B), sonst stürzt das ganze ab) Ich glaube die SFML Library nervt da irgendwie die Vectoren oder so oO

    Sehr, sehr komisch -.-



  • Die Fehlermeldung:

    (Falls es jemanden was bringt, ich werde nicht schlau draus, leider keine Zeilen angegeben xD)

    Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020.
    Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020.
    Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020.
    Eine Ausnahme (erste Chance) bei 0x76f3b727 in SMFL.exe: Microsoft C++-Ausnahme: std::bad_alloc an Speicherposition 0x0044f514..
    Eine Ausnahme (erste Chance) bei 0x6780fd85 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000000.
    Unbehandelte Ausnahme bei 0x6780fd85 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000000
    

  • Mod

    Samyboy schrieb:

    SeppJ schrieb:

    Samyboy schrieb:

    Könnteste bitte konkret werden mit Design?

    Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?

    Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse 😃

    Wie du schon selbst schreibst, ist dein Programm praktisch unlesbar. Außerdem fuchtelst du ohne erkennbaren Grund mit rohen Pointern rum, was gerade bei unerfahrenen Programmierern fast immer schief geht, so auch bei dir. Ich werde mir mal kurz Gedanken machen wie ich ein Schachbrett mit deinen Methoden modellieren würde. Melde mich in ein paar Minuten wieder.



  • SeppJ schrieb:

    Samyboy schrieb:

    SeppJ schrieb:

    Samyboy schrieb:

    Könnteste bitte konkret werden mit Design?

    Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?

    Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse 😃

    Wie du schon selbst schreibst, ist dein Programm praktisch unlesbar. Außerdem fuchtelst du ohne erkennbaren Grund mit rohen Pointern rum, was gerade bei unerfahrenen Programmierern fast immer schief geht, so auch bei dir. Ich werde mir mal kurz Gedanken machen wie ich ein Schachbrett mit deinen Methoden modellieren würde. Melde mich in ein paar Minuten wieder.

    Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?



  • Samyboy schrieb:

    Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?

    Nein, auf keinen Fall! Denk dran, Value-Semantik ist gut. Benutze möglichst automatische Objekte. Wenn du besitzende Zeiger brauchst, kapsle sie (Smart-Pointer, Pointer-Container oder ähnliches). Aber im Anwendungscode sollte new und delete so wenig wie nur möglich auftauchen.


  • Mod

    Hier ist mal ein Anfang, mit dem man arbeiten kann. Du musst nur noch die Methoden Implementieren, was in den meisten Fällen trivial sein sollte. Das schwierige, wo die Magie passiert, ist Coordinates::valid_move().

    #include <vector>
    #include <cassert>
    
    enum Color{white, black};
    enum Value{empty, pawn, knight, bishop, rook, queen, king};
    
    // A set of coordinates on a chess board
    class Coordinates
    {
    private:
      unsigned rank, file;
    public:
      Coordinates(unsigned x, unsigned y): file(x), rank(y)
      {
        assert(x<8);
        assert(y<8);
      };
    
      // Checks if other square is a valid move for a <v> from this coordinate:
      bool valid_move(Value v, Coordinates c) const;
    
    };
    
    class Square
    {
    private:
      // What kind of piece is on the square?
      Value i_value;
      // The color of the piece on the square. Ignored if value is empty.
      Color i_color; 
    
    public:
      Square(Value v, Color c=white): i_value(v), i_color(c){};
    
      // Draw the piece on output
      void draw(sf::RenderWindow* window) const;
    
      void set(Value v, Color c=white);
    
      // Getter:
      Value get_piece();
      Color get_color();
    };
    
    // A chessboard
    class Board
    {
    private:
      std::vector<Square> i_squares[64];
      // Returns reference to square at coordinates
      Square& at(Coordinates c);
    public:
      // Draws a chessboard and calls draw for all squares
      void draw(sf::RenderWindow* window) const;
    
      // Set piece at position
      void AddPiece(Coordinates coordinates, Value v, Color c=white);
    
      // Check if move is legal for player
      bool MoveIsLegal(Coordinates from, Coordinates to, Color player) const;
    
      // Move a piece
      void DoMove(Coordinates from, Coordinates to);
    
      // Sets all squares to empty
      void Reset();
    
      // Resets all squares to the initial value for a standard game
      void InitialPosition();
    
    };
    


  • Bis auf

    std::vector<Square> i_squares[64];
    

    ein (ganz) gutes Design.

    SeppJ, du meinst wohl eher, daß der vector mit 64 Feldern (Square) initialisiert wird, und nicht, daß du 64 vectors erzeugst?

    Und Coordinates::valid_move() wird ohne Zugriff auf das Schachbrett auch nicht sehr sinnvoll sein (d.h. z.B. bei Bauern und Königen ist auch die Farbe entscheidend).

    Und ich würde auch noch die Trennung von GUI (SFML) und Logic (ChessBoard) vornehmen...



  • Samyboy schrieb:

    Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?

    Wenn ein Objekt erst einmal mit new angelegt wurde ist alles was von diesem Objekt ausgeht (Member) automatisch im Heap und nicht im Stack des Programms (des main-Funktionsaufrufes). Geht gar nicht anders. Nur wenn du etwas dann mit new anlegst ist es eben ein beliebiger Speicherbereich und nicht mehr zusammenhängend.



  • Wenn ich zum Design noch was anmerken dürfte:
    Die Methoden Draw( ... ) gehören da eindeutig nicht zu Square und auch nicht zu Board, du solltest Logik und Darstellung trennen.


  • Mod

    Th69 schrieb:

    Bis auf

    std::vector<Square> i_squares[64];
    

    ein (ganz) gutes Design.

    SeppJ, du meinst wohl eher, daß der vector mit 64 Feldern (Square) initialisiert wird, und nicht, daß du 64 vectors erzeugst?

    Ups, ähh, ja.

    Und Coordinates::valid_move() wird ohne Zugriff auf das Schachbrett auch nicht sehr sinnvoll sein (d.h. z.B. bei Bauern und Königen ist auch die Farbe entscheidend).

    Ich hatte mir gedacht, dass die Methode Board::MoveIsLegal() das macht und dabei Coordinates::valid_move() benutzt um überhaupt zu prüfen, wohin gegangen werden kann. Ist sicherlich noch suboptimal, da ich mir nicht wirklich Gedanken gemacht habe, wie man das implementieren würde.

    Und ich würde auch noch die Trennung von GUI (SFML) und Logic (ChessBoard) vornehmen...

    Ahh, die Urfrage der Spieleprogrammierung. Irgendwie konnte mir nie jemand sagen, welche Vorgehensweise besser ist (ich programmiere aber auch nicht viele Spiele). Ist momentan die Trennung von Logik und Darstellung wieder in?



  • SeppJ schrieb:

    Ist momentan die Trennung von Logik und Darstellung wieder in?

    Ich glaube dies war eigentlich nie out. Wobei man abwägen muss: Ist Wartbarkeit und Portierbarkeit wichtiger als der zusätzliche Aufwand?

    Ich arbeite derzeit in einem Projekt, wo es besser gewesen wäre auf ersteres zu setzen. Eine nachträgliche Änderung ist in loser gekoppelten Systemen immer einfacher als in fest "verdrahteten" Systemen. Selbst wenn es nicht um den Austausch der Ausgabeform geht, sondern nur der Anpassung.



  • Dankeschön für die tollen Tipps und Ideen! (Vor allem Dir Sepp)

    Ich guck mir das ganze mal in RUhe an 🙂


Anmelden zum Antworten