protected override float ScoreDetail(CachedMetricState state)
 {
     return(0.7f * totalFillAdvantage.ScoreCached(state)
            + 10.0f * hungerPressureAdvantage.ScoreCached(state)
            + 4.0f * adversarialFillAdvantage.ScoreCached(state)
            + 4.0f * combinedLengthAdvantage.ScoreCached(state));
 }
        private float FoodDistanceMetric(CachedMetricState state)
        {
            var floodBoard = state.OwnFill;

            int bestOwnDistance = int.MaxValue;

            foreach (var fruit in state.World.Fruits)
            {
                var dist = floodBoard.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));
        }
        public float ScoreCached(CachedMetricState state)
        {
            float deltaAdvantage = state.OwnSnake.Length - state.EnemySnake.Length;

            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 is always less than 1, ensures that eating
            // is always better than guarding with proximity of 1.
            float foodMetricMultiplier = deltaOnEatMetric - deltaMetric;

            return(deltaMetric + FoodDistanceMetric(state) * foodMetricMultiplier);
        }
        public float ScoreCached(CachedMetricState state)
        {
            var floodBoard = state.AdversarialFill.Tiles;

            int bestOwnDistance   = int.MaxValue;
            int bestEnemyDistance = int.MaxValue;

            foreach (var fruit in state.World.Fruits)
            {
                ref var tile = ref floodBoard[fruit.Y, fruit.X];
                if (tile.Snake == state.OwnIndex)
                {
                    bestOwnDistance = Math.Min(bestOwnDistance, tile.Distance);
                }
                else if (tile.Snake == state.EnemyIndex)
                {
                    bestEnemyDistance = Math.Min(bestEnemyDistance, tile.Distance);
                }
            }
        public float ScoreCached(CachedMetricState state)
        {
            var floodBoard = state.AdversarialFill.Tiles;

            int friendlyCounter = 0;
            int enemyCounter    = 0;

            for (int i = 0; i < floodBoard.GetLength(0); ++i)
            {
                for (int j = 0; j < floodBoard.GetLength(1); ++j)
                {
                    if (floodBoard[i, j].Snake == state.OwnIndex)
                    {
                        friendlyCounter++;
                    }
                    else if (floodBoard[i, j].Snake == state.EnemyIndex)
                    {
                        enemyCounter++;
                    }
                }
            }

            return((((float)friendlyCounter / (enemyCounter + friendlyCounter)) - 0.5f) * 2.0f);
        }
        public float Score(FastWorld state)
        {
            var me    = state.Snakes[snakeIndex];
            var enemy = state.Snakes[enemyIndex];

            // 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 && !enemy.Alive)
            {
                return(-900.0f + state.Turn / 100.0f);
            }
            if (!me.Alive)
            {
                return(-1000.0f + state.Turn / 100.0f - ScoreKillReason(me.Status));
            }
            if (!enemy.Alive)
            {
                return(1000.0f - state.Turn / 100.0f);
            }

            var cache = new CachedMetricState(state, snakeIndex, enemyIndex);

            return(ScoreDetail(cache));
        }
Example #7
0
 public float ScoreCached(CachedMetricState state)
 {
     return((state.OwnFill.Count / ((float)state.OwnFill.Count + state.EnemyFill.Count) - 0.5f) * 2.0f);
 }
 protected abstract float ScoreDetail(CachedMetricState state);