Iterierbares boost::multi_array<...>::array_type<...> [gelöst]



  • Abend,

    hat einer ne Idee, wie ich boost::multi_array<...>::array_type<...> iterierbar machen kann?

    Brauche es für std::search_n . :xmas2:

    MfG



  • Ich hab das ganze wohl ein wenig zu knapp beschrieben 😃

    Es geht darum, dass ich ein Zweidimensionales Spielfeld für 4-Gewinnt habe. Die einzelnen Feldelemente des Spielfelds sind einfache Objekte dieser Enumeration

    enum ConnectFourFigure
                    {
                            NoPlayer,
                            Player1,
                            Player2,
                            CPU
                    };
    

    Ich muss jetzt einfach alle Sequenzen einer bestimmen Anzahl finden (momentan nur 3/4).
    Das Problem ist, dass ich die Positionen der einzelnen Elemente dieser Sequenzen in ein Set schieben muss.

    Ich hab mir zuerst gedacht, das ganze mit search_n zu erledigen, denn in der Methode in der ich es brauche geht es erstmal nur um horizontale Gruppen die sich mit dem multi_array das ich verwende leicht finden lassen sollten, leider ist es nicht möglich über eine Subview - wenn ich sie erst erzeugt habe - zu iterieren.

    Ich denke, ich lass es jetzt mit den Iteratoren und verwende ganz normale Indize.



  • Warum schaust du jedesmal das ganze Spielfeld von neuem an? Du brauchst doch nur das eine geänderte Feld und seine Nachbarn anschauen, maximal sind das 12 Felder (und es geht sogar auf einem unendlichen Spielfeld).



  • Nö.

    Ich brauche ja die Bedrohungen. Die können sich durch einen Stein völlig verändern.
    Ich zeig das mal.

    + ist eine Bedrohung,
    # ist ein Steinchen

    . . . . . . . .
     . . . . . . . .
     . . . . . . . .
     . . . . # . . .
     . . . . # . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    ➡ In der entsprechenden Spalte einen pushen führt zu

    . . . . . . . .
     . . . . + . . .
     . . . . # . . .
     . . . . # . . .
     . . . . # . . .
     . . . . + . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    Oder

    . . . . . . . .
     . . # # . . . .
     . . . . . . . .
     . . . . # # . .
     . . . . # . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    ➡ In der fünften Zeile pushen führt zu

    . . + . . . . .
     . . # # + . . .
     . . . . # . . .
     . . . . # # . .
     . . . . # . + .
     . . . . + . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    


  • Doch.

    . . . . . . . .
     . . . . . . . .
     . . . . N . . .
     . . . . # . . .
     . . . . # . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    (N heisst neu)

    Test auf Reihe horizontal von N aus: Negativ
    Test auf Reihe diagonal hoch von N aus: Negativ
    Test auf Reihe diagonal runter von N aus: Negativ
    Test auf Reihe vertikal von N aus: 2 Steine darunter, also Reihe von (2, 4) bis (5, 4) von Länge 3 => Bedrohung auf Start+(-1, 0) und auf Ende (sofern kein eigener Stein dort liegt)
    =>

    . . . . . . . .
     . . . . + . . .
     . . . . # . . .
     . . . . # . . .
     . . . . # . . .
     . . . . + . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    Zweites Beispiel:

    . . . . . . . .
     . . # # . . . .
     . . . . N . . .
     . . . . # # . .
     . . . . # . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    

    Test auf Reihe horizontal von N aus: Negativ
    Test auf Reihe diagonal hoch von N aus: Negativ
    Test auf Reihe diagonal runter von N aus: Reihe von (3, 1) bis (6, 4) von Länge 3 => Bedrohung auf Start+(-1, -1) und Ende
    Test auf Reihe vertikal von N aus: Reihe von (4, 2) bis (7, 2) von Länge 3 => Bedrohung auf Start+(0, -1) und Ende
    =>

    . . + . . . . .
     . . # # + . . .
     . . . . # . . .
     . . . . # # . .
     . . . . # . + .
     . . . . + . . .
     . . . . . . . .
     . . . . . . . .
     . . . . . . . .
    


  • Und das ist wirklich (jetzt nur vom Code her) einfacher umzusetzen?

    Locker nicht.

    Die Performance macht sowieso keinen Unterschied.
    Und vom Code her ist es vorausichtlich nach meiner Variante einfacher. :xmas2:



  • Sone schrieb:

    Und vom Code her ist es vorausichtlich nach meiner Variante einfacher. :xmas2:

    Zeig mir mal, wie du die Suche nach diagonalen Bedrohungen aufs ganze Spielfeld umgesetzt hast :xmas2:



  • leisi schrieb:

    Sone schrieb:

    Und vom Code her ist es vorausichtlich nach meiner Variante einfacher. :xmas2:

    Zeig mir mal, wie du die Suche nach diagonalen Bedrohungen aufs ganze Spielfeld umgesetzt hast :xmas2:

    Das willst du nicht sehen, glaub mir.
    Das ist erstmal nur die Suche nach diagonalen Sequenzen:

    ConnectFourField::PlayerPositionSets ConnectFourField::checkDiagonal(uint8_t n) const
                    {
                            ConnectFourFigure checkVal{mNullval};
    
                            PlayerPositionSets rval;
    
                            for(uint8_t globalX(0);globalX < mMatrix.shape()[0];++globalX)
                                    for(uint8_t globalY(0);globalY < mMatrix.shape()[1];++globalY)
                                    {
                                            uint8_t FigureCounter = 0;
    
                                            boost::circular_buffer< Position<> > lastPositions(n);
    
                                            for(uint8_t x(globalX), y(globalY) ; x < mMatrix.shape()[0] && y < mMatrix.shape()[1] ;)
                                            {
                                                    lastPositions.push_back({x, y});
    
                                                    if( ConnectFourFigure f = checkHelper( mMatrix[x][y], checkVal, FigureCounter, n ) )
                                                            ( f == Player1 ? rval.first : rval.second ).insert( PositionSet{ lastPositions.begin(), lastPositions.end() } );
    
                                                    ++y, ++x;
                                            }
    
                                            checkVal = mNullval;//reset checkVal
                                            FigureCounter = 0;//reset the counter
                                            lastPositions.clear();
    
                                            for(int8_t x(globalX), y(globalY) ; x >= 0 && y < mMatrix.shape()[1];)
                                            {
                                                    lastPositions.push_back( {x, y} );
    
                                                    if( ConnectFourFigure f = checkHelper(mMatrix[x][y], checkVal, FigureCounter, n) )
                                                            (f == Player1 ? rval.first : rval.second ).insert( PositionSet{ lastPositions.begin(), lastPositions.end() } );
    
                                                     ++y, --x;
                                            }
                                    }
    
                            return rval;
                    }
    

    (Kommis rausgenommen)
    :xmas1:



  • Die Idee war jetzt, dass man ja die Positionen der in den Sequenzen enthaltenen Steinchen hat, man einfach das ganze abprüfen kann.
    Aber der Code zum Abprüfen einer Bedrohung anhand der Sequenzen ist nochmal lang.

    Edit: Der Code oben wird natürlich noch ggf. umgeschrieben, jetzt wo ich auf multi_array umgestiegen bin dürfte es mit slicing etwas einfacher sein.



  • Gute nachrichten: Habe alles gefixed und hat beim ersten Durchlauf im Test keinen einzigen Fehler gehabt 👍
    Sehr zufrieden :xmas1:


Anmelden zum Antworten