public float Score(FastWorld w, int ownIndex, Util.FillResult fill)
        {
            int maxLength  = 0;
            int sumLength  = 0;
            int otherCount = 0;

            for (int i = 0; i < w.Snakes.Count; ++i)
            {
                if (i == ownIndex)
                {
                    continue;
                }
                if (!w.Snakes[i].Alive)
                {
                    continue;
                }

                sumLength  += w.Snakes[i].Length;
                otherCount += 1;

                if (w.Snakes[i].Length > maxLength)
                {
                    maxLength = w.Snakes[i].Length;
                }
            }

            float averageLength = sumLength / (float)otherCount;

            float interpLength = 0.9f * maxLength + 0.1f * averageLength;

            float deltaAdvantage = w.Snakes[ownIndex].Length - interpLength;

            float deltaMetric      = ScoreDeltaAdvantage(deltaAdvantage);
            float deltaOnEatMetric = ScoreDeltaAdvantage(deltaAdvantage + 1);

            // If food distance metric is 1, want to be exactly as good as eating one
            // fruit. Since food distance metric is always less than 1, ensures that eating
            // is always better than guarding with proximity of 1.
            float foodMetricMultiplier = (deltaOnEatMetric - deltaMetric) * FruitMultiplierFactor;

            float score = deltaMetric + FoodDistanceMetric(w, ownIndex, fill) * foodMetricMultiplier;

            Debug.Assert(!float.IsNaN(score));

            return(score);
        }
        private float FoodDistanceMetric(FastWorld w, int ownIndex, Util.FillResult fill)
        {
            int bestOwnDistance = int.MaxValue;

            foreach (var fruit in w.Fruits)
            {
                var dist = fill.Distances[fruit.Y, fruit.X];

                if (dist <= 0)
                {
                    continue;
                }

                bestOwnDistance = Math.Min(bestOwnDistance, dist);
            }

            if (bestOwnDistance == int.MaxValue)
            {
                return(0);
            }

            return((float)Math.Exp(-FoodDistanceDecay * bestOwnDistance));
        }