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>()); }
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); }