Ejemplo n.º 1
0
 protected void CreateRequirements(SudokuGrid grid, int nc)
 {
     ca = new SudokuRequirement[nc];
     for (int i = 0; i < ca.Length; ++i)
     {
         ca[i] = new SudokuRequirement();
     }
 }
Ejemplo n.º 2
0
 Func <Hint, bool> HintIsAt(int selx, int sely)
 {
     return((Hint hint) =>
     {
         SudokuRequirement r = (SudokuRequirement)hint.Requirement;
         if (r != null)
         {
             return r.AppliesAt(selx, sely, this);
         }
         SudokuCandidate c = (SudokuCandidate)hint.Candidate;
         if (c != null)
         {
             return c.x == selx && c.y == sely;
         }
         return false;
     });
 }
Ejemplo n.º 3
0
        static bool AppliesAt(Hint hint, int x, int y, SudokuGrid grid)
        {
            if (!(hint is ForcedMoveHint))
            {
                SudokuCandidate k = (SudokuCandidate)hint.Candidate;
                if (k != null)
                {
                    return(k.x == x && k.y == y);
                }
            }

            SudokuRequirement c = (SudokuRequirement)hint.Requirement;

            if (c != null)
            {
                return(c.AppliesAt(x, y, grid));
            }

            return(false);
        }
Ejemplo n.º 4
0
 public string[] SolutionStrings()
 {
     string[] ret = new string[Cells];
     char[,] g = new char[Cells, Cells];
     for (int x = 0; x < Cells; ++x)
     {
         for (int y = 0; y < Cells; ++y)
         {
             g[x, y] = '.';
         }
     }
     for (int i = 0; i < tsc; ++i)
     {
         SudokuCandidate sc = (SudokuCandidate)ts[i].Candidate;
         g[sc.x, sc.y] = (char)('1' + sc.n);
     }
     for (int y = 0; y < Cells; ++y)
     {
         ret[y] = "";
         for (int x = 0; x < Cells; ++x)
         {
             if (g[x, y] == '.')
             {
                 ret[y] += "[";
                 SudokuRequirement c = GetRequirement(x, y, Houses.Cell);
                 foreach (SudokuCandidate k in c.UnselectedCandidates)
                 {
                     ret[y] += (char)('1' + k.n);
                 }
                 ret[y] += "]";
             }
             else
             {
                 ret[y] += g[x, y];
             }
         }
     }
     return(ret);
 }
Ejemplo n.º 5
0
        /*
         * public SudokuSolver(string[] lines)
         * {
         *  CreateMatrix();
         *  Apply(lines);
         * }
         */

        void CreateMatrix(SudokuGrid grid)
        {
            // Create requirements - columns of 0/1 matrix
            int num_cages = grid.NumCages;
            int diags     = 0;

            if (grid.MajorDiagonal)
            {
                ++diags;
            }
            if (grid.MinorDiagonal)
            {
                ++diags;
            }
            int d = grid.MajorDiagonal ? 1 : 0; // Where minor diagonal is found

            CreateRequirements(grid, Cells * Cells * 4 + diags * Cells);
            CreateOptionals(grid, num_cages);
            Houses[] houses = new Houses[] {
                Houses.Cell,
                Houses.Column,
                Houses.Row,
                Houses.Box
            };
            for (int i0 = 0; i0 < Cells; ++i0)
            {
                for (int i1 = 0; i1 < Cells; ++i1)
                {
                    for (int type = 0; type < 4; ++type)
                    {
                        Houses            house = houses[type];
                        SudokuRequirement c     = GetRequirement(i0, i1, house);
                        c.i0    = i0;
                        c.i1    = i1;
                        c.house = house;
                        requirements.AddRequirement(c);
                    }
                }
            }
            if (grid.MajorDiagonal)
            {
                for (int i0 = 0; i0 < Cells; ++i0)
                {
                    SudokuRequirement c = GetDiagonalRequirement(0, i0);
                    c.i0    = i0;
                    c.i1    = -1;
                    c.house = Houses.MajorDiagonal;
                    requirements.AddRequirement(c);
                }
            }
            if (grid.MinorDiagonal)
            {
                for (int i0 = 0; i0 < Cells; ++i0)
                {
                    SudokuRequirement c = GetDiagonalRequirement(d, i0);
                    c.i0    = i0;
                    c.i1    = -1;
                    c.house = Houses.MinorDiagonal;
                    requirements.AddRequirement(c);
                }
            }
            for (int i0 = 0; i0 < num_cages; ++i0)
            {
                for (int i1 = 0; i1 < Cells; ++i1)
                {
                    CageOptional ca = GetCageOptional(i0, i1);
                    ca.i0    = i0;
                    ca.i1    = i1;
                    ca.house = Houses.Cage;
                    //optionals.AddRequirement(ca);
                    ca.SetIncluded();
                }
            }

            // Create candidates - rows of 0/1 matrix
            CreateCandidates(new SudokuCandidate[Cells * Cells * Cells]);
            CreateSolution(Cells * Cells);
            for (int x = 0; x < Cells; ++x)
            {
                for (int y = 0; y < Cells; ++y)
                {
                    int cage = grid.CageAt(x, y);
                    int box  = grid.BoxAt(x, y);
                    for (int n = 0; n < Cells; ++n)
                    {
                        SudokuCandidate k = new SudokuCandidate(x, y, n, box, cage);
                        k.AddCandidate(GetRequirement(x, y, Houses.Cell));
                        k.AddCandidate(GetRequirement(x, n, Houses.Column));
                        k.AddCandidate(GetRequirement(y, n, Houses.Row));
                        k.AddCandidate(GetRequirement(box, n, Houses.Box));
                        if (grid.MajorDiagonal && x == y)
                        {
                            k.AddCandidate(GetDiagonalRequirement(0, n));
                        }
                        if (grid.MinorDiagonal && x == Cells - y - 1)
                        {
                            k.AddCandidate(GetDiagonalRequirement(d, n));
                        }
                        if (cage != -1)
                        {
                            k.AddCageOptional(GetCageOptional(cage, n));
                        }
                        tr[trc++] = k;

                        // Discard candidates where cage size already reached 1
                        //if (cage != -1 && grid.cageInfo.sizes[cage] == 1 && n + 1 != grid.cageInfo.totals[cage])
                        //    DiscardCandidate(k);
                    }
                }
            }

            // Discard candidates that do not meet cage total
            for (int i0 = 0; i0 < num_cages; ++i0)
            {
                CageOptional.CheckRemains(this, grid.cageInfo, i0, -1);
            }

            /*
             * if (grid.IsKiller)
             * {
             *  SudokuGrid.CageInfo info = grid.cageInfo;
             *  for (int ca = 0; ca < info.cages.Length; ++ca)
             *  {
             *      List<Point> pts = new List<Point>();
             *      for (int x = 0; x < Cells; ++x)
             *          for (int y = 0; y < Cells-1; ++y)
             *              if (info.cages[x, y] == ca)
             *                  pts.Add(new Point(x, y));
             *      int[] ns = new int[Cells];
             *      for (int i = 0; i < Cells; ++i) ns[i] = i;
             *      Candidate k = new Candidate();
             *      KillerRequire(k, info.totals[ca], pts.ToArray(), ns);
             *  }
             * }
             */
        }