public float Score(CachedMultiMetricState state, int index)
        {
            var me = state.World.Snakes[index];

            float score = 0.0f;

            if (!state.World.Snakes[BountySnake].Alive && index != BountySnake)
            {
                // Be really pessimistic everybody hates us
                score += 2000.0f;
            }

            // Try to win as early as possible and lose or draw as late as possible
            // Also try to prefer death reasons which are not completely deterministic
            if (!me.Alive)
            {
                return(score - 1000.0f + state.World.Turn / 100.0f - BaseDuellingHeuristic.ScoreKillReason(me.Status));
            }
            else if (IsTerminal(state))
            {
                // High score if we are the sole survivor, try to win earlier
                return(score + 1000.0f - state.World.Turn / 100.0f);
            }

            // Else evaluate detailed heuristic if no terminal
            return(ScoreDetail(state, index));
        }
        public float ScoreCached(CachedMultiMetricState state, int ownIndex)
        {
            var  self             = state.World.Snakes[ownIndex];
            bool ownTailReachable = state.AdversarialFill.Tiles[self.Tail.Y, self.Tail.X].Snake == ownIndex;

            if (!ownTailReachable)
            {
                bool sufficientSpace = state.AdversarialFill.EmptyCounts[ownIndex] > self.MaxLength;
                return(sufficientSpace ? 1.0f : -1.0f);
            }
            else
            {
                return(1.0f);
            }
        }
        public float Score(CachedMultiMetricState s, int index)
        {
            if (s.World.Snakes[index].Health > SatisfactionThreshold)
            {
                return(1.0f);
            }

            int bestOwnDistance = int.MaxValue;

            foreach (var fruit in s.World.Fruits)
            {
                ref var tile = ref s.AdversarialFill.Tiles[fruit.Y, fruit.X];
                if (tile.Snake == index)
                {
                    bestOwnDistance = Math.Min(bestOwnDistance, tile.Distance);
                }
            }
Beispiel #4
0
        protected override float ScoreDetail(CachedMultiMetricState state, int index)
        {
            var me = state.World.Snakes[index];

            float score = 0.0f;

            var fill = Util.CountBasicFloodFill(state.World, me.Head);

            var deltaLengthScore  = 12.0f * deltaLengthFoodMetric.Score(state.World, index, fill);
            var controlScore      = 1.0f * controlMetric.Score(state, index);
            var hungerScore       = 10.0f * hungerPressureMetric.Score(state, index);
            var distanceTailScore = TailScoreMultiplier * distanceToOwnTailMetric.ScoreCached(state, index);

            score += deltaLengthScore
                     + controlScore
                     + hungerScore
                     + (me.MaxLength > 6 ? distanceTailScore : 0.0f);

            return(score);
        }
Beispiel #5
0
        public float Score(CachedMultiMetricState s, int index)
        {
            var adversarialFill = s.AdversarialFill.EmptyCounts;

            int friendlyCounter = adversarialFill[index];
            int sum             = 0;

            for (int i = 0; i < adversarialFill.Count; ++i)
            {
                sum += adversarialFill[i];
            }

            if (sum == 0)
            {
                return(0.0f);
            }

            float score = ((friendlyCounter / (float)sum) - 0.5f) * 2.0f;

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

            return(score);
        }
 protected abstract float ScoreDetail(CachedMultiMetricState state, int index);
 public bool IsTerminal(CachedMultiMetricState state)
 {
     return(state.World.IsDecided || !state.World.Snakes[BountySnake].Alive);
 }