Ludii Forum
need to end multi-hop on capture - Printable Version

+- Ludii Forum (https://ludii.games/forums)
+-- Forum: Questions (https://ludii.games/forums/forumdisplay.php?fid=13)
+--- Forum: About the Ludii Grammar (https://ludii.games/forums/forumdisplay.php?fid=15)
+--- Thread: need to end multi-hop on capture (/showthread.php?tid=748)



need to end multi-hop on capture - sharmoni - 11-09-2021

I want to prevent moveAgain being available if a capture occurs during a multi-hop move sequence. What is the correct syntax to check if a capture happened after a move?

functioning code:
Code:
(define "ColumnMoveAgainAfterJumping" (and (moveAgain) (set Pending)) )

syntax error code:
Code:
(define "ColumnMoveAgainAfterJumping" 
    (or
        (is Enemy (who at:(to)))             <-- this is the error line
        (and (moveAgain) (set Pending))
  )
)

I'm trying to check for a capture after the (to part of a hop move. The capture/piece removal seems to be happening automatically (maybe a default?) so at that point in the code I'm not sure there is even an enemy piece to check.
Code:
("ColumnHopSequence" (from) "OnAFriend" "ColumnMoveAgainAfterJumping")

(define "ColumnHop"
    (move
        Hop
        (from #1)
        #2
        (to if:(and "EmptyOrEnemyOccupied" (not (is Visited (to)))))
        #3
    )
)

(define "ColumnHopSequence"
    ("ColumnHop"
        #1
        #2
        (then
            (if
                (can Move ("ColumnHop" (last To) #2))
                #3 
            )
        )
    )
)

This code is modified from Camelot.lud


RE: need to end multi-hop on capture - sharmoni - 11-12-2021

I was able to get rid of my syntax error by moving my conditional to the "ColumnHopSequence" define. So now the if statement that sets whether another hop can occur requires that no capture happened:
Code:
(define "ColumnHopSequence"
    ("ColumnHop"
        #1
        #2
        (then
            (if
                (and
                    (can Move ("ColumnHop" (last To) #2))
                    (not (is Enemy (who at:(last From))))
                )
                #3 
            )
        )
    )
)

Unfortunately this has no effect, I think because the enemy piece has already been removed by default. I believe it might work if I can change the remove to happen at:EndOfTurn, but I don't know where to do that since there is no explicit remove.

I tried using at:EndOfTurn in my capture define for Slide and it removed the player piece—which I guess means the enemy piece was already gone, or it removed every piece on the (to).
Code:
(define "CaptureToPiece"      
    if:(and
        (is Enemy (who at:(to)))
        (not (is In (to) ("EnemyBase")))
    )
    (apply (remove (to) at:EndOfTurn))
)

The define works without that apply line, so I guess I need a global meta setting to override the automatic "landing on an enemy piece applies immediate removal of that piece" and change it to "leave captured piece in place so it can be checked, then remove at end of turn".

Am I right, or have I simply written the code wrong?


RE: need to end multi-hop on capture - sharmoni - 11-13-2021

Problem solved!

I took another look at the "CaptureToPieceAndResetCounter" from Chess.lud and realized I could use Counter as a flag:
Code:
(define "CaptureToPieceAndResetCounter"
    (apply
        (if ("EnemyCanBeCaptured")
            (remove
                (to)
                (then (set Counter))
            )
        )
    )
)

I added the define to "ColumnHop":
Code:
(define "ColumnHop"
    (move
        Hop
        (from #1)
        #2
        (to if:(and
                "EmptyOrEnemyOccupied"
                (not (is Visited (to)))
            )
            "CaptureToPieceAndResetCounter"
        )
        #3
    )
)

So I now have a define to check for capture:
Code:
(define "DidNotCapture" (!= (counter) -1))

And I can use it in the "ColumnHopSequence" to make #3 null (that avoids moveAgain and stops the hop sequence):
Code:
(define "ColumnHopSequence"
    ("ColumnHop"
        #1
        #2
        (then
            (if
                (and
                    "DidNotCapture"
                    (can Move ("ColumnHop" (last To) #2))
                )
                #3 
            )
        )
    )
)

It seems to work, and the only unintended consequence I've found so far is not allowing multiple hops for the Column on the first move of a game. Since multiple hops for the Column on first game move can only occur in Sandbox and not in legal game play, it's an acceptable solution.