A state can be placed, which four things were queued behind
Lander reads sixteen bytes from /lander.state if the disk has one and starts from those: position, velocity, where the station is, fuel, and which screen to be in. A disk without the file is the game as it always was, which is every other flight in the suite. It exists because some states cannot be flown to. A successful dock needs the lander alongside the station and matched, and NINETY SIX pad files failed to get there - not for want of trying, but because climbing spends sideways speed, so a lander cannot rise while matched and arrives slower than orbital every time. Reaching it wants two burns and a phase. The orbit check had already been deleted for the same reason, and the strike check was flown on a nineteen frame window, which is the sort of fixture that ends up measuring the boot time rather than the physics. Binary, because that is what a file is on this machine. A tool to build one from readable text is a small job for another day; until then the tests write the bytes with the fields named, which reads plainly enough. ---- The buffer is a whole block, and that is not caution ---- osFileRead lands a file in Data Memory and a file is stored in blocks of 256, so reading sixteen bytes into sixteen bytes of room writes over whatever follows. It did: the first version put the buffer in front of the view tables, and the program read its state, wiped the numbers every gauge draws from, and left immediately - "finished" and back to the prompt, with nothing on the screen to say why. Four checks, each seen to fail on its own break: a state file places the lander (row 192 and twelve cells of gauge, against thirty one with no file), a matched approach docks and is paid once and not once a frame, it then rides the station a tile under it, and the same approach unmatched is a wreck. The flown strike fixture and its narrow window are gone.
This commit is contained in:
+80
-42
@@ -2347,52 +2347,90 @@ MOVED=$(( X3 - X2 ))
|
||||
&& result ok "and round the back of the moon and out again" "gone, then back at $X7" \
|
||||
|| result no "and round the back of the moon and out again" "$X5 at five million, $X7 at seven"
|
||||
|
||||
# ---- Docking, and the half of it that can be flown to ----
|
||||
# ---- Docking, from a state placed rather than flown to ----
|
||||
#
|
||||
# The same shape as touchdown: close enough, and slow enough, or it is a wreck. What makes it
|
||||
# a different skill is that "slow enough" is measured against the STATION, which is doing
|
||||
# orbital speed - the number the marks on the drift bar already point at.
|
||||
# The same shape as touchdown: close enough, and slow enough RELATIVE TO THE STATION, or it is
|
||||
# a wreck. Its speed is orbital speed, which is what the marks on the drift bar point at.
|
||||
#
|
||||
# ---- A NARROW FIXTURE, and it is written down rather than hidden ----
|
||||
# ---- Placed, because this cannot be flown to ----
|
||||
#
|
||||
# The climb here has to arrive at the station's altitude just as the station arrives at the
|
||||
# lander, and the window measured 496 to 514 frames - about nineteen. 505 sits in the middle
|
||||
# of it. That is thinner than this suite likes and it is the same shape as the orbit check
|
||||
# that had to be deleted for measuring the boot time, so: IF THIS EVER FAILS, re-measure the
|
||||
# window before believing the code is broken.
|
||||
# Ninety six pad files were tried and every one either hit the moon or was run down on the way
|
||||
# up, which is not the search's fault: climbing SPENDS sideways speed, so a lander cannot rise
|
||||
# while matched and arrives slower than orbital every time. Reaching the station wants two
|
||||
# burns and a phase.
|
||||
#
|
||||
# It was not always narrow. The station used to orbit four rows up, where anything climbing
|
||||
# away from the surface had to pass, and a strike could be had with any climb between 135 and
|
||||
# 300 frames - eleven of this suite's other flights were being run down as collateral. Moving
|
||||
# it to twelve rows and the ceiling to twenty four fixed all eleven at once, and made the
|
||||
# station properly hard to blunder into. The narrow window is the price of that, and it is the
|
||||
# right way round.
|
||||
python3 -c "open('$BUILD/struck.pad','wb').write(b'\x08' * 505 + b'\x00' * 60000)"
|
||||
timeout 60 "$EMU" --fast --cycles 40000000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/struck.pad" --disk "$ROOT/Tests/build/disks/cosmos.img" \
|
||||
--ram-disk 2048 "$BUILD/cosmos.bin" > "$BUILD/struck.out" 2>&1 || true
|
||||
grep -q "Wrecked against the station" "$BUILD/struck.out" \
|
||||
&& result ok "the station runs down a lander in its lane" "at 64 sixteenths of relative speed" \
|
||||
|| result no "the station runs down a lander in its lane" "no wreck in the transcript"
|
||||
|
||||
# ---- And the half that is not checked here ----
|
||||
#
|
||||
# THE SUCCESSFUL DOCK IS NOT FLOWN. It was measured working, from a build that PLACED the
|
||||
# lander alongside the station and matched: the tank went from 100 to 180, once and not once a
|
||||
# frame, the message went up, and the pair then held together - lander at 316,168 and station
|
||||
# at 320,160, one tile apart and unmoving for two hundred and forty frames, which is what
|
||||
# riding looks like. A thrust in any direction let go of it.
|
||||
#
|
||||
# What could not be found was a pad file that flies there. Ninety six were tried and every one
|
||||
# either hit the moon or was run down on the way UP, which turns out not to be the search's
|
||||
# fault: climbing SPENDS sideways speed, by the exchange that makes the orbit work at all, so
|
||||
# a lander cannot rise while matched - it arrives slower than orbital every time. Docking needs
|
||||
# two burns, one to raise the far side of the orbit and one to circularise at the top, and no
|
||||
# straight line of button presses stumbles into that.
|
||||
#
|
||||
# So it wants either a hand flown recording or, better, a way to PLACE the lander at a chosen
|
||||
# position and velocity before the loop starts - which is now wanted by this, by the orbit
|
||||
# above, by the ride, and by the narrow window three paragraphs up.
|
||||
# So Lander reads sixteen bytes from /lander.state if the disk has one, and starts from those
|
||||
# instead. A disk without one is the game as it always was, which is every other flight in
|
||||
# this file. The strike below used to be flown, on a climb whose window was nineteen frames
|
||||
# wide - the sort of fixture that ends up measuring the boot time. It is placed now and exact.
|
||||
python3 -c "
|
||||
import struct
|
||||
def state(across, down, vx, vy, stationX, stationDown, fuel, wide, landed):
|
||||
return struct.pack('<hhhhhhBBBB', across, down, vx, vy, stationX, stationDown,
|
||||
fuel, wide, landed, 0)
|
||||
# Hanging at the world's origin with a part tank, to show a state is read at all.
|
||||
open('$BUILD/place.state','wb').write(state(0x14A0, 0, 0, 0, 0x34A0, -1536, 100, 1, 1))
|
||||
# Four pixels behind the station, at its height, and matched to its speed exactly.
|
||||
open('$BUILD/dock.state','wb').write(state(0x34A0 - 64, -1536 + 64, 64, 0, 0x34A0, -1536, 100, 1, 0))
|
||||
# In the same place and NOT matched: 64 sixteenths of relative speed, eight times the limit.
|
||||
open('$BUILD/wreck.state','wb').write(state(0x34A0, -1536, 0, 0, 0x34A0, -1536, 100, 1, 0))
|
||||
"
|
||||
for which in place dock wreck; do
|
||||
cp "$ROOT/Tests/build/disks/cosmos.img" "$BUILD/$which.img"
|
||||
"$ROOT/SplitDisk" put "$BUILD/$which.img" "$BUILD/$which.state" /lander.state > /dev/null
|
||||
done
|
||||
python3 -c "open('$BUILD/ackonly.pad','wb').write(b'\x00' * 200 + b'\x10' * 8 + b'\x00' * 60000)"
|
||||
for run in place:3000000 dock:6000000 dock2:9000000 wreck:3000000; do
|
||||
which="${run%%:*}"; when="${run##*:}"
|
||||
timeout 60 "$EMU" --fast --cycles "$when" --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/ackonly.pad" --screen "$BUILD/$which.ppm" \
|
||||
--disk "$BUILD/${which%2}.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/$which.out" 2>&1 || true
|
||||
done
|
||||
# And the same moment with no state file at all, which is the contrast that says the file did it.
|
||||
timeout 60 "$EMU" --fast --cycles 3000000 --keyboard "$BUILD/fly.keys" \
|
||||
--pad "$BUILD/ackonly.pad" --screen "$BUILD/nostate.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
"$BUILD/cosmos.bin" > "$BUILD/nostate.out" 2>&1 || true
|
||||
read -r PLACEDY PLACEDFUEL PLAINFUEL DOCKFUEL DOCK2FUEL RIDESHIP RIDESTATION <<EOT
|
||||
$(python3 -c "
|
||||
def look(path):
|
||||
d = open(path, 'rb').read()
|
||||
width = int(d[:40].split()[1])
|
||||
px = d[d.index(b'255\n') + 4:]
|
||||
def where(colour):
|
||||
c = bytes.fromhex(colour)
|
||||
return [(i % width, i // width) for i in range(len(px) // 3)
|
||||
if px[i * 3:i * 3 + 3] == c]
|
||||
ship = where('d8c048')
|
||||
station = [p for p in where('5880e0') if p[1] < 250]
|
||||
# The gauge is the top row of the window; the speed bars are green too, further down.
|
||||
fuel = sum(1 for x, y in where('50c050') if y < 8) // 64
|
||||
return (min(y for x, y in ship) if ship else -1, fuel,
|
||||
'%d,%d' % (min(x for x, y in ship), min(y for x, y in ship)) if ship else 'none',
|
||||
'%d,%d' % (min(x for x, y in station), min(y for x, y in station)) if station else 'none')
|
||||
p = look('$BUILD/place.ppm'); d = look('$BUILD/dock.ppm'); d2 = look('$BUILD/dock2.ppm')
|
||||
print(p[0], p[1], look('$BUILD/nostate.ppm')[1], d[1], d2[1], d2[2], d2[3])
|
||||
" 2>/dev/null || echo "-1 -1 -1 -1 -1 none none")
|
||||
EOT
|
||||
# Placed at the world's origin with a hundred units: row 192 is the origin in the wide view,
|
||||
# and twelve cells of gauge is a hundred. The plain disk at the same moment has a full tank,
|
||||
# which is what says the FILE moved these and not the flight.
|
||||
[ "$PLACEDY" = "192" ] && [ "$PLACEDFUEL" = "12" ] && [ "$PLAINFUEL" != "12" ] \
|
||||
&& result ok "a state file places the lander" "row 192 and $PLACEDFUEL cells, against $PLAINFUEL with no file" \
|
||||
|| result no "a state file places the lander" "row $PLACEDY, $PLACEDFUEL cells, plain disk $PLAINFUEL"
|
||||
# A hundred plus eighty is a hundred and eighty, which is twenty two cells - and it is still
|
||||
# twenty two three thousand cycles later, so it was paid ONCE and not once a frame.
|
||||
[ "$DOCKFUEL" = "22" ] && [ "$DOCK2FUEL" = "22" ] \
|
||||
&& result ok "a matched approach docks and is paid" "a hundred became a hundred and eighty, once" \
|
||||
|| result no "a matched approach docks and is paid" "$DOCKFUEL cells, then $DOCK2FUEL"
|
||||
# Held to it, one tile under, rather than merely paid by it.
|
||||
[ "$RIDESHIP" = "316,104" ] && [ "$RIDESTATION" = "320,96" ] \
|
||||
&& result ok "and rides it, a tile under" "lander $RIDESHIP, station $RIDESTATION" \
|
||||
|| result no "and rides it, a tile under" "lander $RIDESHIP, station $RIDESTATION"
|
||||
grep -q "Wrecked against the station" "$BUILD/wreck.out" \
|
||||
&& result ok "and the same approach unmatched is a wreck" "64 sixteenths, eight times the limit" \
|
||||
|| result no "and the same approach unmatched is a wreck" "no wreck in the transcript"
|
||||
|
||||
# ---- Clearing puts the cursor back at the top ----
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user