Example #1
0
 public Rule(Condition condition, EdgeworkValue ev)
 {
     Condition = condition; Solution = new Solution(ev);
 }
Example #2
0
 public static Condition QuadrantMajorityCount(Comparison comparison, bool white, EdgeworkValue ev)
 {
     return(new Condition(
                string.Format("If there are {0} mostly-{1} quadrants {2} {3}", comparison == Comparison.Same ? "exactly as many" : comparison == Comparison.Fewer ? "fewer" : "more", white ? "white" : "black", comparison == Comparison.Same ? "as" : "than", ev.Name),
                Extra.None,
                (grid, bomb) =>
     {
         var quadrants = getQuadrantCounts(grid);
         var numMajQuadrants = quadrants.Count(q => white ? (q > 8) : (q < 8));
         return
         comparison == Comparison.Same ? (numMajQuadrants == ev.GetValue(bomb)) :
         comparison == Comparison.More ? (numMajQuadrants > ev.GetValue(bomb)) : (numMajQuadrants < ev.GetValue(bomb));
     }));
 }
Example #3
0
 public Solution(EdgeworkValue ev)
 {
     Name = ev.Name; Answer = (grid, bomb, extra) => ev.GetValue(bomb);
 }
Example #4
0
    void Start()
    {
        _colorIx = Rnd.Range(0, _lightColors.Length);

        _moduleId              = _moduleIdCounter++;
        Buttons[0].OnInteract += delegate { PushButton(1); return(false); };
        Buttons[1].OnInteract += delegate { PushButton(2); return(false); };
        Buttons[2].OnInteract += delegate { PushButton(3); return(false); };
        Buttons[3].OnInteract += delegate { PushButton(4); return(false); };

        _bitmap = new bool[8][];
        for (int j = 0; j < 8; j++)
        {
            _bitmap[j] = new bool[8];
            for (int i = 0; i < 8; i++)
            {
                _bitmap[j][i] = Rnd.Range(0, 2) == 0;
            }
        }
        _isSolved = false;

        Bitmap.material.mainTexture = generateTexture();
        Bitmap.material.shader      = Shader.Find("Unlit/Transparent");

        Debug.LogFormat("[Bitmaps #{0}] Bitmap ({1}):", _moduleId, _colorNames[_colorIx]);
        for (int y = 0; y < 8; y++)
        {
            Debug.LogFormat("[Bitmaps #{0}] {1}", _moduleId, string.Join("", Enumerable.Range(0, 8).Select(x => (_bitmap[x][y] ? "░░" : "██") + (x == 3 ? "│" : null)).ToArray()));
            if (y == 3)
            {
                Debug.LogFormat("[Bitmaps #{0}] ────────┼────────", _moduleId);
            }
        }
        Debug.LogFormat("[Bitmaps #{0}] Quadrant counts: {1}", _moduleId, string.Join(", ", getQuadrantCounts(_bitmap).Select(w => string.Format("{0}w/{1}b", w, 16 - w)).ToArray()));

        var rnd = RuleSeedable.GetRNG();

        Debug.LogFormat("[Bitmaps #{0}] Using rule seed: {1}", _moduleId, rnd.Seed);
        if (rnd.Seed == 1)
        {
            _defaultRuleset = true;
            _rules          = Ut.NewArray(
                // If exactly one quadrant has 5 or fewer white pixels, the answer is the number of white pixels in the other 3 quadrants.
                new Rule(Condition.QuadrantPixelCount(NumberComparison.ExactlyOne, 5, orFewer: true, white: true), Solution.WhiteInOtherThreeQuadrants),
                // If there are exactly as many mostly-white quadrants as there are lit indicators, the answer is the number of batteries.
                new Rule(Condition.QuadrantMajorityCount(Comparison.Same, white: true, ev: EdgeworkValue.LitIndicators), EdgeworkValue.NumberOfBatteries),
                // If exactly one row or column is completely white or completely black, the answer is its x-/y-coordinate (starting from 1 in the top/left).
                new Rule(Condition.RowOrColumn, Solution.RowColumnCoordinate),
                // If there are fewer mostly-white quadrants than mostly-black quadrants, the answer is the number of mostly-black quadrants.
                new Rule(Condition.QuadrantMajorityComparison(Comparison.Fewer), Solution.NumMostlyBlackQuadrants),
                // If the entire bitmap has 36 or more white pixels, the answer is the total number of white pixels.
                new Rule(Condition.BitmapPixelCount(36, 64, white: true), Solution.NumWhitePixels),
                // If there are more mostly-white quadrants than mostly-black quadrants, the answer is the smallest number of black pixels in any quadrant.
                new Rule(Condition.QuadrantMajorityComparison(Comparison.More), Solution.MinBlackInQuadrant),
                // If exactly one quadrant has 5 or fewer black pixels, the answer is the number of black pixels in the other 3 quadrants.
                new Rule(Condition.QuadrantPixelCount(NumberComparison.ExactlyOne, 5, orFewer: true, white: false), Solution.BlackInOtherThreeQuadrants),
                // If there are exactly as many mostly-black quadrants as there are unlit indicators, the answer is the number of ports.
                new Rule(Condition.QuadrantMajorityCount(Comparison.Same, white: false, ev: EdgeworkValue.UnlitIndicators), EdgeworkValue.Ports),
                // If there is a 3×3 square that is completely white or completely black, the answer is the x-coordinate (starting from 1) of the center of the first such square in reading order.
                new Rule(Condition.Square3, Solution.SquareCoordinate(SquarePoint.Center, 3, y: false, last: false)),
                // If there are exactly as many mostly-white quadrants as mostly-black quadrants, the answer is the first numeric digit of the serial number.
                new Rule(Condition.QuadrantMajorityComparison(Comparison.Same), EdgeworkValue.SnFirstDigit));

            _startRule = EdgeworkValue.SnLastDigit;
        }
        else
        {
            _defaultRuleset = false;

            // Add extra randomness
            var skip = rnd.Next(0, 100);
            for (var i = 0; i < skip; i++)
            {
                rnd.NextDouble();
            }

            // Take a copy of the (static) array
            var edgeworkVariables  = rnd.ShuffleFisherYates(EdgeworkValue.Default.ToArray());
            var edgeworkVariableIx = 0;

            // Optional conditions
            var conditions = new List <Condition>
            {
                Condition.RowOrColumn,
                Condition.Row,
                Condition.Column,
                Condition.Square3,
                new[] { Condition.Square2BW, Condition.Square2W, Condition.Square2B }[rnd.Next(0, 3)],
                Condition.QuadrantMajorityCount(Comparison.Same, white: true, ev: edgeworkVariables[edgeworkVariableIx++]),
                Condition.QuadrantMajorityCount(Comparison.More, white: true, ev: edgeworkVariables[edgeworkVariableIx++]),
                Condition.QuadrantMajorityCount(Comparison.Fewer, white: true, ev: edgeworkVariables[edgeworkVariableIx++]),
                Condition.QuadrantMajorityCount(Comparison.Same, white: false, ev: edgeworkVariables[edgeworkVariableIx++]),
                Condition.QuadrantMajorityCount(Comparison.More, white: false, ev: edgeworkVariables[edgeworkVariableIx++]),
                Condition.QuadrantMajorityCount(Comparison.Fewer, white: false, ev: edgeworkVariables[edgeworkVariableIx++])
            };

            // We will make sure that all three conditions from one of these triplets are present so that there is always one rule that matches.
            var pixelCount1       = rnd.Next(3, 8);
            var orFewer           = rnd.Next(0, 2) == 0;
            var whiteNotBlack     = rnd.Next(0, 2) == 0;
            var pixelCount2       = rnd.Next(26, 30);
            var whiteNotBlack2    = rnd.Next(0, 2) == 0;
            var tripletConditions = Ut.NewArray(
                Ut.NewArray(
                    Condition.QuadrantPixelCount(NumberComparison.None, orFewer ? pixelCount1 : 16 - pixelCount1, orFewer, whiteNotBlack),
                    Condition.QuadrantPixelCount(NumberComparison.ExactlyOne, orFewer ? pixelCount1 : 16 - pixelCount1, orFewer, whiteNotBlack),
                    Condition.QuadrantPixelCount(NumberComparison.MoreThanOne, orFewer ? pixelCount1 : 16 - pixelCount1, orFewer, whiteNotBlack)),
                Ut.NewArray(
                    Condition.QuadrantMajorityComparison(Comparison.Fewer),
                    Condition.QuadrantMajorityComparison(Comparison.More),
                    Condition.QuadrantMajorityComparison(Comparison.Same)),
                Ut.NewArray(
                    Condition.BitmapPixelCount(64 - pixelCount2, 64, whiteNotBlack2),
                    Condition.BitmapPixelCount(0, pixelCount2, whiteNotBlack2),
                    Condition.BitmapPixelCount(pixelCount2 + 1, 63 - pixelCount2, whiteNotBlack2)),
                Ut.NewArray(
                    Condition.QuadrantBalancedNone,
                    Condition.QuadrantBalancedOne,
                    Condition.QuadrantBalancedMoreThanOne));

            var tripletIx = rnd.Next(0, tripletConditions.Length);
            var triplet   = tripletConditions[tripletIx];

            for (var i = 0; i < tripletConditions.Length; i++)
            {
                if (i != tripletIx)
                {
                    for (var j = 0; j < tripletConditions[i].Length; j++)
                    {
                        conditions.Add(tripletConditions[i][j]);
                    }
                }
            }

            rnd.ShuffleFisherYates(conditions);
            conditions.RemoveRange(7, conditions.Count - 7);
            conditions.AddRange(triplet);
            rnd.ShuffleFisherYates(conditions);

            _startRule = edgeworkVariables[edgeworkVariableIx++];

            var solutions = new List <Solution>
            {
                Solution.NumMostlyBlackQuadrants,
                Solution.NumMostlyWhiteQuadrants,
                Solution.NumBalancedQuadrants,
                Solution.NumWhitePixels,
                Solution.NumBlackPixels,
                Solution.MinBlackInQuadrant,
                Solution.MaxBlackInQuadrant,
                Solution.MinWhiteInQuadrant,
                Solution.MaxWhiteInQuadrant
            };

            for (var i = edgeworkVariableIx; i < edgeworkVariables.Length; i++)
            {
                solutions.Add(new Solution(edgeworkVariables[i]));
            }

            var extraSolutions = new Dictionary <Extra, List <Solution> >();

            extraSolutions[Extra.Quadrant] = new List <Solution>
            {
                Solution.WhiteInOtherThreeQuadrants,
                Solution.BlackInOtherThreeQuadrants,
                new Solution("the number of white pixels in the diagonally opposite quadrant", (grid, bomb, extra) => getQuadrantCounts(grid)[3 - extra]),
                new Solution("the number of black pixels in the diagonally opposite quadrant", (grid, bomb, extra) => 16 - getQuadrantCounts(grid)[3 - extra]),
                new Solution("the number of white pixels in the horizontally adjacent quadrant", (grid, bomb, extra) => getQuadrantCounts(grid)[extra ^ 1]),
                new Solution("the number of black pixels in the horizontally adjacent quadrant", (grid, bomb, extra) => 16 - getQuadrantCounts(grid)[extra ^ 1]),
                new Solution("the number of white pixels in the vertically adjacent quadrant", (grid, bomb, extra) => getQuadrantCounts(grid)[extra ^ 2]),
                new Solution("the number of black pixels in the vertically adjacent quadrant", (grid, bomb, extra) => 16 - getQuadrantCounts(grid)[extra ^ 2])
            };
            extraSolutions[Extra.Row] = new List <Solution>
            {
                new Solution("its y-coordinate, counting from 1 from top to bottom", (grid, bomb, extra) => extra + 1),
                new Solution("its y-coordinate, counting from 1 from bottom to top", (grid, bomb, extra) => 8 - extra)
            };
            extraSolutions[Extra.Column] = new List <Solution>
            {
                new Solution("its x-coordinate, counting from 1 from left to right", (grid, bomb, extra) => extra + 1),
                new Solution("its x-coordinate, counting from 1 from right to left", (grid, bomb, extra) => 8 - extra)
            };
            extraSolutions[Extra.Line] = new List <Solution>
            {
                Solution.RowColumnCoordinate,
                new Solution("its x-/y-coordinate, counting from 1 from bottom/right to top/left", (grid, bomb, extra) => 8 - extra)
            };
            extraSolutions[Extra.Square3] = new List <Solution>
            {
                Solution.SquareCoordinate(SquarePoint.Center, 3, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.Center, 3, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.Center, 3, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.Center, 3, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 3, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 3, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 3, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 3, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.TopRight, 3, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.TopRight, 3, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.TopRight, 3, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.TopRight, 3, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 3, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 3, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 3, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 3, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 3, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 3, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 3, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 3, y: true, last: true)
            };
            extraSolutions[Extra.Square2] = new List <Solution>
            {
                Solution.SquareCoordinate(SquarePoint.TopLeft, 2, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 2, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 2, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.TopLeft, 2, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.TopRight, 2, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.TopRight, 2, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.TopRight, 2, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.TopRight, 2, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 2, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 2, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 2, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomLeft, 2, y: true, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 2, y: false, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 2, y: true, last: false),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 2, y: false, last: true),
                Solution.SquareCoordinate(SquarePoint.BottomRight, 2, y: true, last: true)
            };

            _rules = new Rule[10];
            for (int i = 0; i < 10; i++)
            {
                var numSol = solutions.Count;
                if (extraSolutions.ContainsKey(conditions[i].Extra))
                {
                    numSol += extraSolutions[conditions[i].Extra].Count;
                }
                var ix = rnd.Next(0, numSol);
                if (ix < solutions.Count)
                {
                    _rules[i] = new Rule(conditions[i], solutions[ix]);
                    solutions.RemoveAt(ix);
                }
                else
                {
                    ix       -= solutions.Count;
                    _rules[i] = new Rule(conditions[i], extraSolutions[conditions[i].Extra][ix]);
                    extraSolutions[conditions[i].Extra].RemoveAt(ix);
                }
            }
            Debug.LogFormat("<Bitmaps #{0}> RULES:", _moduleId);
            for (int i = 0; i < 10; i++)
            {
                Debug.LogFormat("<Bitmaps #{0}> {1}, the answer is {2}.", _moduleId, _rules[i].Condition.Name, _rules[i].Solution.Name);
            }
            Debug.LogFormat("[Bitmaps #{0}] SOLUTION AT START (may change if solution depends on number of solved modules):", _moduleId);
        }

        // Evaluate the answer just to log it.
        findAnswer(log: true);
    }