V3.3.6 LevelProbabilityPanel 逻辑错误修正

This commit is contained in:
Koha9 2023-10-08 03:05:54 +09:00
parent 0b23c91832
commit 86e51f849f

View File

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