From 277d4bdf815f0b6dbe5d127a34825e2b612ed626 Mon Sep 17 00:00:00 2001 From: alanwatsonforster <68709385+alanwatsonforster@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:05:18 -0600 Subject: [PATCH] Rework altitude. --- airpower/aircraft.py | 14 ++++++------ airpower/altitude.py | 51 +++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/airpower/aircraft.py b/airpower/aircraft.py index 9cb7da45..237c7f17 100644 --- a/airpower/aircraft.py +++ b/airpower/aircraft.py @@ -13,7 +13,7 @@ def __init__(self, name, hexcode, azimuth, altitude): x, y = aphexcode.toxy(hexcode) facing = apazimuth.tofacing(azimuth) - apaltitude._checkaltitude(altitude) + apaltitude.checkisvalidaltitude(altitude) aphex.checkisvalidfacing(x, y, facing) self._turn = 0 @@ -80,13 +80,13 @@ def _reportstatus(self, when): if when != "start": self._report("%d HFPs and %d VFPs used." % (self._ihfp, self._ivfp)) - altitudeband = apaltitude._altitudeband(self._altitude) + altitudeband = apaltitude.altitudeband(self._altitude) if when == "start": self._reportposition("") if when != "start": - self._report("altitude carry is %s." % apaltitude._formataltitudecarry(self._altitudecarry)) + self._report("altitude carry is %s." % apaltitude.formataltitudecarry(self._altitudecarry)) if when == "start": self._initialaltitudeband = altitudeband @@ -177,10 +177,10 @@ def _L(self, facingchange): self._facing = (self._facing + facingchange) % 360 def _D(self, altitudechange): - self._altitude, self._altitudecarry = apaltitude._adjustaltitude(self._altitude, self._altitudecarry, -altitudechange) + self._altitude, self._altitudecarry = apaltitude.adjustaltitude(self._altitude, self._altitudecarry, -altitudechange) def _C(self, altitudechange): - self._altitude, self._altitudecarry = apaltitude._adjustaltitude(self._altitude, self._altitudecarry, +altitudechange) + self._altitude, self._altitudecarry = apaltitude.adjustaltitude(self._altitude, self._altitudecarry, +altitudechange) def _K(self): self._reportfp("killed.") @@ -190,7 +190,7 @@ def _A(self, what): self._reportfp("attack with %s." % what) def checkforterraincollision(self): - altitudeofterrain = apaltitude._altitudeofterrain() + altitudeofterrain = apaltitude.terrainaltitude() if self._altitude <= altitudeofterrain: self._altitude = altitudeofterrain self._altitudecarry = 0 @@ -357,7 +357,7 @@ def next(self, actions): assert self._ifp <= self._nfp aphex.checkiscenteroredge(self._x, self._y) aphex.checkisvalidfacing(self._x, self._y, self._facing) - apaltitude._checkaltitude(self._altitude) + apaltitude.checkisvalidaltitude(self._altitude) if self._ifp == self._nfp: diff --git a/airpower/altitude.py b/airpower/altitude.py index c0f631e5..87afb9e8 100644 --- a/airpower/altitude.py +++ b/airpower/altitude.py @@ -1,13 +1,28 @@ -import math - # _altitudequantum must be 1 over an integral power of 2. _altitudequantum = 1/8 -def _checkaltitude(altitude): - if not isinstance(altitude, (int, float)) or altitude % 1 != 0 or altitude < 1: - raise ValueError("invalid altitude %s." % altitude) +def isvalidaltitude(altitude): + + """ + Return True if altitude is a valid altitude. + """ + return isinstance(altitude, (int, float)) and altitude % 1 == 0 and altitude >= 0 + +def checkisvalidaltitude(altitude): + + """ + Raise a ValueError exception if z is not a valid altitude. + """ + + if not isvalidaltitude(altitude): + raise ValueError("%s is not a valid altitude." % altitude) + +def adjustaltitude(altitude, altitudecarry, altitudechange): -def _adjustaltitude(altitude, altitudecarry, altitudechange): + """ + Adjust altitude by altitudechange, taking into account altitudecarry. + Return the new altitude and altitudecarry. + """ # Here we do altitude arithmetic, ensuring that _altitude stays as an # non-negative integer and keeping track of fractions in _altitudecarry. @@ -19,9 +34,9 @@ def _adjustaltitude(altitude, altitudecarry, altitudechange): altitude = altitude + altitudecarry + altitudechange if altitudechange >= 0: - altitudecarry = altitude - math.floor(altitude) + altitudecarry = altitude % +1 else: - altitudecarry = altitude - math.ceil(altitude) + altitudecarry = altitude % -1 altitude = altitude - altitudecarry if altitude < 0: @@ -33,7 +48,11 @@ def _adjustaltitude(altitude, altitudecarry, altitudechange): return altitude, altitudecarry -def _formataltitudecarry(altitudecarry): +def formataltitudecarry(altitudecarry): + + """ + Return altitudecarry formatted as a signed fraction. + """ assert abs(altitudecarry) < 1 and altitudecarry % _altitudequantum == 0 @@ -48,7 +67,11 @@ def _formataltitudecarry(altitudecarry): m = m / 2 return "%+d/%d" % (n, m) -def _altitudeband(altitude): +def altitudeband(altitude): + + """ + Return the altitude band corresponding to altitude. + """ assert altitude % 1 == 0 and altitude >= 0 @@ -67,6 +90,10 @@ def _altitudeband(altitude): else: return "UH" -def _altitudeofterrain(): - return 0 +def terrainaltitude(): + """ + Return the altitude of the terrain. + """ + + return 0