# How to code Capturing in "Go" Board Game?

By following this series of N3k EN checkers tutorials, I was able to adapt the process to my own 3d models from Blender to code the board game Go instead.

I have it so you can place pieces and take turns but what is giving me the most trouble is coding capturing. So far it works for capturing single pieces, but it can't capture groups of pieces. When a piece is surrounded left right above and below by any color piece it is captured when it should be only if it is surrounded by an opposite color piece it is captured.

I have two classes Stone and Board. Here is my code inside the Stone class for the function that counts single-stone liberties, and attempts to count groups of stone liberties but undercounts the number of stones and also leads to incorrect captures.

The board is a 2x2 array of stones, and the int x and int y specify the position on the board (0 to 18)

public int numLiberties(Stone[,] board, int x, int y)
{
//Created variable so it is easier to debug, can see position in inspector.
xCoordinate = x;
yCoordinate = y;
Liberties = 0;

bool countNeighbor = false;
List<Stone> countedSpaces = new List<Stone>();
List<Stone> countedStones = new List<Stone>();
List<Stone> countMe = new List<Stone>();

//Check if stone has same-colour orthogonal neighbors, then you have to check liberties for all connected stones.
//WIP Code seems like it should work, but gives incorrect liberty counts (usually seems to not be counting all the spaces it should resulting in fewer liberties than it should have

for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (i == 0 && j == 0) { continue; }
if (i == -1 && j == -1) { continue; }
if (i == -1 && j == 1) { continue; }
if (i == 1 && j == -1) { continue; }
if (i == 1 && j == 1) { continue; }

int neighborX = x + i;
int neighborY = y + j;

//Don't count out of bounds spaces
if (neighborX < 0 || neighborY < 0 || neighborX > 18 || neighborY > 18) { continue; }

if (board[neighborX, neighborY] == null)
{
Liberties++;
}
else if (board[neighborX, neighborY].isBlack == isBlack)
{
countNeighbor = true;
}

//We want to iterate through all the positions of an adjacent stone of the same colour after we have checked all positions next to the current stone.
if (countNeighbor && i == 0 && j == 1)
{
foreach(Stone pos in countMe)
{
if (countedStones.Contains(pos))
{
continue;
}
// Liberties += pos.numLiberties(board, x, y, countedSpaces, countedStones, countMe, Liberties);
}
}

}
}

DebugLiberties(x, y);
//object[] toReturn = [Liberties, preSearchedPositions, countedStones];

return Liberties;
}


I also created this function that tells me what the game thinks each stone has for liberties:

private void DebugLiberties(int x, int y)
{
if (isBlack)
{
Debug.Log("Black. Coordinates: " + "(" + x + "," + y + "). " + "Number of liberties: " + Liberties + ".");
}
else
{
Debug.Log("White. Coordinates: " + "(" + x + "," + y + "). " + "Number of liberties: " + Liberties + ".");
}
}


I tried creating an overloaded method that takes multiple lists of stones but it doesn't seem to work and also it is hard for me to track and understand what it does. So for now I will just leave my question like this.

Finally here is what the function in class Board that calls the numLiberties function looks like, which has some comments on what I think I should do. If possible though I would like to avoid having to use a recursive solution.

private Stone[] ScanForCaptures()
{
capturedStones = new List<Stone>();
int numLiberties;

//Determine all groups of stones. If you move orthogonally through every stone recursively, not going to previous spaces you will get to all the edges. Problem right here, not sure how to do.

//Check edges of each group for null spaces

//Iterate through array of all groups, determine if group is captured or not, and if so add all stones in group to capturedStones list

//Check all the pieces
for (int i = 0; i < 19; i++)
for (int j = 0; j < 19; j++)
if(stones[i,j] != null)
{

numLiberties = stones[i, j].numLiberties(stones, i, j);
if (numLiberties == 0) { capturedStones.Add(stones[i, j]); }
}

Stone[] captures = capturedStones.ToArray();
return captures;
}


I am thinking that I need some type of object like a 2x2 array or a list of positions that can store multiple groups of stones, and then I need an algorithm that counts every space adjacent to all stones in the group without double counting. This is the main part that is tricky for me. Can you please help me figure out what algorithm and data structure I need for this, and how to implement it? Thank you.

• As you've seen, <pre> doesn't mix well with <; you could add escapes to the problematic characters, but it's generally easier to use triple back ticks (aka code fences) instead (plus that also adds nice syntax highlighting). More info on code formatting can be found [here]gamedev.stackexchange.com/editing-help#code) (you might need to click the 'show more' to see the section about code fences). Commented Jul 21 at 19:42
• An easy check would be to check if next to every enemy stone is one of your own. If there is one empty spot, you didn't capture the group. Commented Jul 21 at 19:50
• My "point controls" are all linked up to their immediate neighbours (Lists). Even the "boundary points" are given (virtual) out of bounds points to make the model complete. In this way, I can ask any point if there are vacancies (beside it). Which "neighbours" are friendly and which are not. Is it a boundary point. What is the "liberty" count. These points are "weighted" in the process in order to help make plays. I'm also tracking the "groups". Commented Jul 22 at 19:40