Ludii Forum
Problem implementing a rules change in Lielow - Printable Version

+- Ludii Forum (https://ludii.games/forums)
+-- Forum: Problems (https://ludii.games/forums/forumdisplay.php?fid=5)
+--- Forum: Game Problems (https://ludii.games/forums/forumdisplay.php?fid=17)
+--- Thread: Problem implementing a rules change in Lielow (/showthread.php?tid=821)



Problem implementing a rules change in Lielow - Michael - 02-09-2022

We wanted to make it the case that the identity of the king is updated for both players each time any player makes a move. As it is now, it is only updated for the mover after they make a move.

I though it would be as easy as parameterizing the ("UpdateKing") define, because it contains 4 occurrences of the keyword "Mover". I did this, so I could call (and ("UpdateKing" Mover) ("UpdateKing" Next)) where the old version just called ("UpdateKing"). But the result is not at all what I predicted. I also tried (do ("UpdateKing" Mover) next:("UpdateKing" Next)) and ("UpdateKing" Mover (then ("UpdateKing" Next))). Making sure to leave a parameter for the (then)-clause in the last case, of course. But I get different unexpected results.

Here is the relevant define:
Code:
(define "UpdateKing"
    (if
        (= 1
            (count Sites
                in:(forEach
                    (sites Occupied by:#1)
                    if:(=
                        (size Stack at:(site))
                        (max
                            (results
                                from:(sites Occupied by:#1)
                                to:0
                                (size Stack at:(from))
                            )
                        )
                    )
                )
            )
        )
        (forEach Piece
            (if
                (=
                    (size Stack at:(from))
                    (max
                        (results
                            from:(sites Occupied by:#1)
                            to:0
                            (size Stack at:(from))
                        )
                    )
                )
                (set State at:(from) 1)
                (set State at:(from) 0)
            )
            #1
            top:True
        )
        //#2 //with the use of (then)
    )
)
I don't see any other variable whose value depends on whose turn it is, so I don't understand why it doesn't simply work. Any ideas?

I have attached the version with (and ("UpdateKing" Mover) ("UpdateKing" Next)). What happens is that, after move 3, the black piece loses the red ring.


RE: Problem implementing a rules change in Lielow - Michael - 03-03-2022

Ok. Let's start over. I have come to believe that the only correct way of doing this is by using (then). What I want to do is to update both players' kings at the end of each player's turn. An entire turn looks like this:
Code:
            (forEach Piece
                ("Move")
                Mover
                top:True
                (then
                    (do
                        (remove (sites Outer) count:(size Stack at:(last To)))
                        next:("UpdateKing" Mover
                            (then ("UpdateKing" Next))
                        )
                    )
                )
            )
And the most relevant part (as far as I can see) is this:
Code:
("UpdateKing" Mover
    (then ("UpdateKing" Next))
)

This should first go through all stacks of Mover and update which one is king if there is a unique biggest stack, then it should do the same for Next. The actual result seems to be that it simply does not perform the second iteration (over stacks belonging to Next). 

I have attached a trial. On move 17, white captures a black 3-stack which makes it the case that the other 3-stack is uniquely tall among the black stacks. Yet, that stack is not made king. Not until after Black has made a move, that is. How come? What am I missing here?


RE: Problem implementing a rules change in Lielow - Eric Piette - 04-01-2022

Same thing here, I am opening an issue to myself to look at this issue too.


RE: Problem implementing a rules change in Lielow - Michael - 04-20-2022

(03-03-2022, 08:54 AM)Michael Wrote:
Code:
("UpdateKing" Mover
    (then ("UpdateKing" Next))
)

I see I forgot to put the tilde in: ("UpdateKing" Next ~). But it doesn't seem to make a difference.


RE: Problem implementing a rules change in Lielow - dale walton - 05-27-2022

Is it because you are making recursive use of the define?  -- Try taking out the #2 from the define and simply using



(and ("UpdateKing" Mover) ("UpdateKing" Next))


RE: Problem implementing a rules change in Lielow - Michael - 05-27-2022

I think the reason chaining the (then) clauses doesn't work is that the ludeme in the (then) of an (if) is not called if the condition of the (if) evaluates to false..

You suggestion doesn't work either. Neither does (do next:). I'm totally stuck.

(05-27-2022, 10:11 AM)Michael Wrote: I think the reason chaining the (then) clauses doesn't work is that the ludeme in the (then) of an (if) is not called if the condition of the (if) evaluates to false..
No, that doesn't seem to be it. If I put in a (pass) in the the else-clause, the (then)-clause is called in other examples, but it don't fix this. So there must be more too it.


RE: Problem implementing a rules change in Lielow - dale walton - 05-27-2022

If the next:() doesn't evaluate, the do is not performed -- something like the ifAfterwards effect
ForEach Piece is referring only to the mover's pieces. so try:

(and
(forEach Piece
...
("UpdateKing" Mover)
Mover
)

(forEach Piece
...
("UpdateKing" Next)
Next
)
)


RE: Problem implementing a rules change in Lielow - Michael - 05-27-2022

(05-27-2022, 04:27 PM)dale walton Wrote: ForEach Piece is referring only to the mover's pieces. so try:

(and
(forEach Piece
...
("UpdateKing" Mover)
Mover
)

(forEach Piece
...
("UpdateKing" Next)
Next
)
)

Thank you so much for your help, Dale! I'm a bit confused, though.. Either I'm not understanding your suggestion, or you misread the script.

I use (forEach Piece) two places: 
(1) inside the definition of ("UpdateKing") and 
(2) as the outermost ludeme in (play).

In (1) it iterates only over the mover's pieces, but here it does not make sense to put your suggestion.
In (2) it does not iterate only over the mover's pieces, but rather depends on what is put in the place of #1. So in ("UpdateKing" Mover), it should iterate over the mover's pieces, but in ("UpdateKing" Next) it should iterate over the next player's pieces.


RE: Problem implementing a rules change in Lielow - Michael - 05-28-2022

Btw, I'm having what feels like the exact same problem with Lifeline. In the final rules (not implemented in Ludii) one checks for dead enemy groups and removes them if there are any, then one checks for dead friendly groups and remove them if there are any. Seems like this sort of thing is impossible to do..

Edit: Oh, wait. In the case of Lifeline, I think it adding (pass) in the else-clause actually worked..


RE: Problem implementing a rules change in Lielow - dale walton - 05-29-2022

The next:(and ("UpdateKing" Mover) ("UpdateKing" Next)) suggestion should have worked - But after the "next:" maybe it should be next:(or ("UpdateKing" Mover) ("UpdateKing" Next)) instead to allow one to fail? I have often wondered about (or <non-decision moves>) and whether it means and/or in this usage.

I often have problems with this kind of structure, and one thing that might work that I have used is
next:(priority
{
("UpdateKing" Mover
(then ("UpdateKing" Next))
)
("UpdateKing" Mover)
("UpdateKing" Next)
}
)

i.e I construct my own and/or -- if you can't update both then update one or the other...

-- Well usually I uses this for doing something for everything (eg scoring) after something that might fail.

The method of adding in a dummy action that must always occur into your ("UpdateKing" ...) function might also work, but might be unreliable and obscure for debugging... e.g. what if the compiler sees it as redundant and rejects it or strips it out?

I hope I am making sense here.