Ejemplo n.º 1
0
        public static Instruction[,] GetRules(int ruleSeed)
        {
            var random  = new MonoRandom(ruleSeed);
            var weights = new WeightMap <Instruction, string>(i => i.Key);
            var rules   = new Instruction[NumStages, 4];

            for (int i = 0; i < NumStages; ++i)
            {
                for (int j = 0; j < 4; ++j)
                {
                    var digit = random.Next(1, 5);
                    var stage = random.Next(1, i + 1);

                    var instructions = new List <Instruction>()
                    {
                        Instruction.Position1, Instruction.Position2, Instruction.Position3, Instruction.Position4, Instruction.PressDigit(digit)
                    };
                    if (i > 0)
                    {
                        var instruction = i % 2 == 0 ? Instruction.PressLabelFromStage(stage) :
                                          Instruction.PressPositionFromStage(stage);
                        if (i > 2)
                        {
                            weights.SetWeight(instruction, 1);
                        }
                        instructions.Add(instruction);
                    }

                    var instruction2 = weights.Roll(instructions, random);
                    rules[i, j] = instruction2;
                }
            }
            return(rules);
        }
Ejemplo n.º 2
0
        public static Rule[][] GetRules(int ruleSeed)
        {
            if (ruleSeed == 1)
            {
                return(new[] {
                    // 3 wires
                    new[] {
                        new Rule(new[] { NoColourWire.GetCondition(Colour.Red) }, new Instruction(CutWire1)),
                        new Rule(new[] { LastWireIsColour.GetCondition(Colour.White) }, new Instruction(CutWireLast)),
                        new Rule(new[] { MoreThanOneColourWire.GetCondition(Colour.Blue) }, new Instruction(CutWireColourLast, Colour.Blue)),
                        new Rule(new Instruction(CutWireLast))
                    },
                    // 4 wires
                    new[] {
                        new Rule(new[] { MoreThanOneColourWire.GetCondition(Colour.Red), Condition <Colour[]> .SerialNumberIsOdd() }, new Instruction(CutWireColourLast, Colour.Red)),
                        new Rule(new[] { LastWireIsColour.GetCondition(Colour.Yellow), NoColourWire.GetCondition(Colour.Red) }, new Instruction(CutWire0)),
                        new Rule(new[] { ExactlyOneColourWire.GetCondition(Colour.Blue) }, new Instruction(CutWire0)),
                        new Rule(new[] { MoreThanOneColourWire.GetCondition(Colour.Yellow) }, new Instruction(CutWireLast)),
                        new Rule(new Instruction(CutWire1))
                    },
                    // 5 wires
                    new[] {
                        new Rule(new[] { LastWireIsColour.GetCondition(Colour.Black), Condition <Colour[]> .SerialNumberIsOdd() }, new Instruction(CutWire3)),
                        new Rule(new[] { ExactlyOneColourWire.GetCondition(Colour.Red), MoreThanOneColourWire.GetCondition(Colour.Yellow) }, new Instruction(CutWire0)),
                        new Rule(new[] { NoColourWire.GetCondition(Colour.Black) }, new Instruction(CutWire1)),
                        new Rule(new Instruction(CutWire0))
                    },
                    // 6 wires
                    new[] {
                        new Rule(new[] { NoColourWire.GetCondition(Colour.Yellow), Condition <Colour[]> .SerialNumberIsOdd() }, new Instruction(CutWire2)),
                        new Rule(new[] { ExactlyOneColourWire.GetCondition(Colour.Yellow), MoreThanOneColourWire.GetCondition(Colour.White) }, new Instruction(CutWire3)),
                        new Rule(new[] { NoColourWire.GetCondition(Colour.Red) }, new Instruction(CutWireLast)),
                        new Rule(new Instruction(CutWire3))
                    }
                });
            }

            var random   = new MonoRandom(ruleSeed);
            var ruleSets = new Rule[4][];

            for (int i = 3; i <= 6; ++i)
            {
                ConditionType[][] list;
                var conditionWeights   = new WeightMap <ConditionType, string>(c => c.Key);
                var instructionWeights = new WeightMap <InstructionType, string>(s => s.Key);
                var list2 = new List <Rule>();
                if (ruleSeed == 1)
                {
                    list = new[] {
                        new[] { new ConditionType(Condition <Colour[]> .SerialNumberStartsWithLetter()), new ConditionType(Condition <Colour[]> .SerialNumberIsOdd()) },
                        new[] { ExactlyOneColourWire, NoColourWire, LastWireIsColour, MoreThanOneColourWire }
                    }
                }
                ;
                else
                {
                    list = new[] {
                        new[] { new ConditionType(Condition <Colour[]> .SerialNumberStartsWithLetter()), new ConditionType(Condition <Colour[]> .SerialNumberIsOdd()) },
                        new[] { ExactlyOneColourWire, NoColourWire, LastWireIsColour, MoreThanOneColourWire },
                        new[] {
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.DviD)),
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.PS2)),
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.RJ45)),
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.StereoRCA)),
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.Parallel)),
                            new ConditionType(Condition <Colour[]> .PortExactKey(PortType.Serial)),
                            new ConditionType(Condition <Colour[]> .EmptyPortPlate())
                        }
                    }
                };

                var rules = new Rule[random.NextDouble() < 0.6 ? 3 : 4];
                ruleSets[i - 3] = rules;
                for (int j = 0; j < rules.Length; ++j)
                {
                    var colours = new List <Colour>(WiresSolver.colours);
                    var list3   = new List <Colour>();

                    var conditions = new Condition <Colour[]> [random.NextDouble() < 0.6 ? 1: 2];
                    var num        = i - 1;
                    for (int k = 0; k < conditions.Length; ++k)
                    {
                        var possibleQueryableProperties = GetPossibleConditions(list, num, k > 0);
#if TRACE
                        if (System.Diagnostics.Debugger.IsAttached)
                        {
                            System.Diagnostics.Trace.WriteLine("queryWeights:");
                            foreach (var entry in conditionWeights)
                            {
                                System.Diagnostics.Trace.WriteLine($"  -- {entry.Key} = {entry.Value}");
                            }
                        }
#endif
                        var conditionType = conditionWeights.Roll(possibleQueryableProperties, random, 0.1f);
                        if (conditionType.UsesColour)
                        {
                            num -= conditionType.WiresInvolved;

                            var i4     = random.Next(0, colours.Count);
                            var colour = colours[i4];
                            colours.RemoveAt(i4);
                            if (conditionType.ColourAvailableForSolution)
                            {
                                list3.Add(colour);
                            }

                            conditions[k] = conditionType.GetCondition(colour);
                        }
                        else
                        {
                            conditions[k] = conditionType.GetCondition(0);
                        }
                    }

                    var         instructions = GetPossibleInstructions(i, conditions);
                    Instruction solution;
                    var         instructionType = instructionWeights.Roll(instructions, random);
                    if (list3.Count > 0)
                    {
                        solution = new Instruction(instructionType, list3[random.Next(0, list3.Count)]);
                    }
                    else
                    {
                        solution = new Instruction(instructionType);
                    }

                    var rule = new Rule(conditions, solution);
                    if (ruleSeed == 1 || rule.IsValid)
                    {
                        list2.Add(rule);
                    }
                    else
                    {
                        --j;
                    }
                }

                Utils.StableSort(list2, r => - r.Queries.Length);

                var list4 = GetPossibleInstructions(i, null);
                if (ruleSeed != 1)
                {
                    // Remove redundant rules.
                    var forbiddenId = list2[list2.Count - 1].Solution.Type.Key;
                    list4.RemoveAll(l => l.Key == forbiddenId);
                }
                list2.Add(new Rule(new Instruction(random.Pick(list4), null)));
                ruleSets[i - 3] = list2.ToArray();
            }
            return(ruleSets);
        }
Ejemplo n.º 3
0
 private static InitialRule CreateInitialRule(List <Condition <ButtonData> > conditions, WeightMap <InitialSolution, InitialSolution> weights, Random random)
 {
     return(new InitialRule(conditions, weights.Roll(GetInitialSolutions(true), random)));
 }
Ejemplo n.º 4
0
 private static HeldRule CreateHeldRule(Colour?colour, WeightMap <HeldSolution, string> weights, Random random)
 {
     return(new HeldRule(colour, weights.Roll(GetHeldSolutions(), random)));
 }
Ejemplo n.º 5
0
        private static void RemoveRedundantRules(List <InitialRule> rules, WeightMap <InitialSolution, InitialSolution> weights, Random random, List <Condition <ButtonData> > PrimaryQueryList, List <Condition <ButtonData> > SecondaryQueryList)
        {
            // Since the last rule always has the instruction 'hold the button',
            // force the second-last one to have a different instruction.
            if (rules[rules.Count - 2].Solution == InitialSolution.Hold)
            {
                rules[rules.Count - 2] = new InitialRule(rules[rules.Count - 2].Conditions, weights.Roll(GetInitialSolutions(false), random));
            }

            var             twobattery   = -1;
            var             onebattery   = -1;
            InitialSolution?solution     = null;
            var             samesolution = true;

            for (var i = rules.Count - 1; i >= 0; i--)
            {
                var condition = rules[i].Conditions.FirstOrDefault(c => c.Key == nameof(Condition <ButtonData> .MoreThanNBatteries));
                if (condition != null)
                {
                    if (condition.Text.Contains("2"))
                    {
                        twobattery = i;
                        if (onebattery > -1)
                        {
                            samesolution &= rules[i].Solution == solution;
                            break;
                        }
                        solution = rules[i].Solution;
                    }
                    else if (condition.Text.Contains("1"))
                    {
                        onebattery = i;
                        if (twobattery > -1)
                        {
                            samesolution &= rules[i].Solution == solution;
                            break;
                        }
                        solution = rules[i].Solution;
                    }
                }
                if (solution.HasValue)
                {
                    samesolution &= rules[i].Solution == solution;
                }
            }
            if (onebattery == -1 || twobattery == -1)
            {
                return;
            }

            if (onebattery < twobattery && rules[onebattery].Conditions.Count == 1)
            {
                // We have a 'if there is more than 1 battery' rule above a 'if there are more than 2 batteries' rules.
                if (random.Next(2) == 0)
                {
                    rules[onebattery].Conditions.Add(Utils.RemoveRandom(SecondaryQueryList, random));
                }
                else
                {
                    rules[onebattery].Conditions[0] = Utils.RemoveRandom(PrimaryQueryList, random);
                }
            }
            else if (rules[onebattery].Conditions.Count == 1 && rules[twobattery].Conditions.Count == 1 && samesolution)
            {
                // We have a 'if there is more than 1 battery' rule below a 'if there are more than 2 batteries' rules,
                // and every rule in between has the same instruction.
                switch (random.Next(7))
                {
                //Add a secondary query to one or both of the battery rules
                case 0:
                    rules[onebattery].Conditions.Add(Utils.RemoveRandom(SecondaryQueryList, random));
                    break;

                case 1:
                    rules[twobattery].Conditions.Add(Utils.RemoveRandom(SecondaryQueryList, random));
                    break;

                case 2:
                    rules[twobattery].Conditions.Add(Utils.RemoveRandom(SecondaryQueryList, random));
                    goto case 0;

                //Replace one or both of the battery rules with a new primary query
                case 3:
                    rules[onebattery].Conditions[0] = Utils.RemoveRandom(PrimaryQueryList, random);
                    break;

                case 4:
                    rules[twobattery].Conditions[0] = Utils.RemoveRandom(PrimaryQueryList, random);
                    break;

                case 5:
                    rules[twobattery].Conditions[0] = Utils.RemoveRandom(PrimaryQueryList, random);
                    goto case 3;

                //Replace one of the solutions in between the minimum and maximum battery.
                default:
                    var replacementsolution = rules[onebattery].Solution == InitialSolution.Tap ? InitialSolution.Hold : InitialSolution.Tap;
                    if (Math.Abs(onebattery - twobattery) == 1)
                    {
                        rules[Math.Min(onebattery, twobattery)].Solution = replacementsolution;
                    }
                    else
                    {
                        rules[random.Next(Math.Min(onebattery, twobattery), Math.Max(onebattery, twobattery))].Solution = replacementsolution;
                    }
                    break;
                }
            }
        }