From 5b46d4a9bd1dcd78c02aabcc4ca9e3f37cb466cd Mon Sep 17 00:00:00 2001 From: alanwatsonforster <68709385+alanwatsonforster@users.noreply.github.com> Date: Sat, 30 Sep 2023 17:35:56 -0600 Subject: [PATCH] Fixed the AP calculation for SCs. --- airpower/aircraft/__init__.py | 1 + airpower/aircraft/_normalflight.py | 42 ++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/airpower/aircraft/__init__.py b/airpower/aircraft/__init__.py index 2d4dfb6a..bdcaa345 100644 --- a/airpower/aircraft/__init__.py +++ b/airpower/aircraft/__init__.py @@ -288,6 +288,7 @@ def startmove(self, flighttype, power, actions, flamedoutfraction=0): self._lastflighttype = self._flighttype self._lastaltitude = self._altitude self._lastaltitudeband = self._altitudeband + self._lastaltitudecarry = self._altitudecarry self._lastspeed = self._speed # These account for the APs associated with power, speed, speed-brakes, diff --git a/airpower/aircraft/_normalflight.py b/airpower/aircraft/_normalflight.py index 7d9162b5..586d2cd8 100644 --- a/airpower/aircraft/_normalflight.py +++ b/airpower/aircraft/_normalflight.py @@ -656,7 +656,7 @@ def determinerequiredhfpvfpmix(): self._log("- at most %d FPs can be HFPs." % maxhfp) if minunloadedhfp == maxunloadedhfp: - self._log("- exactly %d FPs must be HFPs." % minunloadedhfp) + self._log("- exactly %d FPs must be unloaded HFPs." % minunloadedhfp) elif minunloadedhfp > 0: assert maxunloadedhfp == fp self._log("- at least %d FPs must be unloaded HFPs." % minunloadedhfp) @@ -739,21 +739,38 @@ def determinealtitudeap(): elif flighttype == "SC": + if altitudechange == 0: + + altitudeap = 0.0 - # See rule 8.1.2 and 8.1.4. - if altitudechange < 1: - altitudeap = 0 - elif altitudechange == 1: - # This was either a SC with a CC of 1 or the result of multiple - # turns of SC with a CC of less then 1. - altitudeap = -0.5 else: + + # See rule 8.1.2 and 8.1.4. + climbcapability = self.climbcapability() if self._speed < self.climbspeed(): climbcapability /= 2 - altitudeap = -0.5 * max(altitudechange, climbcapability) - if (altitudechange > climbcapability): - altitudeap += -1.0 * (altitudechange - climbcapability) + + # We need to figure out how much was climbed at the SC rate and + # how much was climbed at the ZC rate. This is complicated since + # altitudechange can be more than the climbcapability because of + # altitudecarry. Therefore, we calculate how much was at the ZC + # rate from the true altitude change, including carry, and then + # assume that any difference was at the SC rate. + # + # We also use that the altitude change at the ZC rate must be an + # integral number of levels. + + truealtitude = self._altitude + self._altitudecarry + lasttruealtitude = self._lastaltitude + self._lastaltitudecarry + + truealtitudechange = truealtitude - lasttruealtitude + + scaltitudechange = min(truealtitudechange, climbcapability) + zcaltitudechange = int(truealtitudechange - scaltitudechange + 0.5) + scaltitudechange = altitudechange - zcaltitudechange + + altitudeap = -0.5 * scaltitudechange + -1.0 * zcaltitudechange elif flighttype == "VC": @@ -786,6 +803,9 @@ def determinealtitudeap(): # See rule 8.2.4. altitudeap = 0 + # Round to nearest 0.25. See rule 6.2. + altitudeap = int(altitudeap * 4 + 0.5) / 4 + self._altitudeap = altitudeap flighttype = self._flighttype