internal virtual void Initialize(int width, int height) { this.width = width; this.height = height; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { dancer.AddColumn(new Pentomino.Point(x, y)); } } int pieceBase = dancer.GetNumberColumns(); foreach (Pentomino.Piece p in pieces) { dancer.AddColumn(p); } bool[] row = new bool[dancer.GetNumberColumns()]; for (int idx = 0; idx < pieces.Count; ++idx) { Pentomino.Piece piece = pieces[idx]; row[idx + pieceBase] = true; GenerateRows(dancer, piece, width, height, false, row, idx == 0); if (piece.GetFlippable()) { GenerateRows(dancer, piece, width, height, true, row, idx == 0); } row[idx + pieceBase] = false; } printer = new Pentomino.SolutionPrinter(width, height); }
/// <summary>Find a solution to the problem.</summary> /// <param name="partial"> /// a temporary datastructure to keep the current partial /// answer in /// </param> /// <param name="output">the acceptor for the results that are found</param> /// <returns>the number of solutions found</returns> private int Search(IList <DancingLinks.Node <ColumnName> > partial, DancingLinks.SolutionAcceptor <ColumnName> output) { int results = 0; if (head.right == head) { IList <IList <ColumnName> > result = new AList <IList <ColumnName> >(partial.Count); foreach (DancingLinks.Node <ColumnName> row in partial) { result.AddItem(GetRowName(row)); } output.Solution(result); results += 1; } else { DancingLinks.ColumnHeader <ColumnName> col = FindBestColumn(); if (col.size > 0) { CoverColumn(col); DancingLinks.Node <ColumnName> row = col.down; while (row != col) { partial.AddItem(row); DancingLinks.Node <ColumnName> node = row.right; while (node != row) { CoverColumn(node.head); node = node.right; } results += Search(partial, output); partial.Remove(partial.Count - 1); node = row.left; while (node != row) { UncoverColumn(node.head); node = node.left; } row = row.down; } UncoverColumn(col); } } return(results); }
/// <summary>Given a prefix, find solutions under it.</summary> /// <param name="prefix"> /// a list of row choices that control which part of the search /// tree to explore /// </param> /// <param name="output">the output for each solution</param> /// <returns>the number of solutions</returns> public virtual int Solve(int[] prefix, DancingLinks.SolutionAcceptor <ColumnName> output) { IList <DancingLinks.Node <ColumnName> > choices = new AList <DancingLinks.Node <ColumnName > >(); for (int i = 0; i < prefix.Length; ++i) { choices.AddItem(Advance(prefix[i])); } int result = Search(choices, output); for (int i_1 = prefix.Length - 1; i_1 >= 0; --i_1) { Rollback(choices[i_1]); } return(result); }
/// <summary>Set the printer for the puzzle.</summary> /// <param name="printer"> /// A call-back object that is given each solution as it is /// found. /// </param> public virtual void SetPrinter(DancingLinks.SolutionAcceptor <Pentomino.ColumnName > printer) { this.printer = printer; }
/// <summary>Solve a complete problem</summary> /// <param name="output">the acceptor to receive answers</param> /// <returns>the number of solutions</returns> public virtual int Solve(DancingLinks.SolutionAcceptor <ColumnName> output) { return(Search(new AList <DancingLinks.Node <ColumnName> >(), output)); }