public IEnumerable<LayoutInstance> Scan(PuzzleBoard board) { var result = new List<LayoutInstance>(); if (board.Dimensions.Y < 1) return result; int numFreeBlocks = 2 * board.Dimensions.X; foreach (LayoutDescription desc in layouts) { int layoutWidth = desc.Bottom.Length; int layoutHeight = string.IsNullOrEmpty(desc.Top) ? 1 : 2; if (layoutWidth > board.Dimensions.X) continue; for (int y = ((layoutHeight == 1) ? 0 : 1); y >= layoutHeight - 1; y--) { for (int x = 0; x <= board.Dimensions.X - layoutWidth; x += 2) { if (MatchLayout(board, desc, x, board.Dimensions.Y - 1 - y)) { var instance = new LayoutInstance(desc, new Point(x, board.Dimensions.Y - 1 - y)); result.Add(instance); ClearLayout(board, desc, x, board.Dimensions.Y - 1 - y); x += layoutWidth; numFreeBlocks -= layoutWidth * layoutHeight; if (numFreeBlocks <= 0) return result; } } } } return result; }
protected bool MatchLayout(PuzzleBoard board, LayoutDescription desc, int startX, int startY) { int layoutWidth = desc.Bottom.Length; int layoutHeight = (string.IsNullOrEmpty(desc.Top) ? 1 : 2); string pattern = desc.Top + desc.Bottom; int i = 0; for (int y = startY; y < startY + layoutHeight; y++) for (int x = startX; x < startX + layoutWidth; x++) { if (board.Blocks[x, y] != CharToBlock(pattern[i++])) return false; } return true; }
private void ClearLayout(PuzzleBoard board, LayoutDescription desc, int startX, int startY) { int layoutWidth = desc.Bottom.Length; int layoutHeight = (string.IsNullOrEmpty(desc.Top) ? 1 : 2); for (int y = startY; y < startY + layoutHeight; y++) for (int x = startX; x < startX + layoutWidth; x++) { board.Blocks[x, y] = BlockType.Empty; } }