[List] ChangeCurrentElement Verständnisproblem

Anfängerfragen zum Programmieren mit PureBasic.
dire3
Beiträge: 7
Registriert: 04.08.2014 13:51

[List] ChangeCurrentElement Verständnisproblem

Beitrag 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?
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: [List] ChangeCurrentElement Verständnisproblem

Beitrag 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
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: [List] ChangeCurrentElement Verständnisproblem

Beitrag 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
dire3
Beiträge: 7
Registriert: 04.08.2014 13:51

Re: [List] ChangeCurrentElement Verständnisproblem

Beitrag von dire3 »

Danke, das hat geholfen.
Antworten