/// <summary> /// Gets all the <see cref="BoardSlot"/>s grouped by row index. /// </summary> public static IDictionary <int, IEnumerable <BoardSlot> > GetBoardSlotRows(this IReadOnlyBoardGrid boardGrid) => Enumerable.Range(1, boardGrid.Rows) .ToDictionary( keySelector: rowIndex => rowIndex, elementSelector: boardGrid.GetBoardSlotsForRow ) ;
/// <summary> /// Prints the board /// </summary> private void PrintBoard(IReadOnlyBoardGrid board, int paddingLeft, bool isDone = false) { var boardSize = board.ToBoardSize(); paddingLeft = ((HeaderSize.Width / 2) - ((boardSize.Width * 7) + 2 + 4) / 2); var columnHeader = String.Join("", Enumerable.Range(1, boardSize.Width).Select(columnIndex => $" {columnIndex:00} ")); Console.WriteLine($"{GeneratePadding(paddingLeft + 4)}{columnHeader}"); Console.WriteLine($"{GeneratePadding(paddingLeft+4)}+{GeneratePadding(boardSize.Width * 7, '+')}+"); foreach (var rowIndex in Enumerable.Range(1, boardSize.Height)) { Console.WriteLine($"{GeneratePadding(paddingLeft+4)}+{RepeatString(boardSize.Width, "+ +")}+"); Console.WriteLine($"{GeneratePadding(paddingLeft)}{rowIndex:00} +{RepeatString(boardSize.Width, "+ +")}+"); Console.WriteLine($"{GeneratePadding(paddingLeft+4)}+{RepeatString(boardSize.Width, "+ +")}+"); Console.WriteLine($"{GeneratePadding(paddingLeft+4)}+{RepeatString(boardSize.Width, "+++++++")}+"); } PrintGameHeader(clearScreen: false); foreach (var boardSlot in board.State.Where(slot => slot.Value != BoardSlotValue.Empty)) { var position = boardSlot.Position; Console.SetCursorPosition(paddingLeft + 4 + (7 * position.Column) - 3, 13 + (4 * (position.Row - 1))); ChangeToColorBasedOnSlotValue(boardSlot.Value); Console.Write("O"); } //if(isDone) //Console.SetCursorPosition(0, 13 + (4 * (board.Rows))); if (!isDone) { return; } ChangeToColor(ConsoleColor.Black); Console.SetCursorPosition(0, 0); }
/// <summary> /// Calculate <see cref="BoardPosition"/>s starting from the column with the column as start and the row as limiter. /// </summary> private static IEnumerable <List <BoardPosition> > GetPositionsTopToBottomRightHalf(IReadOnlyBoardGrid boardGrid) { foreach (var columnIndex in Enumerable.Range(1, boardGrid.Columns)) { var boardPositions = new List <BoardPosition>(); for (var adder = 1; adder <= boardGrid.Rows; adder++) { var calculatedColumn = (columnIndex - 1) + adder; if (calculatedColumn <= boardGrid.Columns) { boardPositions.Add(new BoardPosition( row: adder, column: calculatedColumn) ); } } yield return(boardPositions); } }
/// <summary> /// Gets all the <see cref="BoardSlot"/>-lines from top to bottom. /// </summary> public static IDictionary <int, IEnumerable <BoardSlot> > GetBoardSlotDiagonalTopToBottomLines(this IReadOnlyBoardGrid boardGrid) { var boardPositionsCollection = new List <List <BoardPosition> >() .Concat(GetPositionsTopToBottomLeftHalf(boardGrid)) .Concat(GetPositionsTopToBottomRightHalf(boardGrid)); return(BoardPositionsToBoardSlotDictionary(boardGrid, boardPositionsCollection)); }
/// <summary> /// Gets all the <see cref="BoardSlot"/>s grouped by column index. /// </summary> public static IDictionary <int, IEnumerable <BoardSlot> > GetBoardSlotColumns(this IReadOnlyBoardGrid boardGrid) => Enumerable.Range(1, boardGrid.Columns) .ToDictionary( keySelector: columnIndex => columnIndex, elementSelector: boardGrid.GetBoardSlotsForColumn ) ;
/// <summary> /// Gets the <see cref="BoardSlot"/>s for a given <paramref name="rowIndex"/>. /// </summary> /// <param name="boardGrid">The <see cref="IReadOnlyBoardGrid"/> to get the <see cref="BoardSlot"/> values from.</param> /// <param name="rowIndex">The targetted 1-based row index.</param> /// <returns></returns> public static IEnumerable <BoardSlot> GetBoardSlotsForRow( this IReadOnlyBoardGrid boardGrid, int rowIndex ) => boardGrid .State .Where(slot => slot.Position.Row == rowIndex);
/// <summary> /// Gets the <see cref="BoardSlot"/>s for a given <paramref name="columnIndex"/>. /// </summary> /// <param name="boardGrid">The <see cref="IReadOnlyBoardGrid"/> to get the <see cref="BoardSlot"/> values from.</param> /// <param name="columnIndex">The targetted 1-based column index.</param> /// <returns></returns> public static IEnumerable <BoardSlot> GetBoardSlotsForColumn( this IReadOnlyBoardGrid boardGrid, int columnIndex ) => boardGrid .State .Where(slot => slot.Position.Column == columnIndex);
/// <summary> /// Transfroms a collection of <see cref="BoardPosition"/>s to a dictionary of the concrete <see cref="BoardSlot"/>s from a given <paramref name="boardGrid"/>. /// </summary> private static Dictionary <int, IEnumerable <BoardSlot> > BoardPositionsToBoardSlotDictionary(IReadOnlyBoardGrid boardGrid, IEnumerable <List <BoardPosition> > boardPositionsCollection) { return(boardPositionsCollection .Select(boardPositions => boardPositions .Select(boardPosition => boardGrid.State.SingleOrDefault(slot => slot.Position.Equals(boardPosition))) .Where(slot => slot != null) ) .Select((boardSlots, i) => new { BoardSlots = boardSlots, Index = i }) .ToDictionary( keySelector: kvp => kvp.Index, elementSelector: kvp => kvp.BoardSlots )); }
/// <summary> /// Calculate <see cref="BoardPosition"/>s starting from the column with the column as start and the row as limiter. /// </summary> private static IEnumerable <List <BoardPosition> > GetPositionsBottomToTopRightHalf(IReadOnlyBoardGrid boardGrid) { foreach (var columnIndex in Enumerable.Range(1, boardGrid.Columns)) { var boardPositions = new List <BoardPosition>(); for (var subtractor = 1; subtractor <= boardGrid.Rows; subtractor++) { var calculatedColumn = (columnIndex + 1) - subtractor; if (calculatedColumn <= boardGrid.Columns) { boardPositions.Add(new BoardPosition( row: subtractor, column: calculatedColumn) ); } } yield return(boardPositions); } }
/// <summary> /// Converts a <see cref="IReadOnlyBoardGrid"/> to a <see cref="BoardSize"/>. /// </summary> /// <param name="boardGrid">The <see cref="IReadOnlyBoardGrid"/> to get the <see cref="BoardSize"/> from.</param> public static BoardSize ToBoardSize(this IReadOnlyBoardGrid boardGrid) => new BoardSize(width: boardGrid.Columns, height: boardGrid.Rows);