Ejemplo n.º 1
0
        private static IList <int> FindOpenerMoves(Board board)
        {
            var dimensions = board.Dimensions;

            // The middle of a board is of highest priority.
            // account for a multi cell middle, e.g. width = 4, height = 3 => middle is at (1,1) and (2,1)
            var middleSpan = new CellSpan(1 - dimensions.Width % 2, 1 - dimensions.Height % 2);

            var step = new CellSpan(1, 1);

            for (
                CellCoordinates topLeft = new CellCoordinates(dimensions.Width / 2, dimensions.Height / 2),
                bottomRight = topLeft + middleSpan;
                CellCoordinates.IsInside(topLeft, dimensions) &&
                CellCoordinates.IsInside(bottomRight, dimensions);
                topLeft -= step,
                bottomRight += step)
            {
                var cells = Cells.TakeAnyFreeCellInRect(
                    board,
                    CellCoordinates.ToCellAt(topLeft, dimensions),
                    CellCoordinates.ToCellAt(bottomRight, dimensions));

                // If cells are already occupied, take a cell from the rectangle around the current one,
                if (cells.Length > 0)
                {
                    return(cells);
                }
                // repeat until a free cell is found.
            }

            return(Array.Empty <int>());
        }
Ejemplo n.º 2
0
        private static IList <int> CompleteConsecutiveness(
            Board board,
            IEnumerable <Consecutiveness> incompleteMoves)
        {
            var cells           = board.Cells;
            var boardDimensions = board.Dimensions;

            var moves = new List <int>();

            void collect(CellCoordinates coordinates)
            {
                if (CellCoordinates.IsInside(coordinates, boardDimensions))
                {
                    var cellAt = CellCoordinates.ToCellAt(coordinates, boardDimensions);
                    if (cells[cellAt] == CellOwner.None)
                    {
                        moves.Add(cellAt);
                    }
                }
            }

            var prioritized = incompleteMoves
                              .OrderByDescending(consecutiveness => consecutiveness.CellsAt.Count);

            foreach (var consecutiveness in prioritized)
            {
                // single moves cannot be completed in one turn
                if (consecutiveness.CellsAt.Count < 2)
                {
                    continue;
                }

                var first    = CellCoordinates.FromCellAt(consecutiveness.CellsAt.First(), boardDimensions);
                var second   = CellCoordinates.FromCellAt(consecutiveness.CellsAt.Skip(1).First(), boardDimensions);
                var last     = CellCoordinates.FromCellAt(consecutiveness.CellsAt.Last(), boardDimensions);
                var stepSpan = second - first;
                collect(first - stepSpan);
                collect(last + stepSpan);
            }

            return(moves);
        }