Beispiel #1
0
    static bool solve(PuzzleState puzzleState)
    {
        //Make links with logic
        solveLogic(puzzleState);

        //Make links with guess
        HashSet <Tuple <Point, Point> > links = new HashSet <Tuple <Point, Point> >();
        List <Point> nodes = puzzleState.Nodes.Keys.ToList();

        foreach (Point n in nodes)
        {
            foreach (Point neighbour in Neighbours[n])
            {
                if (puzzleState.CanLink(n, neighbour) > 0)
                {
                    Tuple <Point, Point> canonical = PuzzleState.Canonical(n, neighbour);
                    if (!links.Contains(canonical))
                    {
                        links.Add(canonical);
                    }
                }
            }
        }
        //Hack - try the shortest links first
        List <Tuple <Point, Point> > sortedLinks = links.ToList().OrderBy(l => Math.Abs(l.Item1.X - l.Item2.X) + Math.Abs(l.Item1.Y - l.Item2.Y)).ToList();

        //Choose a random link
        foreach (Tuple <Point, Point> link in sortedLinks)
        {
            //Duplicate the state
            PuzzleState duplicate = new PuzzleState(puzzleState);
            //Make the link
            level++;
            Console.Error.WriteLine(new string(' ', level * 2) + "test linking (" + link.Item1.X + "," + link.Item1.Y + ")->(" + link.Item2.X + "," + link.Item2.Y + ")");
            duplicate.AddLink(link.Item1, link.Item2);
            //If exhausted, check for connectedness
            if (duplicate.Nodes[link.Item1] == 0 && duplicate.Nodes[link.Item2] == 0)
            {
                int degree1 = 0;
                foreach (Point neighbour in Neighbours[link.Item1])
                {
                    if (duplicate.LinkValue(link.Item1, neighbour) > 0)
                    {
                        degree1++;
                    }
                }
                int degree2 = 0;
                foreach (Point neighbour in Neighbours[link.Item2])
                {
                    if (duplicate.LinkValue(link.Item2, neighbour) > 0)
                    {
                        degree2++;
                    }
                }
                //
                if (degree1 == 1 && degree2 == 1)
                {
                    level--;
                    continue;
                }
            }
            //Solve it
            bool result = solve(duplicate);
            level--;
            if (result)
            {
                puzzleState.Nodes         = new Dictionary <Point, int>(duplicate.Nodes);
                puzzleState.Links         = new Dictionary <Tuple <Point, Point>, int>(duplicate.Links);
                puzzleState.Intersections = new HashSet <Point>(duplicate.Intersections);
                break;
            }
        }

        //Solved, check for completness
        if (puzzleState.Nodes.Count(d => d.Value > 0) > 0)
        {
            return(false);
        }
        if (!puzzleState.IsConnected())
        {
            return(false);
        }
        //
        return(true);
    }