Пример #1
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);
        }
Пример #2
0
        public static RuleSet GetRules(int ruleSeed)
        {
            if (ruleSeed == 1)
            {
                return(new RuleSet(
                           new[] {
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        ButtonColour(Colour.Blue), ButtonLabel(Label.Abort)
                    }, InitialSolution.Hold),
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        Condition <ButtonData> .MoreThanNBatteries(1), ButtonLabel(Label.Detonate)
                    }, InitialSolution.Tap),
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        ButtonColour(Colour.White), Condition <ButtonData> .IndicatorLit("CAR")
                    }, InitialSolution.Hold),
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        Condition <ButtonData> .MoreThanNBatteries(2), Condition <ButtonData> .IndicatorLit("FRK")
                    }, InitialSolution.Tap),
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        ButtonColour(Colour.Yellow)
                    }, InitialSolution.Hold),
                    new InitialRule(new List <Condition <ButtonData> >()
                    {
                        ButtonColour(Colour.Red), ButtonLabel(Label.Hold)
                    }, InitialSolution.Tap),
                    new InitialRule(InitialSolution.Hold)
                },
                           new[] {
                    new HeldRule(Colour.Blue, new HeldSolution(HeldSolutionType.ReleaseOnTimerDigit, 4)),
                    new HeldRule(Colour.White, new HeldSolution(HeldSolutionType.ReleaseOnTimerDigit, 1)),
                    new HeldRule(Colour.Yellow, new HeldSolution(HeldSolutionType.ReleaseOnTimerDigit, 5)),
                    new HeldRule(null, new HeldSolution(HeldSolutionType.ReleaseOnTimerDigit, 1)),
                }
                           ));
            }

            var random                    = new MonoRandom(ruleSeed);
            var conditionWeights          = new WeightMap <Condition <ButtonData>, string>(c => c.Key);
            var initialInstructionWeights = new WeightMap <InitialSolution, InitialSolution>(s => s);

            initialInstructionWeights.SetWeight(InitialSolution.Tap, 0.1f);
            initialInstructionWeights.SetWeight(InitialSolution.TapWhenSecondsMatch, 0.05f);
            var heldInstructionWeights = new WeightMap <HeldSolution, string>(s => s.Key);

            // Build condition lists.
            var PrimaryConditions = new List <Condition <ButtonData> >()
            {
                ButtonColour(Colour.Red), ButtonColour(Colour.Blue), ButtonColour(Colour.Yellow), ButtonColour(Colour.White), Condition <ButtonData> .MoreThanNBatteries(1), Condition <ButtonData> .MoreThanNBatteries(2)
            };
            var IndicatorColorConditions = new List <Colour?>()
            {
                Colour.Red, Colour.Blue, Colour.Yellow, Colour.White
            };
            var SecondaryConditions = new List <Condition <ButtonData> >()
            {
                ButtonLabel(Label.Press), ButtonLabel(Label.Hold), ButtonLabel(Label.Abort), ButtonLabel(Label.Detonate)
            };

            for (int i = 0; i < 3; ++i)
            {
                SecondaryConditions.Add(Condition <ButtonData> .IndicatorLit(random.Pick(Utils.IndicatorLabels)));
            }

            var ports = new List <PortType>()
            {
                PortType.DviD, PortType.PS2, PortType.RJ45, PortType.StereoRCA, PortType.Parallel, PortType.Serial
            };

            for (int i = 0; i < 3; ++i)
            {
                var port = Utils.RemoveRandom(ports, random);
                SecondaryConditions.Add(Condition <ButtonData> .Port(port));
            }
            foreach (var port in ports)
            {
                PrimaryConditions.Add(Condition <ButtonData> .Port(port));
            }
            PrimaryConditions.Add(Condition <ButtonData> .EmptyPortPlate());
            SecondaryConditions.Add(Condition <ButtonData> .SerialNumberStartsWithLetter());
            SecondaryConditions.Add(Condition <ButtonData> .SerialNumberIsOdd());

            // Generate initial rules.
            var initialRules = new List <InitialRule>();

            while (initialRules.Count < MaxInitialRules && PrimaryConditions.Count > 0)
            {
                var query = Utils.RemoveRandom(PrimaryConditions, random);
                if (random.Next(2) == 0)
                {
                    initialRules.Add(CreateInitialRule(new List <Condition <ButtonData> >()
                    {
                        query
                    }, initialInstructionWeights, random));
                }
                else
                {
                    initialRules.Add(CreateInitialRule(new List <Condition <ButtonData> >()
                    {
                        query, Utils.RemoveRandom(SecondaryConditions, random)
                    }, initialInstructionWeights, random));
                }
            }
            initialRules.Add(new InitialRule(InitialSolution.Hold));

            // Generate held rules.
            var heldRules = new List <HeldRule>();

            while (heldRules.Count < MaxHeldRules && IndicatorColorConditions.Count > 0)
            {
                var condition = Utils.RemoveRandom(IndicatorColorConditions, random);
                heldRules.Add(CreateHeldRule(condition, heldInstructionWeights, random));
            }
            heldRules.Add(CreateHeldRule(null, heldInstructionWeights, random));

            // Remove redundant rules.
            RemoveRedundantRules(initialRules, initialInstructionWeights, random, PrimaryConditions, SecondaryConditions);

            return(new RuleSet(initialRules.ToArray(), heldRules.ToArray()));
        }