Esempio n. 1
0
        public Tuple<double, int> _Evaluate(Unit unit)
        {
            // Уничтожаемые линии это хорошо
            var dropped = DroppedLines(unit);
            double scoreDropped = Math.Pow(dropped.Count(isDrop => isDrop)-1, 2) + dropped.Select((isDrop, i) => isDrop ? 1.0 +  ((double)i)/map.Height : 0.0).Sum();
            var droppedLines = dropped.Count(isDrop => isDrop);
            // Занимаем полезные клетки - это хорошо
            var usabilities = unit.members.Select(m => UsabilityForCells[m]).ToArray();
            double scoreOccupied = unit.members.Sum(m => UsabilityForCells[m]);
            // Ухудшаем возможность занять полезные клетки - это плохо
            var freeSurroundingCells = GetFreeSurroundingCells(unit);
            Dictionary<Cell, int> newFreeInputCells = freeSurroundingCells.ToDictionary(c => c, c => CountFreeInputs(c, unit));
            double scoreClosed = freeSurroundingCells.Select(c => (newFreeInputCells[c] - freeInputsForCells[c])*UsabilityForCells[c]).Sum();
            // Некомпактность - слишком много свободных клеток вокруг - это плохо
            double scoreCompact = ((double)-freeSurroundingCells.Length)/unit.GetSurroundingCells().Length;
            // Чем ниже тем лучше
            double scorePosHeigh = unit.members.Average(m =>((double)m.y)/map.Height);

            var score = 0.1*scoreDropped +
                        scoreOccupied +
                        0.5*scoreClosed +
                        0.2*scoreCompact +
                        0.1*scorePosHeigh+
                        0;
            return Tuple.Create(score, droppedLines);
        }
Esempio n. 2
0
 public void Test(HashSet<Cell> unitCells, HashSet<Cell> surround)
 {
     Unit unit = new Unit(){members = unitCells, pivot = new Cell(){x=0,y=0}};
     var surrounding = unit.GetSurroundingCells();
     Assert.IsTrue(surround.Count == surrounding.Length);
     foreach (var surroundCell in surrounding)
         Assert.IsTrue(surround.Contains(surroundCell));
 }
Esempio n. 3
0
        public double Evaluate(Unit unit)
        {
            //Ценность занимаемых ячеек
            //Чем меньше остается пустых ячеек в строке - тем лучше
            //Чем меньше в данной стороке "глухих ячек" - тем лучше
            int score = 0;
            int nLinesDropped = 0;
            int[] occupied = new int[map.Height];
            foreach (var occupiedCellsInLine in unit.members.GroupBy(m => m.y))
            {
                var y = occupiedCellsInLine.Key;
                occupied[y] = occupiedCellsInLine.Count();
                var newEmptyCells = emptyCells[y].Except(occupiedCellsInLine);
                int nEmpty = 0, nBlocked = 0;
                foreach (var c in newEmptyCells)
                    if (CountFreeInputs(c, unit) == 0) nBlocked++;
                    else nEmpty++;
                int lineScore = (int) (map.Width - nEmpty - nBlocked)*occupied[y];
                if (nEmpty + nBlocked == 0) nLinesDropped++;
                if (lineScore > 0) score += lineScore;
            }
            score += map.Width*nLinesDropped*(nLinesDropped+1);

            // Насколько хорошая позиция юнита
            // Если рядом стена или заполненная ячейка - отлично
            // Если рядом пустая ячейка, то ее ценность - сколько у нее входов
            int surroundingScore = 0;
            foreach (var surroundingCellsInLine in unit.GetSurroundingCells().GroupBy(c => c.y))
            {
                foreach (var cell in surroundingCellsInLine)
                {

                var cellScore = 0;
                if (!IsCorrect(cell) || map[cell].filled) cellScore= 10;
                else cellScore =  4*CountFreeInputs(cell, unit);
                    if (cellScore == 0) cellScore= -(map.Width - emptyCells[cell.y].Length + occupied[cell.y] + (map.Width - emptyCells[cell.y].Length - blockedCells[cell.y] + occupied[cell.y] > map.Width*3/4 ? 10 : 0));
                surroundingScore += cellScore;

                }
            }

            // Не находится ли юнит рядом с входом
            int posScore = 0;
            if (unit.members.Any(cell =>
                (Math.Abs(cell.x - map.Width/2) < 3 && cell.y < 3)))
                if (nLinesDropped == 0) posScore = -2*map.Width;

            score = score + surroundingScore + posScore;
            return score;
        }
Esempio n. 4
0
 private int[] CountFreeInputsForSurroundingPoints(Unit unit)
 {
     List<int> countOfInputs = new List<int>();
     foreach (var cell in unit.GetSurroundingCells())
         if (cell.x < 0 || cell.y < 0 || cell.x >= map.Width || cell.y >= map.Height) continue;
         else if (map[cell].filled) continue;
         else
         {
             int nfree = 0;
             foreach (var move in up)
             {
                 var c = cell.Move(move);
                 if (c.x < 0 || c.y < 0 || c.x >= map.Width || c.y >= map.Height) continue;
                 if (!map[c].filled && !unit.members.Contains(c)) nfree++;
             }
             countOfInputs.Add(nfree);
         }
     return countOfInputs.ToArray();
 }
Esempio n. 5
0
 private Cell[] GetFreeSurroundingCells(Unit unit)
 {
     return unit.GetSurroundingCells().Where(c => freeInputsForCells.ContainsKey(c)).ToArray();
 }