Python: Add type annotations to all 'print' functions (#662)

* Add test to superstartrek and fixes several issues in superstartrek - I probably introduced them 🙈
* Mastermind type annotations
This commit is contained in:
Martin Thoma
2022-03-21 10:41:14 +01:00
committed by GitHub
parent c444da93c0
commit 1b1d50986b
50 changed files with 241 additions and 172 deletions

View File

@@ -14,13 +14,57 @@
import random
from math import sqrt
from typing import Any, Callable, Dict, List
from typing import Any, Callable, Dict, List, Tuple
# Global variables
restart = False
s = 0
e = 0
d: List[int] = []
k: List[List[float]] = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] # Klingons in current quadrant
devices = [
"WARP ENGINES",
"SHORT RANGE SENSORS",
"LONG RANGE SENSORS",
"PHASER CONTROL",
"PHOTON TUBES",
"DAMAGE CONTROL",
"SHIELD CONTROL",
"LIBRARY-COMPUTER",
]
c = [
[0, 1],
[-1, 1],
[-1, 0],
[-1, -1],
[0, -1],
[1, -1],
[1, 0],
[1, 1],
[0, 1],
] # vectors in cardinal directions
q1 = s1 = 0
q2 = s2 = 0
k3 = b3 = s3 = 0 # Klingons, bases, stars in quad.
b4 = b5 = 0
qs = " " * 192 # quadrant string
# set up global game variables
g = [[0] * 8 for _ in range(8)] # galaxy map
z = [[0] * 8 for _ in range(8)] # charted galaxy map
d = [0] * 8 # damage stats for devices
t = t0 = 100 * random.randint(20, 39) # stardate (current, initial)
t9 = random.randint(25, 34) # mission duration (stardates)
docked = False # true when docked at starbase
e = e0 = 3000 # energy (current, initial)
p = p0 = 10 # torpedoes (current, initial)
s = 0 # shields
k9, b9 = 0, 0 # total Klingons, bases in galaxy
# ^ bug in original, was b9 = 2
s9 = 200 # avg. Klingon shield strength
k7 = k9 # Klingons at start of game
d4 = 0.5 * random.random() # extra delay in repairs at base
# -------------------------------------------------------------------------
# Utility functions
@@ -84,7 +128,7 @@ def compare_marker(row, col, test_marker):
return qs[pos : (pos + 3)] == test_marker
def find_empty_place():
def find_empty_place() -> Tuple[int, int]:
# Find an empty location in the current quadrant.
while True:
row, col = fnr(), fnr()
@@ -97,7 +141,7 @@ def find_empty_place():
# -------------------------------------------------------------------------
def navigation():
def navigation() -> None:
# Take navigation input and move the Enterprise.
global d, s, e, k, qs, t, q1, q2, s1, s2
@@ -148,9 +192,9 @@ def navigation():
line = ""
for i in range(8):
if d[i] < 0:
d[i] += min(warp, 1)
d[i] += min(warp, 1) # type: ignore
if -0.1 < d[i] < 0:
d[i] = -0.1
d[i] = -0.1 # type: ignore
elif d[i] >= 0:
if len(line) == 0:
line = "DAMAGE CONTROL REPORT:"
@@ -175,13 +219,13 @@ def navigation():
x, y = s1, s2
for _ in range(n):
s1 += x1
s2 += x2
s1 += x1 # type: ignore
s2 += x2 # type: ignore
if s1 < 0 or s1 > 7 or s2 < 0 or s2 > 7:
# exceeded quadrant limits; calculate final position
x += 8 * q1 + n * x1
y += 8 * q2 + n * x2
x += 8 * q1 + n * x1 # type: ignore
y += 8 * q2 + n * x2 # type: ignore
q1, q2 = int(x / 8), int(y / 8)
s1, s2 = int(x - q1 * 8), int(y - q2 * 8)
if s1 < 0:
@@ -238,7 +282,7 @@ def navigation():
insert_marker(int(s1), int(s2), "<*>")
maneuver_energy(n)
t += 0.1 * int(10 * warp) if warp < 1 else 1
t += 0.1 * int(10 * warp) if warp < 1 else 1 # type: ignore
if t > t0 + t9:
end_game(won=False, quit=False)
return
@@ -259,7 +303,7 @@ def maneuver_energy(n):
s = max(0, s)
def short_range_scan():
def short_range_scan() -> None:
# Print a short range scan.
global docked, e, p, s
@@ -317,7 +361,7 @@ def short_range_scan():
print(sep)
def long_range_scan():
def long_range_scan() -> None:
# Print a long range scan.
global z, g
@@ -352,7 +396,7 @@ def print_scan_results(
print(sep)
def phaser_control():
def phaser_control() -> None:
# Take phaser control input and fire phasers.
global e, k, g, z, k3, k9
@@ -384,7 +428,7 @@ def phaser_control():
e -= x
if d[7] < 0: # bug in original, was d[6]
x *= random.random()
x *= random.random() # type: ignore
h1 = int(x / k3)
for i in range(3):
@@ -414,7 +458,7 @@ def phaser_control():
klingons_fire()
def photon_torpedoes():
def photon_torpedoes() -> None:
# Take photon torpedo input and process firing of torpedoes.
global e, p, k3, k9, k, b3, b9, docked, g, z
@@ -445,8 +489,8 @@ def photon_torpedoes():
x3, y3 = x, y
print("TORPEDO TRACK:")
while True:
x += x1
y += x2
x += x1 # type: ignore
y += x2 # type: ignore
x3, y3 = round(x), round(y)
if x3 < 0 or x3 > 7 or y3 < 0 or y3 > 7:
print("TORPEDO MISSED")
@@ -523,7 +567,7 @@ def klingons_fire():
print(f"DAMAGE CONTROL REPORTS '{devices[r1]} DAMAGED BY THE HIT'")
def shield_control():
def shield_control() -> None:
# Raise or lower the shields.
global e, s
@@ -590,7 +634,7 @@ def damage_control():
t += d3 + 0.1
def computer():
def computer() -> None:
# Perform the various functions of the library computer.
global d, z, k9, t0, t9, t, b9, s1, s2, b4, b5
@@ -718,7 +762,7 @@ def computer():
)
def print_direction(from1, from2, to1, to2):
def print_direction(from1, from2, to1, to2) -> None:
# Print direction and distance between two locations in the grid.
delta1 = -(to1 - from1) # flip so positive is up (heading = 3)
delta2 = to2 - from2
@@ -752,7 +796,7 @@ def print_direction(from1, from2, to1, to2):
# -------------------------------------------------------------------------
def startup():
def startup() -> None:
# Initialize the game variables and map, and print startup messages.
global g, z, d, t, t0, t9, docked, e, e0, p, p0, s, k9, b9, s9, c
global devices, q1, q2, s1, s2, k7
@@ -850,7 +894,7 @@ def startup():
)
def new_quadrant():
def new_quadrant() -> None:
# Enter a new quadrant: populate map and print a short range scan.
global z, k3, b3, s3, d4, k, qs, b4, b5
@@ -894,7 +938,9 @@ def new_quadrant():
short_range_scan()
def end_game(won=False, quit=True, enterprise_killed=False):
def end_game(
won: bool = False, quit: bool = True, enterprise_killed: bool = False
) -> None:
# Handle end-of-game situations.
global restart

View File

@@ -13,7 +13,7 @@ def get_yes_no(prompt):
return response[0] != "N"
def print_header():
def print_header() -> None:
for _ in range(12):
print()
t10 = " " * 10
@@ -28,7 +28,7 @@ def print_header():
print()
def print_instructions():
def print_instructions() -> None:
# Back in the 70s, at this point, the user would be prompted to
# turn on their (printing) TTY to capture the output to hard copy.

View File

@@ -0,0 +1,11 @@
import io
import pytest
from superstartrek import main
def test_main(monkeypatch, capsys):
monkeypatch.setattr("sys.stdin", io.StringIO("NAV\n1\n1\nSRS\nXXX\nXXX\n"))
with pytest.raises(SystemExit):
main()
# captured = capsys.readouterr()