public static OneSidedShape FromListOfPoints(List <Point> points, int n) { int xShift = points.Min(p => p.X); int yShift = points.Min(p => p.Y); var firstShape = points.Select(p => new Point(p.X - xShift, p.Y - yShift)) .OrderBy(p => p.Y).ThenBy(p => p.X).ToArray(); var result = new OneSidedShape(firstShape); var rotatedPoints = firstShape.ToArray(); for (int i = 0; i < 3; i++) { rotatedPoints = rotatedPoints.Select(p => new Point(p.Y, n - 1 - p.X)).ToArray(); var rotatedPointsShiftX = rotatedPoints.Min(p => p.X); var rotatedPointsShiftY = rotatedPoints.Min(p => p.Y); var shapeRotation = rotatedPoints .Select(p => new Point(p.X - rotatedPointsShiftX, p.Y - rotatedPointsShiftY)) .OrderBy(p => p.Y).ThenBy(p => p.X).ToArray(); bool newShapeAdded = false; for (var index = 0; index < firstShape.Length; index++) { if (firstShape[index] != shapeRotation[index]) { result.Add(shapeRotation); newShapeAdded = true; break; } } if (!newShapeAdded) { break; } } return(result); }
public static OneSidedShape GenerateRandomOneSidedShape(int maxSize, CancellationToken cancellationToken) { OneSidedShape result = null; while (result is null) { int startSize = 1; int lastAddedCellNumber = 1; var cellsToCheck = new List <Cell>(); var startingCell = new Cell(maxSize - 1, 0, lastAddedCellNumber); var cellStack = new Stack <Cell>(); cellStack.Push(startingCell); var board = new bool[2 * maxSize - 1, maxSize]; board[startingCell.X, startingCell.Y] = true; result = GenerateRandomBiggerShape(cellStack, cellsToCheck, startSize, maxSize, lastAddedCellNumber, board, cancellationToken); } return(result); }
private static OneSidedShape GenerateRandomBiggerShape(Stack <Cell> cellStack, List <Cell> cellsToCheck, int currentSize, int maxSize, int lastAddedCellNumber, bool[,] board, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (currentSize == maxSize) { var fixedShape = cellStack.Select(c => new Point(c.X, c.Y)).ToList(); return(OneSidedShape.FromListOfPoints(fixedShape, maxSize)); } var currentCell = cellStack.Peek(); List <Cell> adjacentCells = GenerateAdjacentCells(board, currentCell, lastAddedCellNumber, maxSize); cellsToCheck.RemoveAll(c => c.Number < currentCell.Number); cellsToCheck.AddRange(adjacentCells); if (!cellsToCheck.Any()) { return(null); } adjacentCells.ForEach(c => board[c.X, c.Y] = true); var randomCell = cellsToCheck.GetRandomElement(); cellStack.Push(randomCell); return(GenerateRandomBiggerShape(cellStack, cellsToCheck.Where(c => c != randomCell).ToList(), currentSize + 1, maxSize, lastAddedCellNumber + adjacentCells.Count, board, cancellationToken)); }