Inheritance: IBoard
Example #1
0
        public static IReadOnlyCollection<Cell> GetIntersectingCells(Board board, Cell cellA, Cell cellB)
        {
            var associatedA = GetAssociatedCells(board, cellA);
            var asoociatedB = GetAssociatedCells(board, cellB);

            return associatedA.Intersect(asoociatedB).ToList();
        }
Example #2
0
        static void Main(string[] args)
        {
            Console.WriteLine("Input:");

            var board = new Board();

            for (var i = 0; i < 9; i++)
            {
                board.InputNumbers(i, Console.ReadLine());
            }

            while (!board.Accept)
            {
                board.SolveOnce();
                //board.PutSolution(string.Format("step {0}:", board.Step));

                if (board.Step % 10000 == 0)
                {
                    board.PutSolution(string.Format("Step {0}", board.Step));
                }

                //System.Threading.Thread.Sleep(500);
            }

            Console.WriteLine();

            board.PutSolution("Solution:");
        }
Example #3
0
        public static IReadOnlyCollection<Cell> GetAssociatedCells(Board board, Cell cell)
        {
            var output = new List<Cell>();

            output.AddRange(GetBox(board, cell).Cells);
            output.AddRange(GetColumn(board, cell).Cells);
            output.AddRange(GetRow(board, cell).Cells);
            output.RemoveAll(c => c == cell);

            return output.Distinct().ToList();
        }
Example #4
0
 public void TestHiddenTriples()
 {
     var board = new Board("000001030231090000065003100678924300103050006000136700009360570006019843300000000");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #5
0
 public void TestHiddenSingle()
 {
     var board = new Board("200070038000006070300040600008020700100000006007030400004080009060400000910060002");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #6
0
        public override void Generate()
        {
            xs = new List<int>();
            ys = new List<int>();
            values = new List<int>();
            int width = sizex * sizey;
            int lastLookaheadUsed = 0;
            int loops = 0;

            SudokuDancingLinks dl = new SudokuDancingLinks(sizey, sizex);
            while (true)
            {
                int x = 0;
                int y = 0;
                bool match = true;
                while (match)
                {
                    x = rnd.Next(width);
                    y = rnd.Next(width);
                    match = false;
                    for (int i = 0; i < xs.Count; i++)
                    {
                        if (xs[i] == x && ys[i] == y)
                        {
                            match = true;
                            break;
                        }
                    }
                }
                int v = rnd.Next(width) + 1;
                xs.Add(x);
                ys.Add(y);
                values.Add(v);
                bool hasOpp = width % 2 == 0 || (x != width / 2 || y != width / 2);
                if (hasOpp)
                {
                    xs.Add(width - 1 - x);
                    ys.Add(width - 1 - y);
                    values.Add(rnd.Next(width) + 1);
                }

                dl.Clear();
                for (int i = 0; i < xs.Count; i++)
                {
                    dl.Grid[ys[i], xs[i]] = values[i];
                }
                dl.Solve();
                if (dl.Count <= 0)
                {
                    if (width % 2 == 0 || (xs[xs.Count - 1] != width / 2 || ys[ys.Count - 1] != width / 2))
                    {
                        xs.RemoveAt(xs.Count - 1);
                        ys.RemoveAt(ys.Count - 1);
                        values.RemoveAt(values.Count - 1);
                    }
                    xs.RemoveAt(xs.Count - 1);
                    ys.RemoveAt(ys.Count - 1);
                    values.RemoveAt(values.Count - 1);
                }
                else if (dl.Count == 1)
                {
                    break;
                }
                loops++;
                // if we go for a long time, try again.
                if (loops > width * width * width)
                {
                    Generate();
                    return;
                }

            }
            List<int> xs2 = new List<int>(xs);
            List<int> ys2 = new List<int>(ys);
            List<int> values2 = new List<int>(values);
            xs = new List<int>();
            ys = new List<int>();
            values = new List<int>();

            while (xs2.Count > 0)
            {
                int choice = rnd.Next(xs2.Count);
                int x = xs2[choice];
                int y = ys2[choice];
                int v = values2[choice];
                int x2 = -1;
                int y2 = -1;
                int v2 = -1;
                if (choice > 0 && xs2[choice - 1] == width - 1 - x && ys2[choice - 1] == width - 1 - y)
                {
                    x2 = width - 1 - x;
                    y2 = width - 1 - y;
                    v2 = values2[choice - 1];
                    xs2.RemoveAt(choice - 1);
                    xs2.RemoveAt(choice - 1);
                    ys2.RemoveAt(choice - 1);
                    ys2.RemoveAt(choice - 1);
                    values2.RemoveAt(choice - 1);
                    values2.RemoveAt(choice - 1);
                }
                else if (choice < xs2.Count - 1 && xs2[choice + 1] == width - 1 - x && ys2[choice + 1] == width - 1 - y)
                {
                    x2 = width - 1 - x;
                    y2 = width - 1 - y;
                    v2 = values2[choice + 1];
                    xs2.RemoveAt(choice);
                    xs2.RemoveAt(choice);
                    ys2.RemoveAt(choice);
                    ys2.RemoveAt(choice);
                    values2.RemoveAt(choice);
                    values2.RemoveAt(choice);

                }
                else
                {
                    xs2.RemoveAt(choice);
                    ys2.RemoveAt(choice);
                    values2.RemoveAt(choice);
                }

                dl.Clear();
                for (int i = 0; i < xs.Count; i++)
                {
                    dl.Grid[ys[i], xs[i]] = values[i];
                }
                for (int i = 0; i < xs2.Count; i++)
                {
                    dl.Grid[ys2[i], xs2[i]] = values2[i];
                }
                dl.Solve();
                if (dl.Count != 1)
                {
                    xs.Add(x);
                    ys.Add(y);
                    values.Add(v);
                    if (x2 != -1)
                    {
                        xs.Add(x2);
                        ys.Add(y2);
                        values.Add(v2);
                    }
                }

            }

            if (ensureDiff)
            {
                Board b = new Board(sizey, sizex);
                b.MaxLookahead = maxLookahead;
                b.Apply(xs, ys, values);
                SolveState result = b.Solve();
                if (result != SolveState.Solved)
                {
                    Generate();
                    return;
                }
                lastLookaheadUsed = b.LastLookaheadUsed;

                if (lastLookaheadUsed != maxLookahead)
                {
                    Generate();
                    return;
                }

            }
        }
Example #7
0
 private void UpdateBest(List<int> xs, List<int> ys, List<int> values)
 {
     Board board2 = new Board(sizey, sizex);
     board2.Apply(xs, ys, values);
     textBox4.Lines = DrawBoard(board2);
 }
Example #8
0
        private void Generate(int maxLookahead, Random rnd)
        {
            Generator g = new DancingGenerator(sizex, sizey, rnd, maxLookahead);
            g.Generate();
            xs = g.Xs;
            ys = g.Ys;
            values = g.Values;

            /* reduction phase, takes a long time right now and for no real gain.
            int width = boxes.Count;
            for (int i = 0; i < xs.Count; i++)
            {
                List<int> xs2 = new List<int>(xs);
                List<int> ys2 = new List<int>(ys);
                List<int> values2 = new List<int>(values);
                if (width % 2 == 0 || (xs2[i] != width / 2 || ys2[i] != width / 2))
                {
                    if (i > 0)
                    {
                        if (xs2[i - 1] == width - 1 - xs2[i] && ys2[i - 1] == width - 1 - ys2[i])
                        {
                            continue;
                        }
                    }
                    if (i < xs.Count - 1)
                    {
                        if (xs2[i + 1] == width - 1 - xs2[i] && ys2[i + 1] == width - 1 - ys2[i])
                        {
                            xs2.RemoveAt(i);
                            xs2.RemoveAt(i);
                            ys2.RemoveAt(i);
                            ys2.RemoveAt(i);
                            values2.RemoveAt(i);
                            values2.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    xs2.RemoveAt(i);
                    ys2.RemoveAt(i);
                    values2.RemoveAt(i);
                }
                Board board = new Board(sizey, sizex);
                board.MaxLookahead = maxLookahead;
                for (int j = 0; j < xs2.Count; j++)
                {
                    board.Set(xs2[j], ys2[j], values2[j]);
                }
                SolveState result = board.Solve();
                if (result == SolveState.Solved)
                {
                    xs = xs2;
                    ys = ys2;
                    values = values2;
                    i--;
                }
            }
            */
            // We have what we are looking for, output it and rate it.

            for (int i = 0; i < boxes.Count; i++)
            {
                for (int j = 0; j < boxes[i].Count; j++)
                {
                    boxes[i][j].Text = string.Empty;
                }
            }
            for (int i = 0; i < xs.Count; i++)
            {
                boxes[xs[i]][ys[i]].Text = values[i].ToString();
            }
            Board board2 = new Board(sizey, sizex);
            board2.MaxLookahead = maxLookahead;
            board2.Apply(xs, ys, values);
            textBox4.Lines = DrawBoard(board2); ;

            SolveState result2 = board2.SolveWithRating();
            if (board2.LastLookaheadUsed != 1)
                textBox2.Text = board2.LastLookaheadUsed.ToString();
            else
                textBox2.Text = board2.LastLookaheadUsed.ToString() + "." + board2.Score.ToString() + "." + board2.HighTuples.ToString();
        }
Example #9
0
        public override void Generate()
        {
            xs = new List<int>();
            ys = new List<int>();
            values = new List<int>();
            int lastLookaheadUsed = 0;
            SolveState result = SolveState.MultipleSolutions;
            int width = sizex*sizey;
            Board workingBoard = null;
            int possibilityCount = 0;
            List<List<int>> a = new List<List<int>>();
            while (result != SolveState.Solved)
            {
                if (result == SolveState.MultipleSolutions)
                {
                    bool needsFollowup = false;
                    int altx = 0;
                    int alty = 0;
                    if (workingBoard != null)
                    {
                        int rndnum = rnd.Next(possibilityCount);
                        int i2 = a[rndnum][0];
                        int j2 = a[rndnum][1];
                        int k2 = a[rndnum][2];
                        bool hasOpp = width % 2 == 0 || (i2 != width / 2 || j2 != width / 2);
                        xs.Add(i2);
                        ys.Add(j2);
                        values.Add(k2 + 1);
                        if (hasOpp)
                        {
                            needsFollowup = true;
                            altx = width - 1 - i2;
                            alty = width - 1 - j2;
                        }
                    }
                    else
                    {
                        int x = rnd.Next(width);
                        int y = rnd.Next(width);
                        int v = rnd.Next(width) + 1;
                        xs.Add(x);
                        ys.Add(y);
                        values.Add(v);
                        bool hasOpp = width % 2 == 0 || (x != width / 2 || y != width / 2);
                        if (hasOpp)
                        {
                            int x2 = width - 1- x;
                            int y2 = width - 1 -y;
                            xs.Add(x2);
                            ys.Add(y2);
                            int v2 = rnd.Next(width) + 1;
                            if (x2 == x || y2 == y || (x2/sizex==x/sizex && y2/sizey==y/sizey))
                            {
                                while (v2 == v)
                                {
                                    v2 = rnd.Next(width) + 1;
                                }
                            }
                            values.Add(v2);
                        }
                    }

                    if (workingBoard == null)
                    {
                        workingBoard = new Board(sizey,sizex);
                        // This line used to generate harder games.
                        workingBoard.MaxLookahead = maxLookahead;
                    }

                    // Doesnt hurt to apply the same values more then once.
                    workingBoard.Apply(xs, ys, values);
                    result = workingBoard.Solve();
                    if (result == SolveState.MultipleSolutions || result == SolveState.Solved)
                    {
                        if (needsFollowup)
                        {
                            List<int> poss = new List<int>();
                            for (int i = 0; i < width; i++)
                            {
                                if (workingBoard.CheckPossible(altx, alty, i + 1))
                                {
                                    poss.Add(i + 1);
                                }
                            }
                            if (poss.Count == 0)
                            {
                                result = SolveState.Unsolvable;
                            }
                            else
                            {
                                int choice = rnd.Next(poss.Count);
                                xs.Add(altx);
                                ys.Add(alty);
                                values.Add(poss[choice]);
                                workingBoard.Set(altx, alty, poss[choice]);
                                result = workingBoard.Solve();
                            }
                        }
                    }
                    if (result == SolveState.MultipleSolutions)
                    {
                        a = new List<List<int>>();
                        possibilityCount = 0;
                        for (int i = 0; i < width; i++)
                        {
                            for (int j = 0; j < width; j++)
                            {
                                if (workingBoard.Get(i, j) == 0)
                                {
                                    for (int k = 0; k < width; k++)
                                    {
                                        if (workingBoard.CheckPossible(i, j, k + 1))
                                        {
                                            List<int> aInner = new List<int>();
                                            aInner.Add(i);
                                            aInner.Add(j);
                                            aInner.Add(k);
                                            possibilityCount++;
                                            a.Add(aInner);
                                        }
                                    }
                                }
                            }
                        }
                        if (possibilityCount == 0)
                        {
                            // Deadend, try again.  Faster then walking backwards?
                            Generate();
                            return;
                        }
                    }
                    lastLookaheadUsed = workingBoard.LastLookaheadUsed;
                }
                else if (result == SolveState.Unsolvable)
                {
                    // Deadend, try again.  Faster then walking backwards?
                    Generate();
                    return;
                }
            }

            if (ensureDiff && lastLookaheadUsed != maxLookahead)
            {
                Generate();
                return;
            }
        }
Example #10
0
 public void TestSolvedPropertyTrue()
 {
     var board = new Board("246975138589316274371248695498621753132754986657839421724183569865492317913567842");
     Assert.AreEqual(true, board.Solved);
 }
Example #11
0
 public void TestNakedTriples()
 {
     var board = new Board("294513..66..8423193..697254....56....4..8..6....47....73.164..59..735..14..928637");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #12
0
 public void TestNakedPairs()
 {
     var board = new Board("4.....938.32.941...953..24.37.6.9..4529..16736.47.3.9.957..83....39..4..24..3.7.9");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #13
0
 public static Unit GetColumn(Board board, Cell cell)
 {
     return board.Columns.First(c => c.Cells.Contains(cell));
 }
Example #14
0
 public static Unit GetBox(Board board, Cell cell)
 {
     return board.Boxes.First(b => b.Cells.Contains(cell));
 }
Example #15
0
File: Board.cs Project: Tilps/Stash
        /// <summary>
        /// Performs a single 'lookahead' logic attempt.
        /// </summary>
        /// <param name="ys">
        /// Y coordinates to try.
        /// </param>
        /// <param name="xs">
        /// X coordinates to try.
        /// </param>
        /// <param name="values">
        /// Values to try in each location.
        /// </param>
        /// <returns></returns>
        private SolveState PassPartLookaheadLogic(List<int> ys, List<int> xs, List<int> values, int lookahead)
        {
            Board[] boards = new Board[ys.Count];
            SolveState[] results = new SolveState[ys.Count];
            SolveState result = SolveState.MultipleSolutions;
            for (int i = 0; i < boards.Length; i++)
            {
                boards[i] = this.Clone();
                boards[i].maxLookahead = lookahead - 1;
                boards[i].scoring = 0;
                boards[i].Set(xs[i], ys[i], values[i]+1);
                if (scoring == 0 || lookahead > 1)
                {
                    results[i] = boards[i].SolveProper();
                }
                else
                {
                    for (int j = 0; j < scoring - 1; j++)
                    {
                        results[i] = boards[i].PassZeroSlow();
                        if (results[i] != SolveState.Progressing)
                            break;
                    }
                }
            }
            bool allUnsolvable = true;
            for (int i = 0; i < results.Length; i++)
            {
                if (results[i] != SolveState.Unsolvable)
                    allUnsolvable = false;
                else
                {
                    if (!useEliminations)
                    {
                        results[i] = SolveState.MultipleSolutions;
                        allUnsolvable = false;
                    }
                    else
                    {
                        if (possibles[xs[i], ys[i], values[i]])
                        {
                            possibles[xs[i], ys[i], values[i]] = false;
                            result = SolveState.Progressing;
                        }
                    }
                }
            }
            if (allUnsolvable)
                return SolveState.Unsolvable;
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    if (cells[i, j] == 0)
                    {
                        for (int k = 0; k < width; k++)
                        {
                            if (possibles[i, j, k])
                            {
                                bool allFalse = true;
                                for (int b = 0; b < boards.Length; b++)
                                {
                                    if (results[b] != SolveState.Unsolvable)
                                    {
                                        if (boards[b].possibles[i, j, k])
                                            allFalse = false;
                                    }
                                }
                                if (allFalse)
                                {
                                    if (scoring != 0)
                                    {
                                        if (useLogging)
                                        {
                                            for (int a = 0; a < xs.Count; a++)
                                            {
                                                log.AppendFormat("({0},{1} {2}) ", xs[a], ys[a], values[a] + 1);
                                            }
                                            if (lookahead <=1)
                                                log.AppendFormat("Eliminated {0},{1} {2} in {3} steps\n", i, j, k + 1, scoring - 1);
                                            else
                                                log.AppendFormat("Eliminated {0},{1} {2} at {3} branches\n", i, j, k + 1, lookahead);
                                            if (scoring > 1)
                                            {
                                                for (int a = 0; a < xs.Count; a++)
                                                {
                                                    List<int> peggedxs = new List<int>();
                                                    peggedxs.Add(xs[a]);
                                                    List<int> peggedys = new List<int>();
                                                    peggedys.Add(ys[a]);
                                                    List<int> peggedvs = new List<int>();
                                                    peggedvs.Add(values[a]+1);
                                                    List<int> peggedwhen = new List<int>();
                                                    peggedwhen.Add(0);
                                                    for (int pegged = 0; pegged < scoring - 1; pegged++)
                                                    {
                                                        Board tb = this.Clone();
                                                        tb.Apply(peggedxs, peggedys, peggedvs);
                                                        tb.PassZeroSlow();
                                                        List<int> possiblexs = new List<int>(tb.lastxs);
                                                        List<int> possibleys = new List<int>(tb.lastys);
                                                        List<int> possiblevs = new List<int>(tb.lastvalues);
                                                        List<int> bestxs = new List<int>(possiblexs);
                                                        List<int> bestys = new List<int>(possibleys);
                                                        List<int> bestvs = new List<int>(possiblevs);
                                                        for (int trial = possiblexs.Count - 1; trial >= 0; trial--)
                                                        {
                                                            tb = this.Clone();
                                                            tb.Apply(peggedxs, peggedys, peggedvs);
                                                            possiblexs.RemoveAt(trial);
                                                            possibleys.RemoveAt(trial);
                                                            possiblevs.RemoveAt(trial);
                                                            tb.Apply(possiblexs, possibleys, possiblevs);
                                                            for (int nextp = pegged + 1; nextp < scoring - 1; nextp++)
                                                            {
                                                                if (tb.PassZeroSlow() != SolveState.Progressing)
                                                                    break;
                                                            }
                                                            if (tb.possibles[i, j, k] != false)
                                                            {
                                                                possiblexs = new List<int>(bestxs);
                                                                possibleys = new List<int>(bestys);
                                                                possiblevs = new List<int>(bestvs);
                                                            }
                                                            else
                                                            {
                                                                bestxs = new List<int>(possiblexs);
                                                                bestys = new List<int>(possibleys);
                                                                bestvs = new List<int>(possiblevs);
                                                            }
                                                        }
                                                        peggedxs.AddRange(bestxs);
                                                        peggedys.AddRange(bestys);
                                                        peggedvs.AddRange(bestvs);
                                                        for (int index = 0; index < bestvs.Count; index++)
                                                        {
                                                            peggedwhen.Add(pegged + 1);
                                                        }
                                                    }
                                                    log.AppendFormat("Trial ({0},{1} {2}):\n", xs[a], ys[a], values[a] + 1);
                                                    string[] splits = boards[a].Log.Split('\n');
                                                    for (int b = 0; b < peggedxs.Count; b++)
                                                    {
                                                        log.AppendFormat(" {3}: {0}, {1} {2}\n", peggedxs[b], peggedys[b], peggedvs[b], peggedwhen[b]);
                                                    }
                                                }

                                            }
                                        }
                                        possibles[i, j, k] = false;
                                        return SolveState.Progressing;
                                    }
                                    possibles[i, j, k] = false;
                                    result = SolveState.Progressing;
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }
Example #16
0
 static void Main(string[] args)
 {
     var board = new Board("016007803090800000870001260048000300650009082039000650060900020080002936924600510");
     board.Solve();
     Console.ReadLine();
 }
Example #17
0
 public static bool IsValid(Board board)
 {
     return IsValid(board._data);
 }
Example #18
0
        public static bool IsSolved(Board board)
        {
            // search for a zero value and return
            for (int row = 0; row < board.Size; row++) {
                for (int col = 0; col < board.Size; col++) {
                    if (board[row, col] == 0) {
                        return false;
                    }
                }
            }

            if (!Board.IsValid(board)) {
                return false;
            }

            return true;
        }
Example #19
0
 public void TestNakedQuads()
 {
     var board = new Board("000030086000020040090078520371856294900142375400397618200703859039205467700904132");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #20
0
 public static Unit GetRow(Board board, Cell cell)
 {
     return board.Rows.First(r => r.Cells.Contains(cell));
 }
Example #21
0
 public void TestPointingLineReduction()
 {
     var board = new Board("930050000200630095856002000003180570005020980080005000000800159508210004000560008");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #22
0
        public override void Generate()
        {
            xs = new List<int>();
            ys = new List<int>();
            values = new List<int>();
            int lastLookaheadUsed = 0;
            SolveState result = SolveState.MultipleSolutions;
            int width = sizex * sizey;
            int loops = 0;
            Board workingBoard = null;
            int possibilityCount = 0;
            List<List<int>> a = new List<List<int>>();
            while (result != SolveState.Solved)
            {
                if (result == SolveState.MultipleSolutions)
                {

                    if (workingBoard != null)
                    {
                        int rndnum = rnd.Next(possibilityCount);
                        int i2 = a[rndnum][0];
                        int j2 = a[rndnum][1];
                        int k2 = a[rndnum][2];
                        bool hasOpp = width % 2 == 0 || (i2 != width / 2 || j2 != width / 2);
                        xs.Add(i2);
                        ys.Add(j2);
                        values.Add(k2 + 1);
                        if (hasOpp)
                        {
                            int rnd2 = rnd.Next(a[rndnum].Count - 3) + 3;
                            int l2 = a[rndnum][rnd2];
                            xs.Add(width - 1 - i2);
                            ys.Add(width - 1 - j2);
                            values.Add(l2 + 1);
                        }
                    }
                    else
                    {
                        int x = rnd.Next(width);
                        int y = rnd.Next(width);
                        int v = rnd.Next(width) + 1;
                        xs.Add(x);
                        ys.Add(y);
                        values.Add(v);
                        bool hasOpp = width % 2 == 0 || (x != width / 2 || y != width / 2);
                        if (hasOpp)
                        {
                            xs.Add(width - 1 - x);
                            ys.Add(width - 1 - y);
                            values.Add(rnd.Next(width) + 1);
                        }
                    }

                    Board board = new Board(sizey, sizex);
                    // This line used to generate harder games.
                    board.MaxLookahead = maxLookahead;

                    board.Apply(xs, ys, values);
                    result = board.Solve();
                    if (result == SolveState.MultipleSolutions)
                    {
                        workingBoard = board;
                        a = new List<List<int>>();
                        possibilityCount = 0;
                        for (int i = 0; i < width; i++)
                        {
                            for (int j = 0; j < width; j++)
                            {
                                if (workingBoard.Get(i, j) == 0)
                                {
                                    if (workingBoard.Get(width - 1 - i, width - 1 - j) == 0)
                                    {
                                        for (int k = 0; k < width; k++)
                                        {
                                            if (workingBoard.CheckPossible(i, j, k + 1))
                                            {
                                                List<int> aInner = new List<int>();
                                                aInner.Add(i);
                                                aInner.Add(j);
                                                aInner.Add(k);
                                                for (int l = 0; l < width; l++)
                                                {
                                                    if (workingBoard.CheckPossible(width - 1 - i, width - 1 - j, l + 1))
                                                    {
                                                        aInner.Add(l);
                                                    }
                                                }
                                                if (aInner.Count >= 4)
                                                {
                                                    a.Add(aInner);
                                                    possibilityCount++;
                                                }
                                            }
                                        }

                                    }
                                }
                            }
                        }
                        if (possibilityCount == 0)
                        {
                            a = new List<List<int>>();
                            possibilityCount = 0;
                            for (int i = 0; i < width; i++)
                            {
                                for (int j = 0; j < width; j++)
                                {
                                    if (workingBoard.Get(i, j) == 0)
                                    {
                                        for (int k = 0; k < width; k++)
                                        {
                                            if (workingBoard.CheckPossible(i, j, k + 1))
                                            {
                                                List<int> aInner = new List<int>();
                                                aInner.Add(i);
                                                aInner.Add(j);
                                                aInner.Add(k);
                                                for (int l = 0; l < width; l++)
                                                {
                                                    if (workingBoard.CheckPossible(width - 1 - i, width - 1 - j, l + 1))
                                                    {
                                                        aInner.Add(l);
                                                    }
                                                }
                                                if (aInner.Count >= 4)
                                                {
                                                    a.Add(aInner);
                                                    possibilityCount++;
                                                }
                                            }
                                        }

                                    }
                                }
                            }
                            if (possibilityCount == 0)
                            {
                                // Deadend, try again.  Faster then walking backwards?
                                Generate();
                                return;
                            }
                        }
                    }
                    lastLookaheadUsed = board.LastLookaheadUsed;
                }
                else if (result == SolveState.Unsolvable)
                {
                    if (width % 2 == 0 || (xs[xs.Count - 1] != width / 2 || ys[ys.Count - 1] != width / 2))
                    {
                        xs.RemoveAt(xs.Count - 1);
                        ys.RemoveAt(ys.Count - 1);
                        values.RemoveAt(values.Count - 1);
                    }
                    xs.RemoveAt(xs.Count - 1);
                    ys.RemoveAt(ys.Count - 1);
                    values.RemoveAt(values.Count - 1);
                    result = SolveState.MultipleSolutions;
                }
                loops++;
                // if we go for a long time, try again.
                if (loops > width * width * width)
                {
                    Generate();
                    return;
                }
            }

            if (ensureDiff && lastLookaheadUsed != maxLookahead)
            {
                Generate();
                return;
            }
        }
Example #23
0
        /// <summary>
        /// Will play all forced moves. The result returned will be the resulting
        /// board and an unsorted move list which does not have any forced moves.
        /// </summary>
        protected MoveResult PlayForcedMoves(IBoardCells board, List<IMove> moves,IList<IMove>previousMovesPlayed)
        {
            IBoard playboard = board.Board;
            List<IMove> movesPlayed = new List<IMove>();
            if(previousMovesPlayed != null) {
                movesPlayed.AddRange(previousMovesPlayed);
            }
            List<IMove> forcedMoves = GetForcedMoves(moves);
            IBoardCells playboardCells = new BoardCells(playboard);

            List<Cell> movesRemaining = null;
            do {
                foreach (var move in forcedMoves) {
                    playboard = new Board(playboard, move);
                    movesPlayed.Add(move);
                    _numMovesTried++;
                }

                playboardCells = new BoardCells(playboard);
                movesRemaining = MoveFinder.FindMoves(playboardCells);
                forcedMoves = GetForcedMoves(Board.GetMovesFrom(movesRemaining));
            } while (forcedMoves.Count > 0);

            if (!Board.IsValid((Board)playboard)) {
                return null;
            }

            return new MoveResult(playboardCells, movesPlayed, movesRemaining);
        }
Example #24
0
 public void TestYWing()
 {
     var board = new Board("900240000050690231020050090090700320002935607070002900069020073510079062207086009");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #25
0
 private string[] DrawBoard(Board board2)
 {
     List<string> strs = new List<string>();
     for (int i = 0; i < boxes.Count; i++)
     {
         if (i % sizey == 0 && i != 0)
         {
             string str2 = "";
             for (int j = 0; j < boxes.Count ; j++)
             {
                 if (j % sizex == 0 && j != 0)
                     str2 += '+';
                 str2 += '-';
             }
             strs.Add(str2);
         }
         string str = "";
         for (int j = 0; j < boxes.Count; j++)
         {
             if (j % sizex == 0 && j != 0)
                 str += '|';
             if (board2.Get(i, j) == 0)
                 str += ".";
             else if (board2.Get(i, j) < 10)
                 str += board2.Get(i, j).ToString();
             else
                 str += ((char)('A' + board2.Get(i, j) - 10)).ToString();
         }
         strs.Add(str);
     }
     return strs.ToArray();
 }
Example #26
0
 public void TestBoxLineReduction()
 {
     var board = new Board("020943715904000600750000040500480000200000453400352000042000081005004260090208504");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #27
0
        private void Search()
        {
            Generator g = new DancingGenerator(sizex, sizey, new Random(), 1);
            g.EnsureDiff = false;
            int loop = 0;
            while (true)
            {
                loop++;
                g.Generate();
                List<int> xs = g.Xs;
                List<int> ys = g.Ys;
                List<int> values = g.Values;

                Board board2 = new Board(sizey, sizex);
                board2.MaxLookahead = 2;
                board2.Apply(xs, ys, values);

                SolveState result2 = board2.SolveWithRating();
                string name = "";
                if (board2.LastLookaheadUsed != 1)
                    name = board2.LastLookaheadUsed.ToString();
                else
                    name = board2.LastLookaheadUsed.ToString() + "." + board2.Score.ToString() + "." + board2.HighTuples.ToString();
                if (result2 != SolveState.Solved)
                {
                    name = "Failed to solve.";
                }
                else
                {

                    bool highest = true;
                    string[] nameSplits = name.Split('.');
                    foreach (string key in frequency.Keys)
                    {
                        string[] splits = key.Split('.');
                        if (int.Parse(splits[0]) > int.Parse(nameSplits[0]))
                        {
                            highest = false;
                            break;
                        }
                        else if (int.Parse(splits[0]) < int.Parse(nameSplits[0]))
                        {
                            continue;
                        }
                        else
                        {
                            if (splits.Length == 1)
                            {
                                highest = false;
                                break;
                            }
                            if (int.Parse(splits[1]) > int.Parse(nameSplits[1]))
                            {
                                highest = false;
                                break;
                            }
                            else if (int.Parse(splits[1]) < int.Parse(nameSplits[1]))
                            {
                                continue;
                            }
                            else
                            {
                                if (int.Parse(splits[2]) > int.Parse(nameSplits[2]))
                                {
                                    highest = false;
                                    break;
                                }
                                else if (int.Parse(splits[2]) < int.Parse(nameSplits[2]))
                                {
                                    continue;
                                }
                                else
                                {
                                    highest = false;
                                    break;
                                }
                            }
                        }
                    }
                    if (highest)
                    {
                        this.Invoke(new UpdateBestDelegate(UpdateBest), xs, ys, values);
                    }
                }
                Board board = new Board(sizey, sizex);
                board.Apply(xs, ys, values);

                if (frequency.ContainsKey(name))
                {
                    frequency[name] = frequency[name] + 1;
                    if (sample[name].Count < 100)
                        sample[name].Add(board);
                }
                else
                {
                    frequency[name] = 1;
                    sample[name] = new List<Board>();
                    sample[name].Add(board);
                }
                name = "Count: " + xs.Count;
                if (frequency2.ContainsKey(name))
                {
                    frequency2[name] = frequency2[name] + 1;
                    if (sample2[name].Count < 100)
                        sample2[name].Add(board);
                }
                else
                {
                    frequency2[name] = 1;
                    sample2[name] = new List<Board>();
                    sample2[name].Add(board);
                }
                if ((loop & 0xF) == 0)
                {
                    string result = "";
                    foreach (KeyValuePair<string, int> de in frequency)
                    {
                        result += de.Key + ":" + de.Value.ToString() + "\n";
                    }
                    foreach (KeyValuePair<string, int> de in frequency2)
                    {
                        result += de.Key + ":" + de.Value.ToString() + "\n";
                    }
                    this.Invoke(new UpdateStringDelegate(UpdateString), result);
                }
            }
        }
Example #28
0
 public void TestEasiestSudoku()
 {
     var board = new Board("...1.5...14....67..8...24...63.7..1.9.......3.1..9.52...72...8..26....35...4.9...");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }
Example #29
0
 private void button2_Click(object sender, EventArgs e)
 {
     if (boxes == null)
     {
         return;
     }
     Board board = new Board(sizey, sizex);
     for (int i = 0; i < boxes.Count; i++)
     {
         for (int j = 0; j < boxes[i].Count; j++)
         {
             try
             {
                 if (boxes[i][j].Text.Length != 0)
                 {
                     int value = int.Parse(boxes[i][j].Text);
                     if (value > 0 && value <= boxes.Count)
                         board.Set(i, j, value);
                 }
             }
             catch
             {
                 try
                 {
                     if (boxes[i][j].Text.Length != 0)
                     {
                         int value = char.ToUpper(boxes[i][j].Text[0])-'A'+10;
                         if (value > 0 && value <= boxes.Count)
                             board.Set(i, j, value);
                     }
                 }
                 catch
                 {
                 }
             }
         }
     }
     try
     {
         if (textBox2.Text.Length != 0)
         {
             string[] splits = textBox2.Text.Split('.');
             board.MaxLookahead = int.Parse(splits[0]);
         }
     }
     catch
     {
     }
     board.UseLogging = true;
     SolveState result = board.SolveWithRating();
     if (board.LastLookaheadUsed != 1)
         textBox2.Text = board.LastLookaheadUsed.ToString();
     else
         textBox2.Text = board.LastLookaheadUsed.ToString() + "." + board.Score.ToString() + "." + board.HighTuples.ToString();
     for (int i = 0; i < boxes.Count; i++)
     {
         for (int j = 0; j < boxes[i].Count; j++)
         {
             int value = board.Get(i, j);
             if (value != 0)
             {
                 boxes[i][j].Text = value.ToString();
             }
         }
     }
     textBox3.Text = "";
     if (result != SolveState.Solved)
         MessageBox.Show("Solving produced the following result: " + result.ToString());
     else
         textBox3.Lines = board.Log.Split('\n');
 }
Example #30
0
 public void TestHiddenPairs()
 {
     var board = new Board("000000000904607000076804100309701080008000300050308702007502610000403208000000000");
     board.Solve();
     Assert.AreEqual(true, board.Solved);
 }