// Returns true if placing a stone with color color on point coord is legal private bool LegalMove(Coord coord, State color, State opponent) { HashSet <Coord> neighbours = GetNeighbours(coord); if (_gridStones[coord.Column, coord.Row] != State.None) // there is a stone placed { return(false); } if (GetColoredNeighbour(neighbours, State.None).Count != 0) { return(true); } foreach (Coord n in GetColoredNeighbour(neighbours, color)) { AbGroup g = _groups[_gridGroups[n.Column, n.Row]]; // If the stone connects to a stone with 2 or more liberties It will not be captured. if (g.GetLiberties().Count > 1) { return(true); } } foreach (Coord n in GetColoredNeighbour(neighbours, opponent)) { AbGroup g = _groups[_gridGroups[n.Column, n.Row]]; // If any opponent group has one liberty that group is captured and the move is Legal, as it now has a liberty. if (g.GetLiberties().Count == 1) { return(true); } } return(false); }
// Remove all groups that are marked dead public override void DeleteDead() { foreach (int groupId in _markedGroups) { AbGroup groupToDelete = _groups[groupId]; State opponentColor = groupToDelete.GetColor(); switch (opponentColor) { case State.Black: Capture(groupToDelete, State.White); break; case State.White: Capture(groupToDelete, State.Black); break; case State.None: break; default: throw new ArgumentOutOfRangeException(); } } _markedGroups.RemoveWhere(c => _markedGroups.Contains(c)); }
/** * This method will remove a captured group * Each stone in the group is removed from the board and added as a liberty for all other groups */ private void Capture(AbGroup capturedGroup, State color) { foreach (Coord coord in capturedGroup.GetStones()) { // Update the board and add the capture _gridStones[coord.Column, coord.Row] = State.None; _gridGroups[coord.Column, coord.Row] = 0; switch (color) { case State.Black: _capBlack++; break; case State.White: _capWhite++; break; case State.None: break; default: throw new ArgumentOutOfRangeException(nameof(color), color, null); } // Update all groups liberties/adjacent data foreach (Group g in _groups.Values) { g.RemoveStone(coord); } } // Remove the group from the board DeleteGroup(capturedGroup); }
public override void MergeGroup(AbGroup slaveGroup) { _stones.UnionWith(slaveGroup.GetStones()); _liberties.UnionWith(slaveGroup.GetLiberties()); _adjacent.UnionWith(slaveGroup.GetAdjacent()); foreach (Coord coord in _stones) { _liberties.RemoveWhere(c => c.Row == coord.Row && c.Column == coord.Column); } }
// This method updates the group grid, consuming all stones in the SlaveGroup to the MAsterGroup private void MergeGroupGrid(AbGroup masterGroup, AbGroup slaveGroup) { for (var i = 0; i < _size; i++) { for (var j = 0; j < _size; j++) { if (_gridGroups[i, j] == slaveGroup.GetId()) { _gridGroups[i, j] = masterGroup.GetId(); } } } }
/** * This method Updates the state of the board with the addition of the new stone */ private void UpdateBoard(Coord coord, State color, State opponent) { _gridStones[coord.Column, coord.Row] = color; //Place the stone HashSet <Coord> neigh = GetNeighbours(coord); // Get the neighboouring coords. var g = new Group(GetNextGroupId(), coord, color, GetColoredNeighbour(neigh, State.None), GetColoredNeighbour(neigh, opponent)); //Create the group _groups.Add(g.GetId(), g); // Add the group to the board _gridGroups[coord.Column, coord.Row] = g.GetId(); //Add group to grid foreach (Coord pos in neigh) //Merge adjacent groups of same color into this group. { int groupId = _gridGroups[pos.Column, pos.Row]; if (!_groups.ContainsKey(groupId) || groupId == g.GetId()) // If there is no group of the ID do nothing { continue; } AbGroup ng = _groups[_gridGroups[pos.Column, pos.Row]]; if (ng?.GetColor() == color) // If the group is of the same collor merge the groups { MergeGroupGrid(g, ng); MergeGroup(g, ng); g.AddStone(coord); } else if (ng?.GetColor() == opponent) // If the gorup is of the opponent { ng.AddStone(coord); if (ng.GetLiberties().Count == 0) // If we removed the last liberty capture the group { Capture(ng, color); } } } // These methods prints the board and some debugg information in the output. WriteGroupBoard(); WriteGroupLiberties(); }
// Consumes the argument group into this group public abstract void MergeGroup(AbGroup group);
// Removes the group from the Board private void DeleteGroup(AbGroup group) { _groups.Remove(group.GetId()); }
/** * This method merges group1 with group2 * All stones and liberties from group2 will be added to group1 * Group 2 will be deleted. */ private void MergeGroup(AbGroup group1, AbGroup group2) { group1.MergeGroup(group2); DeleteGroup(group2); }