/// <summary> /// There are two ways to score. One is based on territory, the other on area. /// This method uses the appropriate counting method according to the used ruleset and players' agreement. /// </summary> /// <param name="currentNode">Node of tree representing the previous move.</param> /// <param name="deadPositions">List of dead stones.</param> /// <param name="komi">Komi compensation.</param> /// <returns>The score of players.</returns> public override Scores CountScore(GameTreeNode currentNode, IEnumerable <Position> deadPositions, float komi) { Scores scores; if (_countingType == CountingType.Area) { scores = CountArea(currentNode, deadPositions); } else { scores = CountTerritory(currentNode, deadPositions); } //passing = 1 bonus point to opponent IEnumerable <GameTreeNode> history = currentNode.GetNodeHistory(); foreach (GameTreeNode node in history) { if (node.Move.Kind == MoveKind.Pass) { if (node.Move.WhoMoves == StoneColor.Black) { scores.WhiteScore++; } else if (node.Move.WhoMoves == StoneColor.White) { scores.BlackScore++; } } } scores.WhiteScore += komi; return(scores); }
/// <summary> /// The territory of a player are those empty points on the board which are entirely surrounded by his live stones. /// This method adds up total territory of players. The scores include prisoners and dead stones. /// </summary> /// <param name="currentNode">Node of tree representing the previous move.</param> /// <param name="deadPositions">Positions marked as dead.</param> /// <returns>The score of players, which does not include number of prisoners and dead stones.</returns> protected Scores CountTerritory(GameTreeNode currentNode, IEnumerable <Position> deadPositions) { Scores scores = new Scores(0, 0); //prisoners IEnumerable <GameTreeNode> history = currentNode.GetNodeHistory(); foreach (GameTreeNode node in history) { if (node.Move.Captures.Count != 0) { if (node.Move.WhoMoves == StoneColor.Black) { scores.WhiteScore -= node.Move.Captures.Count; } else if (node.Move.WhoMoves == StoneColor.White) { scores.BlackScore -= node.Move.Captures.Count; } } } //dead stones foreach (Position position in deadPositions) { if (RulesetInfo.BoardState[position.X, position.Y] == StoneColor.Black) { scores.BlackScore--; } else if (RulesetInfo.BoardState[position.X, position.Y] == StoneColor.White) { scores.WhiteScore--; } } //regions Scores regionScores = GetRegionScores(currentNode, deadPositions); scores.WhiteScore += regionScores.WhiteScore; scores.BlackScore += regionScores.BlackScore; return(scores); }