Bill Spight wrote:msgreg wrote:Samura wrote:Just to add another thing to the discussion.
Today I discovered that there is an algorithm used by computer programs to analyze the status of groups, especially if they are unconditionally alive. It's called Benson's algorithm and one of the necessary conditions is that the ruleset forbid suicides. With suicides the algorithm needs more analyzes and thus more time.
So, with a ruleset that allows suicide, computer programs would have a harder time to find the status of groups.
I've never heard of Benson's algorithm before, but I *just* wrote an algorithm to for playing go that determines when to remove stones. If suicide is allowed, I don't have to keep a memory of "prior to the move". If suicide is allowed, all analysis can occur in the same memory structures used to track the current position.
Algorithm if suicide is allowed
1. Place new stone.
2. Merge Groups attached to new stone.
3. Remove dead groups of opposite color.
4. Remove dead groups of same color.
If suicide is allowed, I have to save off the current state before the analysis.
0. Save current board state
...
5. If current stone has been removed, restore saved state, and indicate invalid move
Now I'm going to look up Benson's algorithm to see if it's the same
Edit: No Benson's Algorithm is not the same, which should have been obvious, given different conclusions on complexity of suicide.
FWIW, you do not have to save the current state. Just don't merge too early.
Any placed stone will be adjacent to at most four strings. Of those strings, remove opponent's strings without liberties. If none of them has been removed, check to see if the placed stone has a liberty. If so merge it with the friendly stones. If not, and any of the adjacent friendly strings has a liberty, merge all of them with the played stone. If none of them has a liberty, remove the placed stone and declare an illegal move.
BTW, when I first wrote a go program, for each string I kept a list for each stone in the string and another list for liberties. Doing so made the question of capture or suicide obvious.
Very good insights, Bill. Thank you!!
In my case, I'm programming for a limited memory device. So I'm trying to reduce the number of size-changing objects such as lists. In my case, I keep an array that is the size of the number of intersections. Each location is a "group number". I also keep a "dead/alive" array indicating which stones are without liberties, regardless of color. This way, a group with all zero-liberty stones is a dead group. A group with any non-zero-liberty stones is an alive group.
Any placed stone will be adjacent to at most four strings. Of those strings, remove opponent's strings without liberties.
This is the statement that's difficult to implement given my data structures. In reality, I think this should read "...remove opponent's strings without liberties (except for the newly placed stone)".
I had thought of "pre-emptive" determination of live/dead groups, but I already had whole-board algorithms that implemented some of the functions I needed to track groups and determine life/death of groups that were fully specified within the data structures.
I'll have to rethink to see if I can implement your algorithm with static arrays rather than dynamic lists.