Swift : strange delegate behaviour

I have this routine

 private func transversePATH(from:Point,to:Point,stackUNDO:Bool=true ) {
        var sequence : [SKAction] = []
        //
        // Transverse the designated Path
        //
        for i in(0...p!.count-1) {
//
// This section updates a counter for each move on the path
            if i>0  {
                let incMove = SKAction.customAction(withDuration: 0.01, actionBlock:  { (node, elapsedTime) -> () in
                    print("Call #\(i)")
                    self.mySokobanDelegate?.updateMoveCount(moveCnt: 1)
                })
                sequence.append(incMove)
            }

       .... other unrelated stuff

        }
        theACTOR?.run(SKAction.sequence(sequence))
    }

the line that says

  print("Call #\(i)")

SHOULD be from 1 to 12 (for example)
BUT some values are DUPLICATED?!

Call #1
>>>1
Call #2
>>>2
Call #3
>>>3
Call #4
>>>4
Call #4
>>>5
Call #5
>>>6
Call #6
>>>7
Call #7
>>>8
Call #7
>>>9
Call #8
>>>10
Call #9
>>>11
Call #10
>>>12
Call #10
>>>13
Call #11
>>>14
Call #11
>>>15
Call #12
>>>16

the value with >>> is printed by the called delegate (updateMoveCount)
but the end result should be 12 (same as “i”) not 16

even more strange… the “sequence” (last line) has the correct # of calls

but I have to use delegate as the GUI is on another view
I could just call the delegate once with with the amount to update by, but I was hoping to show it counting as the sprite moved

only thing that springs to mind is that maybe you get multiple updates in one “duration” ?

cant think of any other way that makes any sense

I thought the same thing, but cannot for the life of me see how it calls the delegate multiple times during one loop of the FOR.

I ended up (for now at least) changing it to this

 //let incMove = SKAction.customAction(withDuration: 0.0, actionBlock:  { (node, elapsedTime) -> () in
        //self.mySokobanDelegate?.updateMoveCount(moveCnt: 1)
        //})

        // band-aid
        self.mySokobanDelegate?.updateMoveCount(moveCnt: p!.count-1)
        //

        for i in(0...p!.count-1) {
            // this counts "wrong" :(      if i>0  { sequence.append(incMove) }

it counts correctly, but updates the count in one chunk

What happens when print() is moved outside the incMove declaration?

moving print removes any information that could impart, and the print isn’t what is causing the delegate to be called an incorrect # of times.

Sorry, this a bit off topic… Seems like you are writing a Sokoban game. I have been thinking about rewriting my old Sokoban game as the 8th programming language now uses Nuklear based GUI and I could also support mobile platforms. It’s my version of the original game written for the Plan 9 and Inferno operating systems. I got permission to use data files from the original author. Do you have a level parser that allows using custom levels?

what I am writing is in Swift, and for macOS, iPhone, iPad and AppleTV. If by “parser” you mean an editor to create custom levels, then yes I have considered that. The problem is “real estate”, since the core device paredighm is the iPhone/iPad. (The macOS version is a by product of the iPad that runs on M1 devices), and navigation on the ATV would make an editor clumsy.

This is a sample screen shot (with a super simple puzzle)


and another with a more complex puzzle

Looks good!

My game can import a simple text file using commonly used Sokoban level format that is easy to parse. As an added bonus there are probably thousands of levels available online that can be used.

; #1
 #####
 #   ####
 #   #  #
 ##    .#
### ###.#
# $ # #.#
# $$# ###
#@  #
#####

; #2
  #######
  #     #
  # $ @ #
##### # #
# $     #
#  #$## ##
#..$  #  #
#..      #
##########