NSArray mit rotierendem Index

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

Macoun 2019 - Frühbucherrabatt endet morgen

  • NSArray mit rotierendem Index

    Wie kann ich xcode-konform (NSArray in NSArray?) mit einem rotierenden Index auf Objekte zugreifen. Hier trickse ich noch mit einem in eine Property "geschummelten" C-Array.

    also:
    Ich habe ein 2D-Feld (z.B. Schachbrett) als 1D-NSArray und will eine Zelle(cell) bei einer zutreffenden Bedingung auf eines der 4 bekannten Nachbarfelder(cell.nbh[?]) weiterziehen.


    Quellcode

    1. int dir= random() % 4; // Start => Zufallsrichtung
    2. cell.chance= 4; // Anzahl Möglichkeiten
    3. do {
    4. nextcell= [world.field objectAtIndex:cell.nbh[dir]]; // Testnachbar
    5. dir= ++dir % 4;
    6. } while (--cell.chance && !nextcell.typ); // solange noch Versuche frei und Nachbartyp falsch
    7. if (c.chance) {
    8. [cell hide];
    9. [nextcell show];
    10. }


    das muss doch irgendwie noch anders und ohne Tricks gehen!
  • Mac & i Test Abo
  • Hallo Thallius,
    Es gibt 4 Richtungen dir % 4 kann also 0..3 sein
    um alle durchzutesten musst du max 4 Versuche machen, also Abbruch, wenn kein Versuch mehr frei oder vorher schon ein Treffer
    Die Folgezelle nextdir wird also im NSArray world.field am Index des Nachbars mit der Richtung dir geliefert
    hat dieser den Typ true kann weiter gemacht werden.
    Jetzt alles klar?
    Mein Proben liegt darin, dass mir das C-Array nbh einen Integer als Index zurückliefert. Hätte ich auch hier ein NSArray, bekäme ich ja ein Object zurück.

    ruß, Norbert

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von murpsel ()

  • Nein gar nichts.

    Was ist denn cell ? was ist cell.nbh[] ? Warum zeigt eine Variable in einer celle auf den Index einer anderen ? Warum dann nicht gleich auf die Celle selber (Liste) ? Wozu brauchst du diese Verkettung überhaupt ?

    Wenn Du ein 4x4 Feld hast dann mach doch einfach ein Array von 0-15 und dann kannst du mit index+4, index-4, index+1,index-1 genauso dich auf die Nachbarfelder bewegen. Da brauchst du doch keine Verknüpfung der Celler untereinander?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ganz so einfach ist es leider nicht.
    Ich habe ein zur Laufzeit erzeugtes Feld von bis zu bis zu 1000 x 800 Zellen.
    World.field ist eine Objektive-C Klasse die für jede Zelle eine weitere ObjC Klasse Cell mit diversen Zusatzinformationen und einem C-Array der Feld-Indizies der 4 Neighborhoods(nbh) enthält.
    Der Index im NSArray ist ja nichts anderes als ein Zeiger auf die entsprechende Nachbarzelle. Ich kann also beim Initialisieren die Nachbarzellen festlegen.
    z.B. Nachbar UP => eigener Index - Anzahl Spalten im Feld, Right => eigener Index +1 usw., aber UP von einer Zelle in der ersten Zeile ist die Zelle in der letzten Zeile, da die Welt einen Thorus darstellt.
    Links und rechts sowie oben und unten sind miteinander verknüpft.
    Muss jetzt leider für ein paar Std. weg.
    Danke erst mal!
    Norbert
  • murpsel schrieb:

    Mein Proben liegt darin, dass mir das C-Array nbh einen Integer als Index zurückliefert. Hätte ich auch hier ein NSArray, bekäme ich ja ein Object zurück.

    Warum nicht NSInteger Objekte (oder NSNumber oder wie das hiess) und dann einfach -intValue?

    Frage an Obj-C Profis: Ist das von der Performance eigentlich bei einem grossen Array irgendwie merklich nachteilig -- wegen den ganzen msgSend (die man bei einem C Array nicht haette)?
    C++
  • murpsel schrieb:

    Ganz so einfach ist es leider nicht.
    Ich habe ein zur Laufzeit erzeugtes Feld von bis zu bis zu 1000 x 800 Zellen.
    World.field ist eine Objektive-C Klasse die für jede Zelle eine weitere ObjC Klasse Cell mit diversen Zusatzinformationen und einem C-Array der Feld-Indizies der 4 Neighborhoods(nbh) enthält.
    Der Index im NSArray ist ja nichts anderes als ein Zeiger auf die entsprechende Nachbarzelle. Ich kann also beim Initialisieren die Nachbarzellen festlegen.
    z.B. Nachbar UP => eigener Index - Anzahl Spalten im Feld, Right => eigener Index +1 usw., aber UP von einer Zelle in der ersten Zeile ist die Zelle in der letzten Zeile, da die Welt einen Thorus darstellt.
    Links und rechts sowie oben und unten sind miteinander verknüpft.
    Muss jetzt leider für ein paar Std. weg.
    Danke erst mal!
    Norbert

    Ich verstehe immer noch nicht, warum die Nachbarn über Indexe adressieren möchtest.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Quellcode

    1. int cellsPerRow=10;
    2. int rows=10;
    3. int maxSteps=4;
    4. int cellCount=cellsPerRow*rows;
    5. int array[cellCount];
    6. int testCell=random()%(cellCount);
    7. int destCell=-1;
    8. for(int i=0;i<maxSteps;i++)
    9. {
    10. int testIndex=(testCell-i)%cellCount;
    11. if(array[textIndex]==0) // nicht besetzt
    12. {
    13. destCell=array[testIndex];
    14. break;
    15. }
    16. testIndex=(testCell+i)%cellCount;
    17. if(array[textIndex]==0) // nicht besetzt
    18. {
    19. destCell=array[testIndex];
    20. break;
    21. }
    22. testIndex=(testCell-(i*cellsPerRow))%cellCount;
    23. if(array[textIndex]==0) // nicht besetzt
    24. {
    25. destCell=array[testIndex];
    26. break;
    27. }
    28. testIndex=(testCell+(i*cellsPerRow))%cellCount;
    29. if(array[textIndex]==0) // nicht besetzt
    30. {
    31. destCell=array[testIndex];
    32. break;
    33. }
    34. }
    Alles anzeigen


    oder verstehe ich hier was total falsch ?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Hallo, bin wieder da.

    erst mal vielen Dank für eure Antworten. So richtig klar ist das Problem aber wohl noch nicht. Vielleicht hab ich mich ja auch einfach schlecht ausgedrückt.
    In C ist das ja alles auch kein Thema. Ich will eine elegante Lösung für Objective-C (iPad).
    Ich habe ein Feld mit vielen einzelnen Zellen, die jeweils wiederum Informationen über sich enthalten sollen.
    In schöner OO-Manier ist also das Feld eine Klasse mit Info über Zeilen, Spalten, Bitmap, Zustand, Gitternetz… usw.
    Eine Zelle ist wieder eine eigene Klasse mit allen Informationen über sich selbst, Koordinaten, Zustand, Farbe … usw.
    Nun ist für eine Zelle aber auch der Zustand der Nachbarzellen interessant. Also erhält eine Zelle auch 4 Zeiger auf ihre Nachbarzellen. Diese werden bei der Initialisierung der Feldklasse (erst hier sind sie ja bekannt) vergeben.
    Das Feld ist bei mir (bleiben wir beim Schachbrett) ein NSArray mit mit 64 Zell-Objekten.
    Die Zelle enthält bei mir nun ein C-Array mit den Feld-Indexen der Nachbarn. Also Zelle B1 (10.Feld [idx 9] im Schachbrett) wird mit dem Array nbh[]={1,10,17,8} // UP,RIGHT,DOWN,LEFT initialisiert. Der Index ist ja im Endeffekt wie ein Zeiger auf eine Zelle.
    All dies wird als ein Komplex bei der Initialisierung bereits festgelegt, wenn meine Dimensionen bekannt sind. Zur Laufzeit soll also nicht mehr groß gerechnet werden!!!
    mit nextcell= [world.field objectAtIndex:cell.nbh[dir]] mache ich das ja auch alles bereits und es läuft ja auch wunderbar.
    Meine Frage ist lediglich, wie löse ich das elegant in OBJ-C. Ohne Tricks kann ich kein C-Array als Property in der Klasse übergeben. Eine Property brauche ich aber, da ich von "außen" auf die Cell-Klasse zugreife. verwende ich in Cell aber auch ein NSArray, krieg ich wieder Objekte zurück anstatt einen Index.

    Aber jetzt, wo ich das schreibe: vielleicht liegt ja genau da mein Fehler. Ich kann ja statt dem Index auch wirklich die Zelle zurückgeben. Das Iterieren ist zwar mit [class objectAtIndex:n] etwas langatmiger, aber eigentl. auch kein Problem.
    Also vermutlich erst mal gelöst. Danke trotzdem an alle,

    Norbert
  • murpsel schrieb:

    Nun ist für eine Zelle aber auch der Zustand der Nachbarzellen interessant. Also erhält eine Zelle auch 4 Zeiger auf ihre Nachbarzellen. Diese werden bei der Initialisierung der Feldklasse (erst hier sind sie ja bekannt) vergeben.


    Das ist aber der Punkt wo Du OO verlässt. Wenn du mehrere Objekte miteinander in Verhältnis zueinander setzt dann benötigst Du einen Controller der dieses macht. Das macht nicht das Object selber.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • jein, du hast schon recht und eigentlich sollte eine Zelle nichts von der anderen wissen (der Controller ist hier die Feldklasse), aber ich muss mich von Zelle zu Zelle weiterhangeln können, ohne dies global zu steuern.
    Das macht es ja so einfach. Setz eine Schleife um meinen als erstes genannten 10-Zeiler und ich kann mich bereits an einem Objekt im Bild "entlangtasten"

    Gruß, Norbert
  • murpsel schrieb:

    […]
    Das Feld ist bei mir (bleiben wir beim Schachbrett) ein NSArray mit mit 64 Zell-Objekten.
    Die Zelle enthält bei mir nun ein C-Array mit den Feld-Indexen der Nachbarn. Also Zelle B1 (10.Feld [idx 9] im Schachbrett) wird mit dem Array nbh[]={1,10,17,8} // UP,RIGHT,DOWN,LEFT initialisiert. Der Index ist ja im Endeffekt wie ein Zeiger auf eine Zelle.
    […]t


    NSArray* neighbors = [NSArray arrayWithObjects:upCell, rightCell, downCell, leftCell, nil];
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Also wenn ich es mir recht überlege und deine Zellen ja gar keine Infos über andere Zellen haben sollten, würde ich ein Objekt erstellen mit einem Array der Zellen, Properties für die Ranges x und y, falls es ein 2-dim Array sein soll und eine Methode, der du bei Aufruf die Indizes x und y der aktuellen Zelle übergibst und die dir einen Array mit den entsprechenden Zeigern auf die Nachbarzellen zurückgibt, oder eben die Indizes. Es gibt ja auch Zellen, die nur 2 oder 3 Nachbarn haben. Solche einfachen Index-Rechnungen dürften sich ja kaum performant auswirken.
  • lucia schrieb:

    Also wenn ich es mir recht überlege und deine Zellen ja gar keine Infos über andere Zellen haben sollten, würde ich ein Objekt erstellen mit einem Array der Zellen, Properties für die Ranges x und y, falls es ein 2-dim Array sein soll und eine Methode, der du bei Aufruf die Indizes x und y der aktuellen Zelle übergibst und die dir einen Array mit den entsprechenden Zeigern auf die Nachbarzellen zurückgibt, oder eben die Indizes. Es gibt ja auch Zellen, die nur 2 oder 3 Nachbarn haben. Solche einfachen Index-Rechnungen dürften sich ja kaum performant auswirken.


    Das meinte ich mit einem Controller der die Cellen verwaltet

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Amin Negm-Awad schrieb:

    NSArray* neighbors = [NSArray arrayWithObjects:upCell, rightCell, downCell, leftCell, nil];

    So was in der Art hab ich mir auch schon gedacht. Aber das wird ziemlich aufwändig im Konstruktor, da ja in der Initialisierungsschleife noch nicht alle Objekte vorhanden sind. Die Indizes aber kann ich jederzeit bereits festlegen.
    Abgesehen davon. Wie gestalte ich einen Aufruf in adäquater Form zu

    Quellcode

    1. next= [world.field objectAtIndex:c.nbh[dir]];
    2. if (next.typ) c= next;

    mit objectAtIndex kann ich ja nicht mehr arbeiten, wenn das nbh-Array Objekte enthält!

    Ich fang halt gerade erst mit ObjC an und muss mich durch vieles erst noch durchlesen. Gerade das ganze Memory Management und so.
    Aber wie gesagt, mein Code läuft ja (und zwar rattenschnell). Eigentlich ist dies eine View-Klasse und das Feld eine als Thorus zusammengeklappte Bitmap.