protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY) { foreach (var bitmap in piece.PossibleOrientations) { for (var y = 0; y <= BoardState.Height - bitmap.Height; y++) { for (var x = 0; x <= BoardState.Width - bitmap.Width; x++) { if (board.CanPlace(bitmap, x, y)) { resultBitmap = bitmap; resultX = x; resultY = y; return(true); } } } } resultBitmap = null; resultX = -1; resultY = -1; return(false); }
protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY) { int smallestSize = BoardState.Height * BoardState.Width + 1; resultBitmap = null; resultX = 0; resultY = 0; //TODO: If we weren't a singleton we could track our used Width/Height int currentHeight = CalcUsedHeight(ref board); int currentWidth = CalcUsedWidth(ref board); //Console.WriteLine($"Current {currentWidth}x{currentHeight}"); for (var x = 0; x < BoardState.Width; x++) { for (var y = 0; y < BoardState.Height; y++) { foreach (var bitmap in piece.PossibleOrientations) { var size = Math.Max(currentWidth, x + bitmap.Width) * Math.Max(currentHeight, y + bitmap.Height); if (size < smallestSize && x + bitmap.Width <= BoardState.Width && y + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, x, y)) { smallestSize = size; resultBitmap = bitmap; resultX = x; resultY = y; } } } } return(resultBitmap != null); }
protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY) { resultBitmap = null; resultX = -1; resultY = -1; int bestLeastHoles = BoardState.Width * BoardState.Height + 1; int bestLargestHole = BoardState.Width * BoardState.Height + 1; int bestDistance = BoardState.Width * BoardState.Height + 1; var holes = new List <int>(); foreach (var bitmap in piece.PossibleOrientations) { //TODO: Try at 0, 0 if (board.CanPlace(bitmap, 0, 0)) { TryPlacement(board, bitmap, 0, 0, ref resultBitmap, ref resultX, ref resultY, ref bestLeastHoles, ref bestLargestHole, ref bestDistance, holes); } for (var x = 0; x <= BoardState.Width - bitmap.Width; x++) { //You can only place in a position if you couldn't place in the previous position, or if you can't place in the next position bool couldPlaceBefore = true; for (var y = 0; y <= BoardState.Height - bitmap.Height; y++) { var canPlaceNow = board.CanPlace(bitmap, x, y); if (!couldPlaceBefore && canPlaceNow) { //Try here TryPlacement(board, bitmap, x, y, ref resultBitmap, ref resultX, ref resultY, ref bestLeastHoles, ref bestLargestHole, ref bestDistance, holes); } if (couldPlaceBefore && !canPlaceNow && y > 0) { //try at previous place // TODO May have already been tried (optimization, record the last tried place?) TryPlacement(board, bitmap, x, y - 1, ref resultBitmap, ref resultX, ref resultY, ref bestLeastHoles, ref bestLargestHole, ref bestDistance, holes); } couldPlaceBefore = canPlaceNow; } } //Do a y then x loop as well for (var y = 0; y <= BoardState.Height - bitmap.Height; y++) { //You can only place in a position if you couldn't place in the previous position, or if you can't place in the next position bool couldPlaceBefore = true; for (var x = 0; x <= BoardState.Width - bitmap.Width; x++) { var canPlaceNow = board.CanPlace(bitmap, x, y); if (!couldPlaceBefore && canPlaceNow) { //Try here //TODO May have already tried this in the x,y loop above TryPlacement(board, bitmap, x, y, ref resultBitmap, ref resultX, ref resultY, ref bestLeastHoles, ref bestLargestHole, ref bestDistance, holes); } if (couldPlaceBefore && !canPlaceNow && x > 0) { //try at previous place // TODO May have already been tried (optimization, record the last tried place?) //TODO May have already tried this in the x,y loop above TryPlacement(board, bitmap, x - 1, y, ref resultBitmap, ref resultX, ref resultY, ref bestLeastHoles, ref bestLargestHole, ref bestDistance, holes); } couldPlaceBefore = canPlaceNow; } } } return(resultBitmap != null); }
protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY) { var holes = new List <int>(); int leastHoles = BoardState.Width * BoardState.Height; int largestHoleSize = 0; resultBitmap = null; resultX = -1; resultY = -1; //TODO: Distance could be < the piece size too for (var distance = 0; distance < BoardState.Width + BoardState.Height; distance++) { //TODO: Min(distance, Width - bitmap.MinSideSize) ? for (var x = 0; x <= distance; x++) { var y = distance - x; foreach (var bitmap in piece.PossibleOrientations) { if (x + bitmap.Width <= BoardState.Width && y + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, x, y)) { var clone = board; clone.Place(bitmap, x, y); holes.Clear(); PlacementHelper.HoleCount(clone, ref holes); //TODO: No Linq if (holes.Count < leastHoles || (holes.Count == leastHoles && holes.Max() > largestHoleSize)) { leastHoles = holes.Count; largestHoleSize = holes.Max(); resultBitmap = bitmap; resultX = x; resultY = y; } } } } if (resultBitmap != null) { return(true); } } return(false); }
protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int x, out int y) { for (var oppositeWallGap = 0; oppositeWallGap < BoardState.Width; oppositeWallGap++) { //TODO: Could use the minimum of the size of the sides of the bitmap in this gap < part to skip some wasteful loops for (var gap = 0; gap < BoardState.Height; gap++) { foreach (var bitmap in piece.PossibleOrientations) { //Try place in x direction if (gap + bitmap.Width <= BoardState.Width && oppositeWallGap + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, gap, oppositeWallGap)) { resultBitmap = bitmap; x = gap; y = oppositeWallGap; return(true); } //Try place in y direction if (oppositeWallGap + bitmap.Width <= BoardState.Width && gap + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, oppositeWallGap, gap)) { resultBitmap = bitmap; x = oppositeWallGap; y = gap; return(true); } } } } resultBitmap = null; x = -1; y = -1; return(false); }