/// <summary> /// Cycles through the UI depending on the button pushed. /// </summary> /// <param name="num">The index for the 4 buttons.</param> protected internal void PressButton(ref byte num) { // Plays button sound effect. reversal.Audio.PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.ButtonPress, reversal.Buttons[num].transform); reversal.Buttons[num].AddInteractionPunch(); // If lights are off or the module is solved, the buttons should do nothing. if (!init.Ready || init.Solved) { return; } int length = init.Conditions.GetLength(0) * init.Conditions.GetLength(1); switch (ButtonOrder[num]) { // Subtract 1 from the current selected wire. case 0: reversal.Audio.PlaySoundAtTransform(Sounds.Rrr.Button(4), reversal.Buttons[num].transform); WireSelected = ((WireSelected + 7) % 9) + 1; selectWire = true; break; // Read previous instruction. case 1: reversal.Audio.PlaySoundAtTransform(Sounds.Rrr.Button(2), reversal.Buttons[num].transform); if (selectWire) { return; } Instruction = (--Instruction + length) % length; break; // Read next instruction. case 2: reversal.Audio.PlaySoundAtTransform(Sounds.Rrr.Button(1), reversal.Buttons[num].transform); if (selectWire) { return; } Instruction = ++Instruction % length; break; // Add 1 to the current selected wire. case 3: reversal.Audio.PlaySoundAtTransform(Sounds.Rrr.Button(3), reversal.Buttons[num].transform); WireSelected = (WireSelected % 9) + 1; selectWire = true; break; } coroutines.UpdateScreen(instructionX: Instruction / init.Conditions.GetLength(1), instructionY: Instruction % init.Conditions.GetLength(1), wireSelected: ref WireSelected, isSelectingWire: ref selectWire); }
/// <summary> /// Scans through the condition's properties to determine the answer of the module. /// </summary> /// <param name="Seed">The seed in base 10.</param> /// <returns>Returns the answer, if the answer is null then any wire can be cut.</returns> private int?GetAnswer(int[] wires, ref int lookup, ref bool discard, ref bool append) { int wireSelected = 1, wireCount = wires.Length - 2, iMax = init.Conditions.GetLength(1); bool isSelectingWire = false; string[] discardValues = new[] { "-2", "-1", "1", "2" }; coroutines.UpdateScreen(instructionX: 0, instructionY: 0, wireSelected: ref wireSelected, isSelectingWire: ref isSelectingWire); bool shouldRun = wireCount >= 0 && wireCount <= 7; for (int i = 0; i < iMax && shouldRun; i++) { // If true, set the current index to the Skip property. if (init.Conditions[wireCount, i].Skip != null) { int?skipValue = init.Conditions[wireCount, i].Skip; if (skipValue < 1 || skipValue > iMax) { throw new IndexOutOfRangeException("[Reformed Role Reversal #" + init.ModuleId + "]: Condition [" + wireCount + ", " + i + "] returned " + init.Conditions[wireCount, i].Skip + " for parameter \"Skip\"! This should not happen under normal circumstances, as the specified condition doesn't exist."); } Debug.LogFormat("[Reformed Role Reversal #{0}]: <Condition {1}, {2}> \"{3}\" is true, skip to section {4}.", init.ModuleId, wireCount + 2, i + 1, init.Conditions[wireCount, i].Text, init.Conditions[wireCount, i].Skip); i = (int)skipValue - 1; } // If true, regenerate a set of conditions and refer the index to the new conditions. if (init.Conditions[wireCount, i].Discard != null) { int?discardValue = init.Conditions[wireCount, i].Discard; if (!discardValues.Contains(discardValue.ToString())) { throw new ArgumentOutOfRangeException("[Reformed Role Reversal #" + init.ModuleId + "]: Condition [" + wireCount + ", " + i + "] returned " + discardValue + " for parameter \"Discard\"! This should not happen under normal circumstances, as it should only return -2, -1, 1, or 2."); } Debug.LogFormat("[Reformed Role Reversal #{0}]: <Condition {1}, {2}> \"{3}\" is true, discard the {4}{5} wire{6}.", init.ModuleId, wireCount + 2, i + 1, init.Conditions[wireCount, i].Text, Math.Abs((int)discardValue) > 1 ? Math.Abs((int)discardValue) + " " : string.Empty, discardValue < 0 ? "leftmost" : "rightmost", Math.Abs((int)discardValue) > 1 ? "s" : string.Empty); wires = Algorithms.SubArray(wires, discardValue < 0 ? Math.Abs((int)discardValue) : 0, wires.Length - Math.Abs((int)discardValue)); // Log the list of all wires, converting each index to the respective string. string[] log = new string[wires.Length]; for (int j = 0; j < wires.Length; j++) { log[j] += j == wires.Length - 1 ? "and " + Arrays.Colors[wires[j]] : Arrays.Colors[wires[j]]; } Debug.LogFormat("[Reformed Role Reversal #{0}]: The wires are now {1}.", init.ModuleId, log.Join(", ")); coroutines.GenerateSetOfConditions(wires.Length - 2, wires, ref lookup, ref discard, ref append); // This method will run again from the generate set of conditions. An answer has not been determined yet. return(null); } // If true, regenerate a set of conditions and refer the index to the new conditions. if (init.Conditions[wireCount, i].Append != null && init.Conditions[wireCount, i].Append != null) { int[] appendValue = init.Conditions[wireCount, i].Append; int minValue = 10, maxValue = 0; for (int j = 0; j < appendValue.Length; j++) { if (appendValue[j] < minValue) { minValue = appendValue[j]; } if (appendValue[j] > maxValue) { maxValue = appendValue[j]; } } if (appendValue.Min() < 0 || appendValue.Max() > 9) { throw new ArgumentOutOfRangeException("[Reformed Role Reversal #" + init.ModuleId + "]: Condition [" + wireCount + ", " + i + "] returned " + init.Conditions[wireCount, i].Append.Join(", ") + " for parameter \"Append\"! This should not happen under normal circumstances, as all values should be between 0 through 9."); } Debug.LogFormat("[Reformed Role Reversal #{0}]: <Condition {1}, {2}> \"{3}\" is true, append the wires to the {4}.", init.ModuleId, wireCount + 2, i + 1, init.Conditions[wireCount, i].Text, append ? "left" : "right"); Array.Resize(ref wires, wires.Length + appendValue.Length); while (Seed.Length < 9) { Seed = append ? 'X' + Seed : Seed + 'X'; } // Append right. if (!append) { Array.Copy(appendValue, 0, wires, wires.Length - appendValue.Length, appendValue.Length); } // Append left. else { Array.Copy(wires, 0, wires, appendValue.Length, wires.Length - appendValue.Length); Array.Copy(appendValue, 0, wires, 0, appendValue.Length); } // Log the list of all wires, converting each index to the respective string. string[] log = new string[wires.Length]; for (int j = 0; j < wires.Length; j++) { log[j] += j == wires.Length - 1 ? "and " + Arrays.Colors[wires[j]] : Arrays.Colors[wires[j]]; } Debug.LogFormat("[Reformed Role Reversal #{0}]: The wires are now {1}.", init.ModuleId, log.Join(", ")); coroutines.GenerateSetOfConditions(wires.Length - 2, wires, ref lookup, ref discard, ref append); // This method will run again from the generate set of conditions. An answer has not yet been determined. return(null); } // If true, the answer has been reached, and the wire to cut is in the Wire property. if (init.Conditions[wireCount, i].Wire != null) { SouvenirWires = wires; SouvenirIndex[0] = wireCount; SouvenirIndex[1] = i; int?wireValue = init.Conditions[wireCount, i].Wire; if (wireValue < 1 || wireValue > 9) { throw new IndexOutOfRangeException("[Reformed Role Reversal #" + init.ModuleId + "]: Condition [" + (wireCount + 2) + ", " + (i + 1) + "] returned " + wireValue + " for parameter \"Wire\"! This should not happen under normal circumstances, as the wire specified to cut doesn't exist."); } Debug.LogFormat("[Reformed Role Reversal #{0}]: <Condition {1}, {2}> \"{3}\" is true, cut the {4} wire.", init.ModuleId, wireCount + 2, i + 1, init.Conditions[wireCount, i].Text, Arrays.Ordinals[(int)wireValue - 1]); init.Ready = true; return((int)wireValue); } Debug.LogFormat("[Reformed Role Reversal #{0}]: <Condition {1}, {2}> \"{3}\" is false.", init.ModuleId, wireCount + 2, i + 1, init.Conditions[wireCount, i].Text); } // Failsafe: If the answer isn't found, any wire can be cut. Debug.LogWarningFormat("[Reformed Role Reversal #{0}]: An internal error has occured whilst trying to calculate the answer. Any submitted answer will solve the module.", init.ModuleId); init.Ready = true; return(null); }