diff --git a/Assets/TargetLevelProbabilityPanel.cs b/Assets/TargetLevelProbabilityPanel.cs index dedd01e..ea4be15 100644 --- a/Assets/TargetLevelProbabilityPanel.cs +++ b/Assets/TargetLevelProbabilityPanel.cs @@ -10,8 +10,8 @@ public class TargetLevelProbabilityPanel : MonoBehaviour public GameObject targetTitleText; private GameObject titleText; - private List singleLevelPanelsObjs = new List(); - private List singleLevelPanels = new List(); + public List singleLevelPanelsObjs = new List(); + public List singleLevelPanels = new List(); private int panelNum = 0; @@ -23,7 +23,7 @@ public void IntializePanels(int levelNum, string titleName) float titleHeight = targetTitleText.GetComponent().sizeDelta.y; float averageProbability = 1f / levelNum; float lastLevelProbability = 1f - averageProbability * (levelNum - 1); - Debug.Log("averageProbability: " + averageProbability); + // Debug.Log("averageProbability: " + averageProbability); transform.GetComponent().sizeDelta = new Vector2(defaultWidth, (defaultLevelHeight * levelNum) + titleHeight); // create title text titleText = Instantiate(targetTitleText, transform); @@ -67,10 +67,11 @@ private void AddEventTrigger(GameObject gameObject, EventTriggerType triggerType /// changed panel index private void OnSliderValueChange(float value, int exceptedIndex) { - float newTotalValue = 0; + float newTotalValue = 0; // new total probability value without locked panel int unlockedPanelNum = 0; int remainCorrectionNum = panelNum; - float extraValue = 0; + float extraValue = 0; // the extra value after probability value changed + float maxLimitValue = 1; // the max value of unlocked panel permitted float[] correctionValues = new float[panelNum]; // calculate total probability value @@ -78,10 +79,15 @@ private void OnSliderValueChange(float value, int exceptedIndex) { // disable slider listener singleLevelPanels[i].probabilitySlider.onValueChanged.RemoveAllListeners(); - newTotalValue += (i == exceptedIndex ? value : singleLevelPanels[i].ProbabilityValue); if (singleLevelPanels[i].UnLocked) { unlockedPanelNum++; + newTotalValue += (i == exceptedIndex ? value : singleLevelPanels[i].ProbabilityValue); + } + else + { + // delete locked probability value from maxLimitValue + maxLimitValue -= singleLevelPanels[i].ProbabilityValue; } } // only have one panel @@ -94,13 +100,13 @@ private void OnSliderValueChange(float value, int exceptedIndex) //only one panel is unlocked if (unlockedPanelNum == 1) { - // limit this panel value under 1 - (newTotalValue - value) - singleLevelPanels[exceptedIndex].SetProbability(newTotalValue - 1 > 0 ? 1 - newTotalValue + value : value); + // limit this panel value at maxLimitValue + singleLevelPanels[exceptedIndex].SetProbability(maxLimitValue); enableSliderListener(); return; } // Calculate the average correction value - extraValue = newTotalValue - 1; + extraValue = newTotalValue - maxLimitValue; // initialize correction value to each panel correctionValues = Enumerable.Repeat(extraValue / (unlockedPanelNum - 1), panelNum).ToArray(); // make sure all probability value is not less than 0 and equal to 1 @@ -108,7 +114,7 @@ private void OnSliderValueChange(float value, int exceptedIndex) while (remainCorrectionNum > 0) { iterationCount++; - (correctionValues, remainCorrectionNum) = reCalculateCorrectionValues(correctionValues, exceptedIndex, value, extraValue); + (correctionValues, remainCorrectionNum) = reCalculateCorrectionValues(correctionValues, exceptedIndex, value, extraValue, maxLimitValue); // protect the infinite loop if (iterationCount >= 100) { @@ -137,18 +143,23 @@ private void enableSliderListener() /// /// calculate the correction value to each panel,while the total value is not equal to 1 /// - private (float[], int) reCalculateCorrectionValues(float[] correctionValues, int exceptedIndex, float value, float extraValue) + private (float[], int) reCalculateCorrectionValues(float[] correctionValues, int exceptedIndex, float value, float extraValue, float maxLimitValue) { + // the number of panels which need to be corrected in next iteration int remainCorrectionNum = 0; List reCorrectionIndex = new List(); + // the index of the last panel which need to be corrected in this iteration int lastReCorrectionIndex = 0; + // another extra value after correctionValue applicate to probability value which value also less than 0 + // this value will be added to the panel which value is bigger. float underZeroExtraValueAfterCorrected = 0; for (int i = 0; i < panelNum; ++i) { // if the panel is the changed one if (i == exceptedIndex) { - correctionValues[i] = singleLevelPanels[i].ProbabilityValue - value; + // limit the value under maxLimitValue + correctionValues[i] = value > maxLimitValue ? (singleLevelPanels[i].ProbabilityValue - maxLimitValue) : (singleLevelPanels[i].ProbabilityValue - value); continue; } // if the panel is locked @@ -157,21 +168,27 @@ private void enableSliderListener() correctionValues[i] = 0; continue; } - //if the probability value is 0 or the probability value is equal to the correction value - if (singleLevelPanels[i].ProbabilityValue < 0 || singleLevelPanels[i].ProbabilityValue > 1) + // if the panel is unlocked + // and the probability value is less than 0 or bigger than maxLimitValue + if (singleLevelPanels[i].ProbabilityValue < 0 || singleLevelPanels[i].ProbabilityValue > maxLimitValue) { - correctionValues[i] = 0; + // correct this panel value to 0 or maxLimitValue + correctionValues[i] = singleLevelPanels[i].ProbabilityValue; } + // probability value will be correct to 0 else if (singleLevelPanels[i].ProbabilityValue == correctionValues[i]) { + // that's good keep this correction value, and add it to the extraValue underZeroExtraValueAfterCorrected += correctionValues[i]; } - else if (singleLevelPanels[i].ProbabilityValue - correctionValues[i] < 0 || singleLevelPanels[i].ProbabilityValue - correctionValues[i] > 1) + // probability value will be correct over the limit (bigger than maxLimitValue or less than 0) + else if (singleLevelPanels[i].ProbabilityValue - correctionValues[i] < 0 || singleLevelPanels[i].ProbabilityValue - correctionValues[i] > maxLimitValue) { - underZeroExtraValueAfterCorrected += correctionValues[i]; + // should be corrected to 0 or maxLimitValue,and add it to the extraValue + underZeroExtraValueAfterCorrected += singleLevelPanels[i].ProbabilityValue; correctionValues[i] = singleLevelPanels[i].ProbabilityValue; - remainCorrectionNum++; } + // left panels correction value which need to be re-corrected else { lastReCorrectionIndex = i; @@ -180,11 +197,15 @@ private void enableSliderListener() } foreach (int index in reCorrectionIndex) { + // calculate the average correction value float newAverageCorrectionValue = (extraValue - underZeroExtraValueAfterCorrected) / reCorrectionIndex.Count; + // if the panel is the last one which need to be corrected. + // Avoidance of floating-point rounding error, the last panel correction value will be the extraValue minus the sum of the other panels correction value if (index == lastReCorrectionIndex) { correctionValues[index] = extraValue - (newAverageCorrectionValue * (reCorrectionIndex.Count - 1)); - if (singleLevelPanels[index].ProbabilityValue - correctionValues[index] < 0) + // still out of limit after correction, correct it to 0 and activate next iteration + if (singleLevelPanels[index].ProbabilityValue - correctionValues[index] < 0 || singleLevelPanels[index].ProbabilityValue - correctionValues[index] > maxLimitValue) { correctionValues[index] = singleLevelPanels[index].ProbabilityValue; remainCorrectionNum++; @@ -193,7 +214,8 @@ private void enableSliderListener() else { correctionValues[index] = newAverageCorrectionValue; - if (singleLevelPanels[index].ProbabilityValue - correctionValues[index] < 0) + // still out of limit after correction, correct it to 0 and activate next iteration + if (singleLevelPanels[index].ProbabilityValue - correctionValues[index] < 0 || singleLevelPanels[index].ProbabilityValue - correctionValues[index] > maxLimitValue) { correctionValues[index] = singleLevelPanels[index].ProbabilityValue; remainCorrectionNum++; @@ -210,13 +232,13 @@ private void applyCorrectionValue(float[] correctionValues) { for (int i = 0; i < panelNum; i++) { - if (singleLevelPanels[i].ProbabilityValue - correctionValues[i] < 0) - { - Debug.LogWarning("Probability value is less than 0"); - Debug.Log(i); - Debug.Log(singleLevelPanels[i].ProbabilityValue); - Debug.Log(correctionValues[i]); - } + /* if (singleLevelPanels[i].ProbabilityValue - correctionValues[i] < 0) + { + Debug.LogWarning("Probability value is less than 0"); + Debug.Log(i); + Debug.Log(singleLevelPanels[i].ProbabilityValue); + Debug.Log(correctionValues[i]); + }*/ singleLevelPanels[i].SetProbability(singleLevelPanels[i].ProbabilityValue - correctionValues[i]); } }