void AddResultDistance(SubMode subMode, string subModeUnit, string label, string modeUnit) { RunData runData = new RunData(mode); ResultMode resultMode = Tools.ToResultMode(mode); RunResult runResult = new RunResult(ResultMode.Distance); runData.Load(itemRun); runResult.Load(); listViewItems.Add(new ResultItem(label + " (" + modeUnit + ")", "")); foreach (ResultItem input in runResult.Items) { ResultItem output = runData.GetResult(input, subMode, subModeUnit); listViewItems.Add(output); Debug.LogToFile("result " + mode + " (" + subMode + ")" + ": " + output.Left + " " + modeUnit + " = " + output.Right); } if (Config.Result.CalibrationLabelEnabled) { if (subMode == SubMode.TimeDistance) { if (lblRunInfo.Text.Contains("Calibration") == false) // do not add this text twice { lblRunInfo.Text += Environment.NewLine + GetCalibrationRunInfo(runData); Debug.LogToFile(runData.ToString()); // prints calibration from runAdjust } } } }
void CreateResultTime(SubMode subMode, string subModeUnit, string label, string modeUnit) { RunData runData = new RunData(mode); ResultMode resultMode = Tools.ToResultMode(mode); RunResult runResult = new RunResult(resultMode); runData.Load(itemRun); runResult.Load(); listViewItems = new List <ResultItem>(); listViewItems.Add(new ResultItem(label + " (" + modeUnit + ")", "")); Debug.LogToFile("run [id, date, time]: " + itemRun.Id + " // " + itemRun.Date.ToString("dd MMMM yyyy") + " // " + itemRun.Date.ToString("HH:mm")); foreach (ResultItem input in runResult.Items) { ResultItem output = runData.GetResult(input, subMode, subModeUnit); listViewItems.Add(output); Debug.LogToFile("result " + mode + " (" + subMode + ")" + ": " + output.Left + " " + modeUnit + " = " + output.Right); } listView.ItemsSource = listViewItems; plotView.Update(runData, subMode); if (Config.Result.CalibrationLabelEnabled) { lblRunInfo.Text = Tools.RemoveTillEnd(lblRunInfo.Text, Environment.NewLine + "Peak Acceleration"); } }
float Subtract(Event eventEnd, Event eventStart, SubMode subMode) { float result = 0; if ((eventEnd != null) && (eventStart != null)) { switch (subMode) { case SubMode.TimeSpeed: case SubMode.TimeDistance: result = eventEnd.time - eventStart.time; break; case SubMode.Distance: result = eventEnd.distance - eventStart.distance; break; case SubMode.Height: result = eventEnd.height - eventStart.height; break; } } //Debug.LogToFileMethod("eventEnd: " + eventEnd); //Debug.LogToFileMethod("eventStart: " + eventStart); //Debug.LogToFileMethod("result: " + result); return(result); }
private void ChangeMode(Mode mode) { // Assembly reference may be lost here when called from OnRemove. // Toggle mode. if (mode == m_mode) { mode = Mode.None; } m_selection.Clear(); RemoveAllChildren(); m_mode = mode; m_subMode = SubMode.None; if (m_mode == Mode.Shape) { ShapeCreateTool = new ShapeCreateTool(Assembly.gameObject); } else if (m_mode == Mode.Constraint) { ConstraintCreateTool = new ConstraintCreateTool(Assembly.gameObject, true); } }
private void Start() { header = FindObjects.GameLogic.GetComponent <HeaderStatus>(); mode = FindObjects.GameLogic.GetComponent <SubMode>(); header.AddMode(this); }
private void Start() { mode = FindObjects.GameLogic.GetComponent <SubMode>(); header = FindObjects.GameLogic.GetComponent <HeaderAction>(); setting = FindObjects.GameLogic.GetComponent <GameSetting>(); ui = FindObjects.GameLogic.GetComponent <UserInterface>(); uiSetting = FindObjects.GameLogic.GetComponent <UISetting>(); }
public static int[] Encode(string data) { EncodingMode encodingMode = EncodingMode.Text; SubMode textSubMode = SubMode.Upper; var result = new List <int>(); while (data.Length > 0) { var numericCount = DetermineConsecutiveDigitCount(data); if (numericCount >= MinNumericCount || numericCount == data.Length) { result.Add(LatchToNumeric); encodingMode = EncodingMode.Numeric; textSubMode = SubMode.Upper; IEnumerable <int> numData = EncodeNumeric(data.Substring(0, numericCount)); result.AddRange(numData); data = data.Substring(numericCount); } else { var textCount = DetermineConsecutiveTextCount(data); if (textCount >= 5 || textCount == data.Length) { if (encodingMode != EncodingMode.Text) { result.Add(LatchToText); encodingMode = EncodingMode.Text; textSubMode = SubMode.Upper; } IEnumerable <int> txtData = EncodeText(EncodeTextPreprocess(data.Substring(0, textCount), ref textSubMode)); result.AddRange(txtData); data = data.Substring(textCount); } else { var binaryCount = DetermineConsecutiveBinaryCount(data); if (binaryCount == 0) { binaryCount = 1; } string bytes = data.Substring(0, binaryCount); if (bytes.Length != 1 || encodingMode != EncodingMode.Text) { encodingMode = EncodingMode.Binary; textSubMode = SubMode.Upper; } IEnumerable <int> byteData = EncodeBinary(bytes, encodingMode); result.AddRange(byteData); data = data.Substring(binaryCount); } } } return(result.ToArray()); }
private void Start() { coord = FindObjects.GameLogic.GetComponent <ConvertCoordinates>(); dungeon = FindObjects.GameLogic.GetComponent <DungeonBoard>(); actor = FindObjects.GameLogic.GetComponent <ActorBoard>(); mode = FindObjects.GameLogic.GetComponent <SubMode>(); fov = FindObjects.PC.GetComponent <FieldOfView>(); }
/// <summary> /// Build ultra-wideband submodes. /// </summary> /// <returns>the ultra-wideband submodes.</returns> protected static internal SubMode[] BuildUwbSubModes() { /* Initialize Long Term Predictions */ HighLspQuant highLU = new HighLspQuant(); SubMode[] uwbSubModes = new SubMode[SB_SUBMODES]; uwbSubModes[1] = new SubMode(0, 0, 1, 0, highLU, null, null, .75f, .75f, -1, 2); return(uwbSubModes); }
private void Start() { mode = FindObjects.GameLogic.GetComponent <SubMode>(); buyPower = FindObjects.GameLogic.GetComponent <UIBuyPower>(); ui = FindObjects.GameLogic.GetComponent <UserInterface>(); pcPower = FindObjects.PC.GetComponent <Power>(); header = FindObjects.GameLogic.GetComponent <HeaderAction>(); text = FindObjects.GameLogic.GetComponent <GameText>(); }
private void ChangeSubMode(SubMode subMode) { // Toggle sub-mode. if (subMode == m_subMode) { subMode = SubMode.None; } m_rbSelection = null; m_subMode = subMode; }
private void Start() { schedule = FindObjects.GameLogic.GetComponent <SchedulingSystem>(); wizard = FindObjects.GameLogic.GetComponent <WizardMode>(); init = FindObjects.GameLogic.GetComponent <Initialize>(); coord = FindObjects.GameLogic.GetComponent <ConvertCoordinates>(); actor = FindObjects.GameLogic.GetComponent <ActorBoard>(); gameMode = FindObjects.GameLogic.GetComponent <SubMode>(); modeline = FindObjects.GameLogic.GetComponent <UIModeline>(); input = GetComponent <PlayerInput>(); }
string GetShareTextForMode(RunData runData, RunResult runResult, SubMode subMode, string subModeUnit, string modeUnit) { string result = ""; foreach (ResultItem input in runResult.Items) { ResultItem output = runData.GetResult(input, subMode, subModeUnit); result += mode + " (" + subMode + ")" + ": " + output.Left + " " + modeUnit + " = " + output.Right + Environment.NewLine; } return(result); }
float GetDifferenceAcceleration(float start, float end, SubMode subMode) { float result = 0; Event eventStart = null; Event eventEnd = null; // search for start in events foreach (Event e in events) { if (subMode == SubMode.TimeDistance) { if (e.distance >= start) { eventStart = e; break; } } else { if (e.speed >= start) { eventStart = e; break; } } } // search for end in events foreach (Event e in events) { if (subMode == SubMode.TimeDistance) { if (e.distance >= end) { eventEnd = e; break; } } else { if (e.speed >= end) { eventEnd = e; break; } } } result = Subtract(eventEnd, eventStart, subMode); return(result); }
/// <summary> /// Build wideband submodes. /// </summary> /// <returns>the wideband submodes.</returns> protected static internal SubMode[] BuildWbSubModes() { // Initialize Long Term Predictions HighLspQuant highLU = new HighLspQuant(); // Initialize Codebook Searches SplitShapeSearch ssCbHighLbrSearch = new SplitShapeSearch(40, 10, 4, NSpeex.Codebook_Constants.hexc_10_32_table, 5, 0); SplitShapeSearch ssCbHighSearch = new SplitShapeSearch(40, 8, 5, NSpeex.Codebook_Constants.hexc_table, 7, 1); // Initialize wide-band modes SubMode[] wbSubModes = new SubMode[SB_SUBMODES]; wbSubModes[1] = new SubMode(0, 0, 1, 0, highLU, null, null, .75f, .75f, -1, 36); wbSubModes[2] = new SubMode(0, 0, 1, 0, highLU, null, ssCbHighLbrSearch, .85f, .6f, -1, 112); wbSubModes[3] = new SubMode(0, 0, 1, 0, highLU, null, ssCbHighSearch, .75f, .7f, -1, 192); wbSubModes[4] = new SubMode(0, 0, 1, 1, highLU, null, ssCbHighSearch, .75f, .75f, -1, 352); return(wbSubModes); }
public List <Event> GetEventsAdjusted(SubMode subMode) { List <Event> result = new List <Event>(); // copy events to new list, adjust time and distance according to calibration foreach (Event e in events) { result.Add(new Event(runAdjust.GetAdjusted(e.time, mode, subMode), // time adjusted e.acceleration, e.speed, runAdjust.GetAdjusted(e.distance, mode, subMode), // distance adjusted e.height)); } return(result); }
float GetDifferenceZeroToZero(float start, float target, float end, SubMode subMode) { float result = 0; Event eventStart = null; Event eventTarget = null; Event eventEnd = null; float eventTargetTime = float.MaxValue; // search for start in events foreach (Event e in events) { if (e.speed >= start) { eventStart = e; break; } } // search for taget in events foreach (Event e in events) { if (e.speed >= target) { eventTarget = e; eventTargetTime = e.time; break; } } // search for end in events foreach (Event e in events) { if (e.speed <= end) { // ensure end is later than target if (e.time > eventTargetTime) { eventEnd = e; break; } } } result = Subtract(eventEnd, eventStart, subMode); return(result); }
public static string ToResultFormat(float value, SubMode subMode, string unit) { if ((subMode == SubMode.TimeDistance) || subMode == SubMode.TimeSpeed) { return(ToStopwatchTime(value)); } else { if (unit.Equals(Localization.unitFeet)) { return(ToFeet(value).ToString("0.00") + unit); } else { return(value.ToString("0.00") + unit); } } }
public float GetAdjusted(float valueRaw, string mode, SubMode subMode) { float result = 0; switch (subMode) { case SubMode.TimeDistance: case SubMode.TimeSpeed: result = GetAdjustedTime(valueRaw, mode); break; case SubMode.Distance: case SubMode.Height: result = GetAdjustedDistance(valueRaw, mode); break; } return(result); }
float GetDifferenceBrake(float start, float end, SubMode subMode) { float result = 0; Event eventStart = null; Event eventEnd = null; int indexStart = 0; // check index out of bounds if (events.Count > 0) { // search for start in events in reverse order -> omit matchig events at the beginning of the events for (indexStart = events.Count - 1; indexStart >= 0; indexStart--) { Event e = events[indexStart]; if (e.speed >= start) { eventStart = e; break; } } } // do not allow negative array index indexStart = (indexStart < 0) ? 0 : indexStart; // search for end in events, start search where eventStart was found for (int i = indexStart; i < events.Count; i++) { Event e = events[i]; if (e.speed <= end) { eventEnd = e; break; } } result = Subtract(eventEnd, eventStart, subMode); return(result); }
/// <summary> /// Build narrowband submodes /// </summary> /// <returns></returns> protected static SubMode[] buildNbSubModes() { /* Initialize Long Term Predictions */ Ltp3Tap ltpNb = new Ltp3Tap(Codebook.gain_cdbk_nb, 7, 7); Ltp3Tap ltpVlbr = new Ltp3Tap(Codebook.gain_cdbk_lbr, 5, 0); Ltp3Tap ltpLbr = new Ltp3Tap(Codebook.gain_cdbk_lbr, 5, 7); Ltp3Tap ltpMed = new Ltp3Tap(Codebook.gain_cdbk_lbr, 5, 7); LtpForcedPitch ltpFP = new LtpForcedPitch(); /* Initialize Codebook Searches */ NoiseSearch noiseSearch = new NoiseSearch(); SplitShapeSearch ssNbVlbrSearch = new SplitShapeSearch(40, 10, 4, Codebook.exc_10_16_table, 4, 0); SplitShapeSearch ssNbLbrSearch = new SplitShapeSearch(40, 10, 4, Codebook.exc_10_32_table, 5, 0); SplitShapeSearch ssNbSearch = new SplitShapeSearch(40, 5, 8, Codebook.exc_5_64_table, 6, 0); SplitShapeSearch ssNbMedSearch = new SplitShapeSearch(40, 8, 5, Codebook.exc_8_128_table, 7, 0); SplitShapeSearch ssSbSearch = new SplitShapeSearch(40, 5, 8, Codebook.exc_5_256_table, 8, 0); SplitShapeSearch ssNbUlbrSearch = new SplitShapeSearch(40, 20, 2, Codebook.exc_20_32_table, 5, 0); /* Initialize Line Spectral Pair Quantizers */ NbLspQuant nbLspQuant = new NbLspQuant(); LbrLspQuant lbrLspQuant = new LbrLspQuant(); /* Initialize narrow-band modes */ SubMode[] nbSubModes = new SubMode[NB_SUBMODES]; /* 2150 bps "vocoder-like" mode for comfort noise */ nbSubModes[1] = new SubMode(0, 1, 0, 0, lbrLspQuant, ltpFP, noiseSearch, .7f, .7f, -1, 43); /* 5.95 kbps very low bit-rate mode */ nbSubModes[2] = new SubMode(0, 0, 0, 0, lbrLspQuant, ltpVlbr, ssNbVlbrSearch, 0.7f, 0.5f, .55f, 119); /* 8 kbps low bit-rate mode */ nbSubModes[3] = new SubMode(-1, 0, 1, 0, lbrLspQuant, ltpLbr, ssNbLbrSearch, 0.7f, 0.55f, .45f, 160); /* 11 kbps medium bit-rate mode */ nbSubModes[4] = new SubMode(-1, 0, 1, 0, lbrLspQuant, ltpMed, ssNbMedSearch, 0.7f, 0.63f, .35f, 220); /* 15 kbps high bit-rate mode */ nbSubModes[5] = new SubMode(-1, 0, 3, 0, nbLspQuant, ltpNb, ssNbSearch, 0.7f, 0.65f, .25f, 300); /* 18.2 high bit-rate mode */ nbSubModes[6] = new SubMode(-1, 0, 3, 0, nbLspQuant, ltpNb, ssSbSearch, 0.68f, 0.65f, .1f, 364); /* 24.6 kbps high bit-rate mode */ nbSubModes[7] = new SubMode(-1, 0, 3, 1, nbLspQuant, ltpNb, ssNbSearch, 0.65f, 0.65f, -1, 492); /* 3.95 kbps very low bit-rate mode */ nbSubModes[8] = new SubMode(0, 1, 0, 0, lbrLspQuant, ltpFP, ssNbUlbrSearch, .7f, .5f, .65f, 79); /* Return the Narrowband SubModes*/ return(nbSubModes); }
public void SwitchSubMode(int mode) { submode = (SubMode)mode; SingleModeText.color = Color.white; SmoothModeText.color = Color.white; AmplifyModeText.color = Color.white; if (submode == SubMode.Set) { SingleModeText.color = Color_selected; transform.Find("s_Distortion").gameObject.SetActive(false); } else if (submode == SubMode.Avg) { SmoothModeText.color = Color_selected; transform.Find("s_Distortion").gameObject.SetActive(true); } else if (submode == SubMode.Amp) { AmplifyModeText.color = Color_selected; transform.Find("s_Distortion").gameObject.SetActive(false); } }
public SubInfo(SubMode mode) : this() { this._subInfo.mode = mode; }
public void Update(RunData runData, SubMode subMode) { List <Event> events = runData.GetEventsAdjusted(subMode); LineSeries lineSeries = new LineSeries(); float speedUnit = (Settings.IsSpeedUnitKph()) ? 3.6f : 2.23694f; float distanceUnit = (Settings.IsDistanceUnitMeter()) ? 1.0f : 3.28084f; LinearAxis xAxis = null; LinearAxis yAxis = null; string titleTime = Localization.quantityTime + " [" + Localization.unitSecond + "]"; string titleSpeed = Localization.quantitySpeed + " [" + ((Settings.IsSpeedUnitKph()) ? Localization.unitKph : Localization.unitMph) + "]"; string titleDistance = Localization.quantityDistance + " [" + ((Settings.IsDistanceUnitMeter()) ? Localization.unitMeter : Localization.unitFeet) + "]"; string titleHeight = Localization.quantityHeight + " [" + ((Settings.IsDistanceUnitMeter()) ? Localization.unitMeter : Localization.unitFeet) + "]"; float xVal = 0; float xMin = 0; float xMax = 0; float yVal = 0; float yMin = 0; float yMax = 0; List <DouglasPeucker.Point> fullList = new List <DouglasPeucker.Point>(); double tolerance = 0; switch (subMode) { case SubMode.TimeSpeed: foreach (Event e in events) { xVal = e.time; yVal = e.speed * speedUnit; fullList.Add(new DouglasPeucker.Point(xVal, yVal)); GetMinMax(xVal, yVal, ref xMin, ref xMax, ref yMin, ref yMax); } tolerance = GetReductionTolerance(xMin, xMax, yMin, yMax); BuildReducedSeries(lineSeries, fullList, tolerance); xAxis = CreateAxis(AxisPosition.Bottom, titleTime); yAxis = CreateAxis(AxisPosition.Left, titleSpeed); break; case SubMode.TimeDistance: foreach (Event e in events) { xVal = e.time; yVal = e.distance * distanceUnit; fullList.Add(new DouglasPeucker.Point(xVal, yVal)); GetMinMax(xVal, yVal, ref xMin, ref xMax, ref yMin, ref yMax); } tolerance = GetReductionTolerance(xMin, xMax, yMin, yMax); BuildReducedSeries(lineSeries, fullList, tolerance); xAxis = CreateAxis(AxisPosition.Bottom, titleTime); yAxis = CreateAxis(AxisPosition.Left, titleDistance); break; case SubMode.Distance: foreach (Event e in events) { xVal = e.distance * distanceUnit; yVal = e.speed * speedUnit; fullList.Add(new DouglasPeucker.Point(xVal, yVal)); GetMinMax(xVal, yVal, ref xMin, ref xMax, ref yMin, ref yMax); } tolerance = GetReductionTolerance(xMin, xMax, yMin, yMax); BuildReducedSeries(lineSeries, fullList, tolerance); xAxis = CreateAxis(AxisPosition.Bottom, titleDistance); yAxis = CreateAxis(AxisPosition.Left, titleSpeed); break; case SubMode.Height: foreach (Event e in events) { xVal = e.time; yVal = e.height * distanceUnit; fullList.Add(new DouglasPeucker.Point(xVal, yVal)); GetMinMax(xVal, yVal, ref xMin, ref xMax, ref yMin, ref yMax); } tolerance = GetReductionTolerance(xMin, xMax, yMin, yMax); BuildReducedSeries(lineSeries, fullList, tolerance); xAxis = CreateAxis(AxisPosition.Bottom, titleTime); yAxis = CreateAxis(AxisPosition.Left, titleHeight); break; } lineSeries.Color = colorGreen; if (Config.Result.PlotSmoothingEnabled) { // plot smoothing needs at last 3 samples (bezier curve) if (lineSeries.Points.Count >= 3) { lineSeries.Smooth = true; } } Model.Axes.Clear(); xAxis.Maximum = Get110Percent(xMax); xAxis.Minimum = Get110Percent(xMin); Model.Axes.Add(xAxis); yAxis.Maximum = Get110Percent(yMax); yAxis.Minimum = Get110Percent(yMin); Model.Axes.Add(yAxis); Model.Series.Clear(); Model.Series.Add(lineSeries); Model.InvalidatePlot(true); }
private void Start() { mode = FindObjects.GameLogic.GetComponent <SubMode>(); coord = FindObjects.GameLogic.GetComponent <ConvertCoordinates>(); actor = FindObjects.GameLogic.GetComponent <ActorBoard>(); }
// TODO: add period param public SubInfo(Reliability reliability, SubMode mode) : this() { this._subInfo.reliability = reliability; this._subInfo.mode = mode; }
public ResultItem GetResult(ResultItem item, SubMode subMode, string unit) { ResultItem result; string start; string end; float speedStart; float speedEnd; float distanceStart; float distanceEnd; float resultValue; //Debug.LogToFileMethod("item: " + item + " // " + "subMode: " + subMode + " // " + "unit: " + unit); item.GetStartEnd(out start, out end); //Debug.LogToFileMethod("start: " + start + " // " + "end: " + end); // convert speed strings if (Settings.IsSpeedUnitKph()) { // from kph-string to m/s-float speedStart = Tools.ToMeterPerSecond(start); speedEnd = Tools.ToMeterPerSecond(end); } else { // from mph-string to m/s-float speedStart = Tools.ToMeterPerSecondM(start); speedEnd = Tools.ToMeterPerSecondM(end); } //Debug.LogToFileMethod("speedStart: " + speedStart + " // " + "speedEnd: " + speedEnd); if (mode.Equals(RunModeZeroToZero.Mode)) // zerotozero results in [time] unit { // mode zerotozero -> stop is same as start, but with stop detection limit on top (avoid unfound speedStop) RunStartStop runStartStop = new RunStartStop(Database.GetInstance().GetActiveProfile()); float speedStop = speedStart + runStartStop.GetStopLimit(); resultValue = GetDifferenceZeroToZero(speedStart, speedEnd, speedStop, subMode); resultValue = runAdjust.GetAdjusted(resultValue, mode, subMode); result = new ResultItem(start + " - " + end + " - " + start, Tools.ToResultFormat(resultValue, subMode, unit)); } else if (mode.Equals(RunModeBrake.Mode)) // brake results in [time] unit { // adjust speedEnd with calibrated stopDetection to avoid unfound speedEnd RunStartStop runStartStop = new RunStartStop(Database.GetInstance().GetActiveProfile()); speedEnd += runStartStop.GetStopLimit(); resultValue = GetDifferenceBrake(speedStart, speedEnd, subMode); resultValue = runAdjust.GetAdjusted(resultValue, mode, subMode); result = new ResultItem(start + " - " + end, Tools.ToResultFormat(resultValue, subMode, unit)); } else // acceleretion results in [time] or [distance] unit { if (subMode == SubMode.TimeDistance) { // convert distance strings if (Settings.IsDistanceUnitMeter()) { // from meter-string to meter-float distanceStart = float.Parse(start); distanceEnd = float.Parse(end); } else { // from foot-string to meter-float distanceStart = Tools.ToMeter(start); distanceEnd = Tools.ToMeter(end); } //Debug.LogToFileMethod("distanceStart: " + distanceStart + " // " + "distanceEnd: " + distanceEnd); resultValue = GetDifferenceAcceleration(distanceStart, distanceEnd, subMode); resultValue = runAdjust.GetAdjusted(resultValue, mode, subMode); float speedAtEndDistance = GetSpeed(distanceEnd); string speedAtEndDistanceString = (Settings.IsSpeedUnitKph()) ? Tools.ToKilometerPerHour(speedAtEndDistance) : Tools.ToMilesPerHour(speedAtEndDistance); string unitDistance = (Settings.IsSpeedUnitKph()) ? Localization.unitKph : Localization.unitMph; result = new ResultItem(start + " - " + end, Tools.ToResultFormat(resultValue, subMode, unit) + " @" + speedAtEndDistanceString + unitDistance); } else { resultValue = GetDifferenceAcceleration(speedStart, speedEnd, subMode); resultValue = runAdjust.GetAdjusted(resultValue, mode, subMode); result = new ResultItem(start + " - " + end, Tools.ToResultFormat(resultValue, subMode, unit)); } } return(result); }
private void Start() { mode = FindObjects.GameLogic.GetComponent <SubMode>(); header = FindObjects.GameLogic.GetComponent <HeaderAction>(); }
private static IReadOnlyList <int> EncodeTextPreprocess(string text, ref SubMode subMode) { bool IsAlphaUpper(char ch) => ch == ' ' || (ch >= 'A' && ch <= 'Z'); bool IsAlphaLower(char ch) => ch == ' ' || (ch >= 'a' && ch <= 'z'); bool IsMixed(char ch) => MixedMap.ContainsKey(ch); bool IsPunctuation(char ch) => PunctuationMap.ContainsKey(ch); int idx = 0; var result = new List <int>(); while (idx < text.Length) { char ch = text[idx]; switch (subMode) { case SubMode.Upper: if (IsAlphaUpper(ch)) { if (ch == ' ') { result.Add(26); // space } else { result.Add(ch - 'A'); } } else { if (IsAlphaLower(ch)) { subMode = SubMode.Lower; result.Add(27); // lower latch continue; } if (IsMixed(ch)) { subMode = SubMode.Mixed; result.Add(28); // mixed latch continue; } result.Add(29); // punctuation switch result.Add(PunctuationMap[ch]); } break; case SubMode.Lower: if (IsAlphaLower(ch)) { if (ch == ' ') { result.Add(26); // space } else { result.Add(ch - 'a'); } } else { if (IsAlphaUpper(ch)) { result.Add(27); // upper switch result.Add(ch - 'A'); break; } if (IsMixed(ch)) { subMode = SubMode.Mixed; result.Add(28); // mixed latch continue; } result.Add(29); // punctuation switch result.Add(PunctuationMap[ch]); } break; case SubMode.Mixed: if (IsMixed(ch)) { result.Add(MixedMap[ch]); } else { if (IsAlphaUpper(ch)) { subMode = SubMode.Upper; result.Add(28); // upper latch continue; } if (IsAlphaLower(ch)) { subMode = SubMode.Lower; result.Add(27); // lower latch continue; } if (idx + 1 < text.Length) { char next = text[idx + 1]; if (IsPunctuation(next)) { subMode = SubMode.Punctuation; result.Add(25); // punctuation latch continue; } } result.Add(29); // punctuation switch result.Add(PunctuationMap[ch]); } break; case SubMode.Punctuation: if (IsPunctuation(ch)) { result.Add(PunctuationMap[ch]); } else { subMode = SubMode.Upper; result.Add(29); // upper latch continue; } break; default: throw new InvalidOperationException($"Unknown submode {subMode}"); } idx++; } return(result); }