Exemple #1
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);
 }
Exemple #2
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);
                }
            }
        }
Exemple #3
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;
            }
        }
Exemple #4
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();
        }
Exemple #5
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;
                }

            }
        }