// Place piece on the board and handle board state management private void PlacePiece(GoStone piece, Vector2 pointGrid) { int point_x = (int)pointGrid.x; int point_y = (int)pointGrid.y; GoPoint point_center = gridPoints[point_x, point_y]; GoColor color_attacker = piece.Color; GoColor color_enemy = (color_attacker == GoColor.GC_Black ? GoColor.GC_White : GoColor.GC_Black); // Place GoPiece GameObject in the GoPoint point_center.SetPiece(piece); //// Decrement neighboring point's empty count //UpdateAdjacentEmptySpaces(pointGrid, (color_attacker == GoColor.GC_Black)); // Check if we have captured any enemy pieces (Up/Down/Left/Right Queue <Vector2> queue_adjacents = new Queue <Vector2>(); List <Vector2> list_adj = GetAdjacentPoints(pointGrid); foreach (Vector2 point_adj in list_adj) { queue_adjacents.Enqueue(point_adj); } int count_captured = 0; while (queue_adjacents.Count > 0) { // Retrieve Vector2 Vector2 vec_curr = queue_adjacents.Dequeue(); // Check if valid if (IsValidPoint(vec_curr)) { // Retrieve GoPoint GoPoint point_curr = gridPoints[(int)vec_curr.x, (int)vec_curr.y]; // Check if valid, if enemy color if (!point_curr.IsEmpty() && point_curr.GetStone().Color == color_enemy) { // If so, check if surrounded. if (IsGroupCaptured(vec_curr, color_enemy)) { // If so, remove group and report score to GoStateManager count_captured += TryCaptureGroup(vec_curr, color_enemy); } } } } // Report captured stones if (count_captured > 0) { gameStateManager.OnStonesCaptured(color_attacker, count_captured); } }
// Retrieve immediately adjacent liberties for a given point. // Allied adjacent stones do NOT count as liberties. // @param point Point on the board to check for liberties // @return # of empy adjacent spaces public int GetLibertiesAdjacent(Vector2 point) { // Return -1 if invalid point if (!IsValidPoint(point)) { return(-1); } // Otherwise, count # of empty adjacent points int count_liberties = 0; List <Vector2> list_adj = GetAdjacentPoints(point); foreach (Vector2 point_adj in list_adj) { GoPoint gp_adj = gridPoints[(int)point_adj.x, (int)point_adj.y]; if (gp_adj.IsEmpty()) { count_liberties++; } } return(count_liberties); }
// @param listExcludes List of board Points that will not be checkable. Used to simulate empty spaces actually having enemy Stones within public bool IsGroupCaptured(Vector2 point, GoColor groupColor, List <Vector2> listExcludes) { // Check: Bounds if (!IsValidPoint(point)) { return(false); } int x_start = (int)point.x; int y_start = (int)point.y; // Create hash to store all points that have been checked HashSet <GoPoint> hash_group = new HashSet <GoPoint>(); // Create queue to store list of points that need to be checked Queue <GoPoint> queue_points = new Queue <GoPoint>(); // Insert excluded points into our HashSet foreach (Vector2 point_exclude in listExcludes) { if (IsValidPoint(point_exclude)) { hash_group.Add(gridPoints[(int)point_exclude.x, (int)point_exclude.y]); } } int x_curr = x_start; int y_curr = y_start; GoPoint point_curr = gridPoints[x_curr, y_curr]; bool b_first = true; // We don't want to check the Point/Stone at the initial position; so we can check even if no Stone is placed yet while (b_first || queue_points.Count > 0) { bool b_allied_piece = (b_first || false); // Check current point's Stone (or lack thereof) if (!b_first) { // Retrieve next point point_curr = queue_points.Dequeue(); x_curr = (int)point_curr.PointBoard.x; y_curr = (int)point_curr.PointBoard.y; // Only proceed if we haven't seen this point yet if (!hash_group.Contains(point_curr)) { // If we don't find a stone, then there is at least one open space and the group is not captured if (point_curr.IsEmpty()) { return(false); } // Next, check if we have found an enemy Stone. If so, we don't want to check adjacent spaces if (point_curr.GetStone().Color == groupColor) { b_allied_piece = true; } } } // We only want to skip the checks for our initial point b_first = false; // Retrieve adjacent points if allied if (b_allied_piece) { List <Vector2> list_adj = GetAdjacentPoints(point_curr.PointBoard); foreach (Vector2 point_adj in list_adj) { queue_points.Enqueue(gridPoints[(int)point_adj.x, (int)point_adj.y]); } } // Mark GoPoint as checked hash_group.Add(point_curr); } // If we run out of points to check without having found an empty spot, this group is captured return(true); }