/** * Basic constructor. Does not conduct any dimension * checks. */ public Tour(int width, int height) { Board = new Square[width, height]; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) Board[x, y] = new Square(x, y); Width = width; Height = height; }
/** * Creates a knight's tour starting from a random * square. If a knight's tour cannot be created then * create a linear path. */ public Square CreateTour() { Square square; Square current; if (IsValid(Width, Height)) { var rand = new Random(); square = Board[rand.Next(0, Width), rand.Next(0, Height)]; current = square; do { current.Visited = true; current.Next = FindNext(current); current = current.Next; } while (current != null); } else { square = Board[0, 0]; current = square; for (int x = 0; x < Width; x++) { if (current == null) break; for (int y = 0; y < Height; y++) { if (current == null) break; if (y + 1 < Height) current.Next = Board[x, y + 1]; else if (x + 1 < Width) current.Next = Board[x + 1, 0]; else current.Next = null; current = current.Next; } } } _path = square; return square; }
/** * Creates a tour based on the imported path. */ public Square Import(String export) { string[] squares = export.Trim().Split(';'); var square = new Square(-1, -1) { X = int.Parse(squares[0].Split(',')[0]), Y = int.Parse(squares[0].Split(',')[1]) }; Square current = square; for (int n = 1; n < squares.Length - 1; n++) { var next = new Square(-1, -1) { X = int.Parse(squares[n].Split(',')[0]), Y = int.Parse(squares[n].Split(',')[1]) }; current.Next = next; current = next; } _path = square; return square; }
/** * Creates a list of all possible moves. */ public List<Square> GetMoves(Square square) { var list = new List<Square>(); int x = square.X; int y = square.Y; if (InBounds(x + 2, y - 1) && !Board[x + 2, y - 1].Visited) list.Add(Board[x + 2, y - 1]); if (InBounds(x + 2, y + 1) && !Board[x + 2, y + 1].Visited) list.Add(Board[x + 2, y + 1]); if (InBounds(x - 2, y - 1) && !Board[x - 2, y - 1].Visited) list.Add(Board[x - 2, y - 1]); if (InBounds(x - 2, y + 1) && !Board[x - 2, y + 1].Visited) list.Add(Board[x - 2, y + 1]); if (InBounds(x - 1, y + 2) && !Board[x - 1, y + 2].Visited) list.Add(Board[x - 1, y + 2]); if (InBounds(x - 1, y - 2) && !Board[x - 1, y - 2].Visited) list.Add(Board[x - 1, y - 2]); if (InBounds(x + 1, y + 2) && !Board[x + 1, y + 2].Visited) list.Add(Board[x + 1, y + 2]); if (InBounds(x + 1, y - 2) && !Board[x + 1, y - 2].Visited) list.Add(Board[x + 1, y - 2]); return list; }
/** * Finds a next possible square. */ public Square FindNext(Square square) { List<Square> moves = GetMoves(square); if (Util.IntToBool(moves.Count)) return moves.OrderBy(s => GetMoves(s).Count).First(); return null; }
/** * Returns a BitArray object containing the bits extracted from * the pixel array "bits". */ private static BitArray Extract(int[] bits, Tour tour, Square path, int size) { var file = new BitArray(size); Square start = path; for (int n = 0; n < size; n += 3) { int depth = n/bits.Length; int index = Util.ToIndex(tour.Width, path.X, path.Y); Color color = Util.BitsToColor(bits[index]); int r = color.R; int g = color.G; int b = color.B; r = r & 1 << depth; g = g & 1 << depth; b = b & 1 << depth; file.Set(n, Util.IntToBool(r)); if (n + 1 < size) file.Set(n + 1, Util.IntToBool(g)); if (n + 2 < size) file.Set(n + 2, Util.IntToBool(b)); //Select the next pixel to read from. path = path.Next ?? start; } return file; }