Ludii Forum
Iterating over groups - 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: Iterating over groups (/showthread.php?tid=187)



Iterating over groups - Michael - 09-23-2020

Is there a way of iterating over groups?

I have made a game where your score is the sum of the values of all your groups, and the value of a group is (n(n+1)/2)-1, where n is the number of a kind of stone in the group.

I'm pretty sure I can do this by iterating over stones and removing a group after I have calculated its value in order not to count the same group over again, but I would like to not have to do it that way.


RE: Iterating over groups - Eric Piette - 09-23-2020

Hi,

No unfortunately not with the current ludemes, this is not possible to iterate over groups.
Something we should consider to add in future releases.

Regards,
Eric Piette


RE: Iterating over groups - Michael - 09-23-2020

Thanks for the reply! I'll try working around it by iterating over pieces and using (set State at:<int> <int>) and (state at:<int>) to make sure I don't count the same group twice.


RE: Iterating over groups - Michael - 09-24-2020

I can't figure out what is wrong with my workaround. Here is what I'm trying:
Code:
(define "CalculateScoreP1"
    (forEach Site
        (sites Occupied by:P1 component:"DoubleCounter")
        (if
            (!= 1 (state at:(site)))
                (and
                    (forEach Site
                        (sites Group at:(site))
                        (set State at:(site) 1)
                    )
                    (addScore P1
                        (/ (* "n1" (+ 1 "n1") ) 2)
                    )
                )
        )
    )
)
Where "n1" is defined like this:
Code:
(define "n1"
    (count Sites in:(intersection (sites Occupied by:P1 component:"DoubleCounter") (sites Group at:(site)) ) )
)

The intended effect is to score P1 the sum of the values of all of their groups, where the value of a group is a function of the number of DoubleCounters it contains. The function is (#ofDoubleCounters * (#ofDoubleCounters + 1)) / 2.

The way I'm thinking that my "CalculateScoreP1" works is this:
It goes through all sites occupied by P1s DoubleCounters and looks if its state is 1. If it is not, it does the following:
First it changes the state of all sites in the group of the site currently under consideration to 1. This should make it the case that the other DoubleCounters in this group does not pass the "is its state 1?"-test when the (forEach)-iteration eventually gets to these sites.
Then it adds to P1s score a number that is a function of the number of DoubleCounters in the group that the one under consideration belongs to. The function is the one I described above.
Because of the change of state this calculation should only be preformed once per group.

It does not work the way I'm envisioning, though. Every DoubleCounter is counted as if it is a singleton, as if a group can't consist of both Counters and DoubleCounters. But this is not what happens with (count Groups). Then the different pieces of the same color is treated as belonging together in groups.  I have attached the relevant game. I would be super grateful for any help with this.

Edit: The attached file contains an unrelated error: When calculating the score of P2 it uses the P1's number ("n1" in stead of "n2").


RE: Iterating over groups - Michael - 09-24-2020

I have now confirmed that (sites Group), as opposed to (count Groups), treats a Counter adjacent to a DoubleCounter as two groups. Is there a way to force (sites Group) to only care about who owns the pieces?


RE: Iterating over groups - Eric Piette - 09-25-2020

Hi Michael,

I modified (sites Group) in one of the previous release to be generic for such cases with a condition thanks to the "if:" parameter but I did not updated the (count Group) in the same way for now.

That's on my TODO list ;)

I will keep you aware when that will be released.

Regards,
Eric Piette


RE: Iterating over groups - Michael - 09-25-2020

(09-25-2020, 07:56 AM)Eric Piette Wrote: I modified (sites Group) in one of the previous release to be generic for such cases with a condition thanks to the "if:" parameter but I did not updated the (count Group) in the same way for now.
I don't think I understand. My issue is specifically with (sites Group) in this case. The "if:" parameter is great, but it only sets a restriction inside the context of a decision the ludeme makes automatically based on the "at:" parameter. If the site given in "at:" is occupied by one of my DoubleCounters it computes a group consisting of only sites occupied by my DoubleCounters. I can't force it to be more generic, so I can't make it compute a group consisting of my pieces, not specifically my DoubleCounters.

It would be great if the generic property that connects the sites in the group (in addition to adjacency) can be set in a paramenter. In that way I could compute a group of sites connected by a chain of adjacencies between sites with "some property" set by me. A group could then (if one sets this optional parameter) cut across sites occupied by different players. An example is a group of all sites connected by a chain of adjacencies between sites whose state is even. Is this the intended effect of "if:"?

Sorry for just throwing out wishes. I understand that you have a lot todo. And I really appreciate your work!