Seite 1 von 1

[List] ChangeCurrentElement Verständnisproblem

Verfasst: 25.12.2014 14:54
von dire3
Hallo,

die Funktion ChangeCurrentElement verhält sich nicht so, wie ich es erwarten würde. Zunächst einmal ein Auszug aus meinem Code:

Code: Alles auswählen

  ; Iterate through all objects and look for the goals
  ResetList(*g\Objects())
  While NextElement(*g\Objects())
    If *g\Objects()\Type = #Goal
      ; We found a goal, search for a (color mating) box in the goal
      *goal.Object = *g\Objects() ; Save current position
      ; Reset list to iterate through all objects and look for the box
      ResetList(*g\Objects())
      While NextElement(*g\Objects())
        If *g\Objects()\Type = #Box And *g\Objects()\Color = *goal\Color And IsBoxInGoal(*g\Objects(), *goal)
          ; Match found, search for next goal
          numFullGoals = numFullGoals + 1
          Break
        EndIf
      Wend
      
      ; Change to prev. position
      ChangeCurrentElement(*g\Objects(), *goal) ; <---- Funktioniert nicht
    EndIf
  Wend
Der Code ist hoffentlich verständlich. Ich gehe eine Liste zunächst in einer äußeren Schleife durch und suche nach einem Ziel (Goal). Ist dieses gefunden, so muss ich noch einmal durch die komplette Liste gehen und nach einem anderen Objekt (Box) suchen, welches sich in diesem Ziel befindet. Am Ende der inneren Schleife (oder bereits nach dem Break innen) möchte ich das aktuelle Element der Liste mithilfe von ChangeCurrentElement wieder auf das zuvor gefundene Ziel setzen, damit ich nicht in einer Endlosschleife hängen bleibe. Das funktioniert (so) aber leider nicht. Ein Debuggen von *g\Objects() direkt nach ChangeCurrentElement liefert einen unsinnigen Wert, weswegen der nächste Aufruf von NextElement der äußeren While-Schleife zum Absturz des Programms führt. Der Wert von *goal ist aber korrekt und befindet sich auch weiterhin irgendwo in der Liste (siehe nächster Absatz).

Als Abhilfe habe ich mir nun eine Funktion geschrieben, die gefordertes löst, allerdings nur für Listen vom Typen "Object" funktioniert, was unschön ist. Diese Hilfsfunktion durchläuft die Liste einfach so lange, bis (abstrakt gesehen) *g\Objects() = *goal ist. Das funktioniert auch bisher problemlos.

Meine Frage ist nun, weswegen die offizielle Funktion ChangeCurrentElement nicht meinem erwarteten Verhalten entspricht. Was mache ich falsch?

Re: [List] ChangeCurrentElement Verständnisproblem

Verfasst: 25.12.2014 15:53
von Bisonte
ChangeCurrentElement ist die falsche Wahl.

Sieh dir PushListPosition() und PopListPosition() in der Hilfe mal genauer an....

Ohne Test da Rest fehlt wäre :

Code: Alles auswählen

; Iterate through all objects and look for the goals
ResetList(*g\Objects())
While NextElement(*g\Objects())
  If *g\Objects()\Type = #Goal
    ; We found a goal, search for a (color mating) box in the goal
    ; *goal.Object = *g\Objects() ; Save current position
    PushListPosition(*g\Objects()) ; <---------------------
    ; Reset list to iterate through all objects and look for the box
    ResetList(*g\Objects())
    While NextElement(*g\Objects())
      If *g\Objects()\Type = #Box And *g\Objects()\Color = *goal\Color And IsBoxInGoal(*g\Objects(), *goal)
        ; Match found, search for next goal
        numFullGoals = numFullGoals + 1
        Break
      EndIf
    Wend
    
    ; Change to prev. position
    ; ChangeCurrentElement(*g\Objects(), *goal) ; <---- Funktioniert nicht
    PopListPosition(*g\Objects()) ; <------------------------
  EndIf
Wend

Re: [List] ChangeCurrentElement Verständnisproblem

Verfasst: 25.12.2014 16:43
von NicTheQuick
'ChangeCurrentElement()' ist völlig korrekt. 'Push' und 'Pull' sind neuere Befehle, die das allerdings vereinfachen, aber das gleiche machen.
Der Fehler liegt wo anders. Hier gehört ein @ rein:

Code: Alles auswählen

*goal.Object = @*g\Objects() ; Save current position

Re: [List] ChangeCurrentElement Verständnisproblem

Verfasst: 25.12.2014 19:55
von dire3
Danke, das hat geholfen.