/// <summary>
 /// Calculate the mobility score for all amazons on the PieceGrid
 /// </summary>
 /// <param name="pieceGrid">PieceGrid to analyze</param>
 private void CalculateAllAmazonMobility(PieceGrid pieceGrid)
 {
     AmazonMobilityScores.Clear();
     foreach (Point p in pieceGrid.Amazon1Points)
     {
         AmazonMobilityScores.Add(p, CalculateAmazonMobility(p, Owner.Player1, pieceGrid));
     }
     foreach (Point p in pieceGrid.Amazon2Points)
     {
         AmazonMobilityScores.Add(p, CalculateAmazonMobility(p, Owner.Player2, pieceGrid));
     }
 }
        private void FloodFillMinDistancesQueen(Point point, PieceGrid pieceGrid, PointSquareArray <double?> result)
        {
            ISet <Point>            visited = new HashSet <Point>();
            Queue <(Point, double)> toVisit = new Queue <(Point, double)>();

            foreach (Point p in pieceGrid.GetOpenPointsOutFrom(point))
            {
                toVisit.Enqueue((p, 1));
            }

            while (toVisit.Any())
            {
                (Point, double)p = toVisit.Dequeue();
                if (visited.Contains(p.Item1))
                {
                    continue;
                }
                if (result[p.Item1].HasValue)
                {
                    result[p.Item1] = Math.Min(p.Item2, result[p.Item1].Value);
                }
                else
                {
                    result.Add(p.Item1, p.Item2);
                }
                visited.Add(p.Item1);
                foreach (Point pNext in pieceGrid.GetOpenPointsOutFrom(p.Item1)
                         .Where(adj => !visited.Contains(adj)))
                {
                    toVisit.Enqueue((pNext, p.Item2 + 1));
                }
            }
        }
        private void FloodFillMinDistancesKing(Point point, PieceGrid pieceGrid, PointSquareArray <double?> result)
        {
            ISet <Point>            visited = new HashSet <Point>();
            Queue <(Point, double)> toVisit = new Queue <(Point, double)>();

            foreach (Point p in point.GetAdjacentPoints().Where(adj => !pieceGrid.IsOutOfBounds(adj) &&
                                                                !pieceGrid.PointPieces[adj].Impassible))
            {
                toVisit.Enqueue((p, 1));
            }

            while (toVisit.Any())
            {
                (Point, double)p = toVisit.Dequeue();
                if (visited.Contains(p.Item1))
                {
                    continue;
                }
                if (result[p.Item1].HasValue)
                {
                    result[p.Item1] = Math.Min(p.Item2, result[p.Item1].Value);
                }
                else
                {
                    result.Add(p.Item1, p.Item2);
                }
                if (SpecificKingDistances[point] == null)
                {
                    SpecificKingDistances.Add(point, new PointSquareArray <double>(pieceGrid.Size));
                }
                SpecificKingDistances[point].Add(p.Item1, p.Item2);
                visited.Add(p.Item1);
                foreach (Point pNext in p.Item1.GetAdjacentPoints()
                         .Where(adj => !pieceGrid.IsOutOfBounds(adj) &&
                                !pieceGrid.PointPieces[adj].Impassible &&
                                !visited.Contains(adj)))
                {
                    toVisit.Enqueue((pNext, p.Item2 + 1));
                }
            }
        }