Example #1
0
    protected override void DoStart()
    {
        var rnd = RuleSeedable.GetRNG();

        Log("Using rule seed: {0}", rnd.Seed);

        var skip = rnd.Next(0, 6);

        for (var i = 0; i < skip; i++)
        {
            rnd.NextDouble();
        }
        _instructions = rnd.ShuffleFisherYates((Instruction[])Enum.GetValues(typeof(Instruction)));

        var numbers = Enumerable.Range(0, 16).ToArray();

        _ordersByStage = new int[5][];
        for (var stage = 0; stage < 4; stage++)
        {
            rnd.ShuffleFisherYates(numbers);
            _ordersByStage[stage] = numbers.ToArray();
        }

        SetInitialState();
    }
    private void GenerateRules()
    {
        var rnd = RuleSeedable.GetRNG();

        // Add more random spread
        for (int i = 0; i < 13; i++)
        {
            rnd.Next();
        }

        // Generate color pentagons
        _table = new Dictionary <SquareColor, SquareColor[]>();
        var origColors = new[] { SquareColor.Red, SquareColor.Blue, SquareColor.Green, SquareColor.Yellow, SquareColor.Magenta };

        for (int i = 0; i < 5; i++)
        {
            rnd.ShuffleFisherYates(_colorCandidates);
            _table[origColors[i]] = _colorCandidates.ToArray();
            LogDebug("Rule Generator: {0} pentagon is: {1}", origColors[i], _table[origColors[i]].Select(c => c.ToString()[0]).JoinString("-"));
        }

        // Random spread
        rnd.Next();
        rnd.Next();
        rnd.Next();

        // Generate directions
        _ruleOneDirection = (rnd.Next(2) * 2) - 1;
        _backupDirection  = (rnd.Next(2) * 2) - 1;
        LogDebug("Rule Generator: rule one direction is: {0}", _ruleOneDirection == -1 ? "counter-clockwise" : "clockwise");
        LogDebug("Rule Generator: backup rule direction is: {0}", _backupDirection == -1 ? "counter-clockwise" : "clockwise");
    }
Example #3
0
    protected override void StartModule()
    {
        _moduleId = _moduleIdCounter++;

        var rnd = RuleSeedable.GetRNG();

        Debug.LogFormat("[X-Ray #{0}] Using rule seed: {1}", _moduleId, rnd.Seed);

        if (_ruleSeededRules.ContainsKey(rnd.Seed))
        {
            _rules = _ruleSeededRules[rnd.Seed];
        }
        else
        {
            if (rnd.Seed == 1)
            {
                _rules = new XRayRules(
                    columns: Enumerable.Range(0, 12).Select(convertForSeed1).ToArray(),
                    rows: Enumerable.Range(0, 12).Select(i => convertForSeed1(i + 12)).ToArray(),
                    t3x3: Enumerable.Range(0, 9).Select(i => convertForSeed1(i + 24)).ToArray(),
                    numbersInTable: GenerateTableOfNumbers(rnd));
            }
            else
            {
                // Decide on the icons for the 3×3 table up top
                var _3x3 = rnd.ShuffleFisherYates(Enumerable.Range(0, 22).ToArray()).Take(9).Select(x => new SymbolInfo(x + 88, false)).ToArray();

                // For the rows, we can use any non-symmetric icon
                var _rows = rnd.ShuffleFisherYates(Enumerable.Range(0, 88).ToArray()).Take(12).Select(x => new SymbolInfo(x, x < 55 ? rnd.Next(0, 2) != 0 : false)).ToArray();

                // For the columns, we can only use flippable icons that we haven’t already used for rows
                var columnsRaw = rnd.ShuffleFisherYates(Enumerable.Range(0, 55).Where(x => !_rows.Any(r => r.Index == x)).ToArray());
                var _columns   = new SymbolInfo[12];
                for (var i = 0; i < 6; i++)
                {
                    var f = rnd.Next(0, 2);
                    _columns[2 * i]     = new SymbolInfo(columnsRaw[i], f == 0);
                    _columns[2 * i + 1] = new SymbolInfo(columnsRaw[i], f != 0);
                }

                _rules = new XRayRules(_columns, _rows, _3x3, GenerateTableOfNumbers(rnd));
            }
            _ruleSeededRules[rnd.Seed] = _rules;
        }

        Initialize();
    }
    protected override void DoStart()
    {
        // Start of rule-seed code
        var rnd = RuleSeedable.GetRNG();

        Log("Using rule seed: {0}", rnd.Seed);

        var colors = _allColors.ToArray();

        _table = new AdjacentColors[16];
        for (var row = 0; row < 16; row++)
        {
            rnd.ShuffleFisherYates(colors);
            var theseColors = colors.Where(c => c != _allColors[row]).ToArray();
            _table[row].LeftRight = theseColors.Take(3).ToArray();
            _table[row].UpDown    = theseColors.Skip(3).Take(3).ToArray();
            LogDebug("Row {0}: LR {1} // UD {2}", _allColors[row], _table[row].LeftRight.JoinString(", "), _table[row].UpDown.JoinString(", "));
        }
        // End of rule-seed code

        SetInitialState();
    }
Example #5
0
    protected override void DoStart()
    {
        var rnd = RuleSeedable.GetRNG();

        Log("Using rule seed: {0}", rnd.Seed);
        if (rnd.Seed == 1)
        {
            _table = newArray(
                // false = Column; true = Row
                new object[] { SquareColor.Blue, false, SquareColor.Red, SquareColor.Yellow, true, SquareColor.Green, SquareColor.Magenta },
                new object[] { true, SquareColor.Green, SquareColor.Blue, SquareColor.Magenta, SquareColor.Red, false, SquareColor.Yellow },
                new object[] { SquareColor.Yellow, SquareColor.Magenta, SquareColor.Green, true, SquareColor.Blue, SquareColor.Red, false },
                new object[] { SquareColor.Blue, SquareColor.Green, SquareColor.Yellow, false, SquareColor.Red, true, SquareColor.Magenta },
                new object[] { SquareColor.Yellow, true, SquareColor.Blue, SquareColor.Magenta, false, SquareColor.Red, SquareColor.Green },
                new object[] { SquareColor.Magenta, SquareColor.Red, SquareColor.Yellow, SquareColor.Green, false, SquareColor.Blue, true },
                new object[] { SquareColor.Green, true, false, SquareColor.Blue, SquareColor.Magenta, SquareColor.Yellow, SquareColor.Red },
                new object[] { SquareColor.Magenta, SquareColor.Red, SquareColor.Green, SquareColor.Blue, SquareColor.Yellow, false, true },
                new object[] { false, SquareColor.Yellow, SquareColor.Red, SquareColor.Green, true, SquareColor.Magenta, SquareColor.Blue },
                new object[] { SquareColor.Green, false, true, SquareColor.Red, SquareColor.Magenta, SquareColor.Blue, SquareColor.Yellow },
                new object[] { SquareColor.Red, SquareColor.Yellow, true, false, SquareColor.Green, SquareColor.Magenta, SquareColor.Blue },
                new object[] { false, SquareColor.Blue, SquareColor.Magenta, SquareColor.Red, SquareColor.Yellow, true, SquareColor.Green },
                new object[] { true, SquareColor.Magenta, false, SquareColor.Yellow, SquareColor.Blue, SquareColor.Green, SquareColor.Red },
                new object[] { SquareColor.Red, SquareColor.Blue, SquareColor.Magenta, true, SquareColor.Green, SquareColor.Yellow, false },
                new object[] { false, true, false, true, false, true, false }
                );
        }
        else
        {
            var candidates = new object[] { SquareColor.Blue, false, SquareColor.Red, SquareColor.Yellow, true, SquareColor.Green, SquareColor.Magenta };
            _table = new object[15][];
            for (int i = 0; i < 14; i++)
            {
                _table[i] = rnd.ShuffleFisherYates(candidates).ToArray();
            }
            _table[14] = new object[] { false, true, false, true, false, true, false };
        }

        SetInitialState();
    }
Example #6
0
    protected override void DoStart()
    {
        var rnd = RuleSeedable.GetRNG();

        Log("Using rule seed: {0}", rnd.Seed);

        var shapes      = new List <bool[, ]>();
        var extraShapes = rnd.ShuffleFisherYates(_sometimesShapes.ToArray());

        for (var i = 0; i < 18; i++)
        {
            shapes.Add(extraShapes[i]);
        }

        // Sneaky! Put the two “alwaysShapes” in the right place to recreate original rules under Seed #1
        shapes.Insert(8, _alwaysShapes[0]);
        shapes.Insert(8, _alwaysShapes[1]);
        rnd.ShuffleFisherYates(shapes);

        _table = newArray(
            new bool[][, ] {
            null, shapes[0], shapes[1], shapes[2], shapes[3]
        },
            new bool[][, ] {
            shapes[4], null, shapes[5], shapes[6], shapes[7]
        },
            new bool[][, ] {
            shapes[8], shapes[9], null, shapes[10], shapes[11]
        },
            new bool[][, ] {
            shapes[12], shapes[13], shapes[14], null, shapes[15]
        },
            new bool[][, ] {
            shapes[16], shapes[17], shapes[18], shapes[19], null
        });

        SetStage(isStart: true);
    }
    protected override void DoStart()
    {
        var rnd = RuleSeedable.GetRNG();

        Log("Using rule seed: {0}", rnd.Seed);

        var skip = rnd.Next(0, 50);

        for (var i = 0; i < skip; i++)
        {
            rnd.NextDouble();
        }

        _direction = rnd.Next(0, 8);

        _squareForFlowchartStartColumn = rnd.Next(0, 16);
        _squareForFlowchartStartRow    = rnd.Next(0, 15);
        if (_squareForFlowchartStartRow >= _squareForFlowchartStartColumn)
        {
            _squareForFlowchartStartRow++;
        }

        var subsets   = new List <HashSet <SquareColor> >();
        var colorList = new List <SquareColor>();

        for (var i = 0; i < 32; i++)
        {
            colorList.Clear();
            for (var j = 0; j < 5; j++)
            {
                if ((i & (1 << j)) != 0)
                {
                    colorList.Add(_usefulColors[j]);
                }
            }
            rnd.ShuffleFisherYates(colorList); // this has no impact on the module, but the manual does this
            subsets.Add(new HashSet <SquareColor>(colorList));
        }
        rnd.ShuffleFisherYates(subsets);

        var pointedAt = new bool[36];

        _pointsAtY = new int[36];
        _pointsAtN = new int[36];
        var missingCells = new List <int>();

        do
        {
            missingCells.Clear();

            _flowchartStartColumnFromColor = rnd.ShuffleFisherYates(Enumerable.Range(0, 6).ToArray());
            for (var i = 0; i < 6; i++)
            {
                missingCells.Add(_flowchartStartColumnFromColor[5] + 6 * i);
            }

            _flowchartStartRowFromColor = rnd.ShuffleFisherYates(_flowchartStartColumnFromColor.ToArray());
            for (var i = 0; i < 6; i++)
            {
                if (!missingCells.Contains(i + 6 * _flowchartStartRowFromColor[5]))
                {
                    missingCells.Add(i + 6 * _flowchartStartRowFromColor[5]);
                }
            }

            for (var ix = 0; ix < 36; ix++)
            {
                pointedAt[ix] = false;
            }

            rnd.ShuffleFisherYates(missingCells);
            missingCells.RemoveRange(4, missingCells.Count - 4);

            var pointsAtSquare = new Func <int, int, int?>((px, dir) =>
            {
                var x = px % 6;
                var y = (px / 6) | 0;
                do
                {
                    x += _flowChartDeltaX[dir];
                    y += _flowChartDeltaY[dir];
                    if (x < 0 || x >= 6 || y < 0 || y >= 6)
                    {
                        return(null);
                    }
                }while (missingCells.Contains(x + 6 * y));
                return(x + 6 * y);
            });

            _flowchart = new HashSet <SquareColor> [36];
            for (var ix = 0; ix < 36; ix++)
            {
                if (missingCells.Contains(ix))
                {
                    continue;
                }

                var dirs = new List <int?>();
                for (var dir = 0; dir < 4; dir++)
                {
                    if (pointsAtSquare(ix, dir) != null)
                    {
                        dirs.Add(dir);
                    }
                }
                rnd.ShuffleFisherYates(dirs);
                dirs.RemoveRange(2, dirs.Count - 2);    // 0 = no, 1 = yes

                var sbstIx = ix - missingCells.Count(cel => cel < ix);
                _flowchart[ix] = subsets[sbstIx];
                if (subsets[sbstIx].Count == 0)
                {
                    dirs[1] = null;
                }
                else if (subsets[sbstIx].Count == 5)
                {
                    dirs[0] = null;
                }

                for (var yn = 0; yn < 2; yn++)
                {
                    if (dirs[yn] == null)
                    {
                        continue;
                    }
                    var target = pointsAtSquare(ix, dirs[yn].Value);
                    (yn == 0 ? _pointsAtN : _pointsAtY)[ix] = target.Value;
                    pointedAt[target.Value] = true;
                }
            }
        }while (pointedAt.Where((p, pIx) => !p && (!missingCells.Contains(pIx))).Any());

        SetInitialState();
    }
Example #8
0
    protected override void StartModule()
    {
        _moduleId = _moduleIdCounter++;
        _isSolved = false;

        var rnd = RuleSeedable.GetRNG();

        Debug.LogFormat("[Not X-Ray #{0}] Using rule seed: {1}", _moduleId, rnd.Seed);

        // RULE SEED
        if (_ruleSeededRules.ContainsKey(rnd.Seed))
        {
            _rules = _ruleSeededRules[rnd.Seed];
        }
        else
        {
            var _tables     = new SymbolInfo[8][];
            var _notWallses = new int[8][];
            var sqs         = Enumerable.Range(0, 49).Where(c => c != 0 && c != 6 && c != 42 && c != 48 && c != 24).ToArray();

            // First 55 symbols can be flipped, next 55 cannot
            const int numFlippable       = 55;
            const int numUnflippable     = 55;
            var       unflippableSymbols = rnd.ShuffleFisherYates(Enumerable.Range(0, numUnflippable).Select(c => numFlippable + c).ToArray());
            var       flippableSymbols   = rnd.ShuffleFisherYates(Enumerable.Range(0, numFlippable).ToArray());

            var combinations = new List <int[]>();
            for (var ai = 0; ai < sqs.Length; ai++)
            {
                for (var bi = ai + 1; bi < sqs.Length; bi++)
                {
                    if (sqs[bi] / 7 > sqs[ai] / 7 && sqs[bi] % 7 < sqs[ai] % 7)
                    {
                        for (var ci = ai + 1; ci < sqs.Length; ci++)
                        {
                            if (ci != bi && sqs[ci] / 7 > sqs[ai] / 7 && sqs[ci] % 7 > sqs[ai] % 7 && sqs[ci] % 7 > sqs[bi] % 7)
                            {
                                for (var di = Math.Max(bi, ci) + 1; di < sqs.Length; di++)
                                {
                                    if (sqs[di] / 7 > sqs[bi] / 7 && sqs[di] / 7 > sqs[ci] / 7 && sqs[di] % 7 > sqs[bi] % 7 && sqs[di] % 7 < sqs[ci] % 7)
                                    {
                                        combinations.Add(new int[] { sqs[ai], sqs[bi], sqs[ci], sqs[di] });
                                    }
                                }
                            }
                        }
                    }
                }
            }

            for (var tableIx = 0; tableIx < 8; tableIx++)
            {
                var symbols = new List <SymbolInfo>();
                for (var i = 0; i < 4; i++)
                {
                    symbols.Add(new SymbolInfo(flippableSymbols[tableIx * 4 + i], false));
                }
                for (var i = 0; i < 4; i++)
                {
                    symbols.Add(new SymbolInfo(flippableSymbols[tableIx * 4 + i], true));
                }
                for (var i = 0; i < 3; i++)
                {
                    symbols.Add(new SymbolInfo(unflippableSymbols[tableIx * 3 + i], false));
                }

                // generate maze
                const int w = 7, h = 7;
                var       notWalls = new List <int>(); // (cell << 1) + (right ? 1 : 0)
                var       todo     = Enumerable.Range(0, 49).Where(c => c != 0 && c != 6 && c != 42 && c != 48).ToList();
                var       active   = new List <int>();

                var start = rnd.Next(0, todo.Count);
                active.Add(todo[start]);
                todo.RemoveAt(start);

                while (todo.Count > 0)
                {
                    var activeIx = rnd.Next(0, active.Count);
                    var sq       = active[activeIx];
                    var adjs     = new List <int>();
                    if ((sq % w) > 0 && todo.Contains(sq - 1))
                    {
                        adjs.Add(sq - 1);
                    }
                    if ((sq % w) < w - 1 && todo.Contains(sq + 1))
                    {
                        adjs.Add(sq + 1);
                    }
                    if (((sq / w) | 0) > 0 && todo.Contains(sq - w))
                    {
                        adjs.Add(sq - w);
                    }
                    if (((sq / w) | 0) < h - 1 && todo.Contains(sq + w))
                    {
                        adjs.Add(sq + w);
                    }

                    if (adjs.Count == 0)
                    {
                        active.RemoveAt(activeIx);
                        continue;
                    }

                    var adj = adjs[rnd.Next(0, adjs.Count)];
                    todo.RemoveAt(todo.IndexOf(adj));
                    active.Add(adj);

                    if (adj == sq - 1)
                    {
                        notWalls.Add((adj << 1) | 1);
                    }
                    else if (adj == sq + 1)
                    {
                        notWalls.Add((sq << 1) | 1);
                    }
                    else if (adj == sq - w)
                    {
                        notWalls.Add(adj << 1);
                    }
                    else if (adj == sq + w)
                    {
                        notWalls.Add(sq << 1);
                    }
                }


                // generate symbol arrangements

                var backtracks = 0;
                Func <int, int[][], List <int[]> > findArrangement = null;
                findArrangement = (numSofar, combinationsLeft) =>
                {
                    if (numSofar == 11)
                    {
                        return(new List <int[]>());
                    }
                    if (combinationsLeft.Length == 0)
                    {
                        return(null);
                    }

                    var offset = rnd.Next(0, combinationsLeft.Length);
                    for (var ir = 0; ir < combinationsLeft.Length; ir++)
                    {
                        var i           = (ir + offset) % combinationsLeft.Length;
                        var combination = combinationsLeft[i];
                        var combLeft    = combinationsLeft.Where(cmb => cmb.All(c => !combination.Contains(c))).ToArray();
                        var result      = findArrangement(numSofar + 1, combLeft);
                        if (result != null)
                        {
                            result.Add(combination);
                            return(result);
                        }
                        if (backtracks > 500)
                        {
                            return(null);
                        }
                    }
                    backtracks++;
                    return(null);
                };

                List <int[]> arrangement;
                do
                {
                    backtracks  = 0;
                    arrangement = findArrangement(0, combinations.ToArray());
                }while (arrangement == null);


                // generate symbol table
                var table = new SymbolInfo[49];
                for (var cell = 0; cell < 49; cell++)
                {
                    if (cell == 0 || cell == 6 || cell == 42 || cell == 48 || cell == 24)
                    {
                        continue;
                    }

                    var arrIx = arrangement.IndexOf(comb => comb.Contains(cell));
                    table[cell] = symbols[arrIx];
                }

                _tables[tableIx]     = table;
                _notWallses[tableIx] = notWalls.ToArray();
            }

            _rules = new NotXRayRules(_tables, _notWallses);
            _ruleSeededRules[rnd.Seed] = _rules;
        }
        // END RULE SEED

        Initialize();
    }