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); }
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())); }