Merge pull request #694 from coding-horror/py-type-annotations

BUG: Hangman (Python) had a List-vs-Str comparison
This commit is contained in:
Jeff Atwood
2022-03-31 13:13:37 -05:00
committed by GitHub
26 changed files with 516 additions and 532 deletions
+1 -1
View File
@@ -115,7 +115,7 @@ def game_loop() -> None:
game_over = True
def main():
def main() -> None:
print(
"""
Acey Ducey is a card game where you play against the computer.
+2 -2
View File
@@ -6,10 +6,10 @@ You are able to choose your shot types as well as defensive formations
"""
import random
from typing import Optional, List, Literal
from typing import List, Literal, Optional
def explain_keyboard_inputs():
def explain_keyboard_inputs() -> None:
print("\t\t\t Basketball")
print("\t Creative Computing Morristown, New Jersey\n\n\n")
print("This is Dartmouth College basketball. ")
+3 -3
View File
@@ -112,10 +112,10 @@ def print_intro() -> None:
def ask_bool(prompt: str) -> bool:
while True:
answer = input(prompt)
if answer == "YES":
answer = input(prompt).lower()
if answer == "yes":
return True
elif answer == "NO":
elif answer == "no":
return False
else:
print("INCORRECT ANSWER - - PLEASE TYPE 'YES' OR 'NO'.")
+5 -236
View File
@@ -2,241 +2,10 @@
# This data is meant to be read-only, so we are storing it in a tuple
DATA = (
2,
21,
14,
14,
25,
1,
2,
-1,
0,
2,
45,
50,
-1,
0,
5,
43,
52,
-1,
0,
7,
41,
52,
-1,
1,
9,
37,
50,
-1,
2,
11,
36,
50,
-1,
3,
13,
34,
49,
-1,
4,
14,
32,
48,
-1,
5,
15,
31,
47,
-1,
6,
16,
30,
45,
-1,
7,
17,
29,
44,
-1,
8,
19,
28,
43,
-1,
9,
20,
27,
41,
-1,
10,
21,
26,
40,
-1,
11,
22,
25,
38,
-1,
12,
22,
24,
36,
-1,
13,
34,
-1,
14,
33,
-1,
15,
31,
-1,
17,
29,
-1,
18,
27,
-1,
19,
26,
-1,
16,
28,
-1,
13,
30,
-1,
11,
31,
-1,
10,
32,
-1,
8,
33,
-1,
7,
34,
-1,
6,
13,
16,
34,
-1,
5,
12,
16,
35,
-1,
4,
12,
16,
35,
-1,
3,
12,
15,
35,
-1,
2,
35,
-1,
1,
35,
-1,
2,
34,
-1,
3,
34,
-1,
4,
33,
-1,
6,
33,
-1,
10,
32,
34,
34,
-1,
14,
17,
19,
25,
28,
31,
35,
35,
-1,
15,
19,
23,
30,
36,
36,
-1,
14,
18,
21,
21,
24,
30,
37,
37,
-1,
13,
18,
23,
29,
33,
38,
-1,
12,
29,
31,
33,
-1,
11,
13,
17,
17,
19,
19,
22,
22,
24,
31,
-1,
10,
11,
17,
18,
22,
22,
24,
24,
29,
29,
-1,
22,
23,
26,
29,
-1,
27,
29,
-1,
28,
29,
-1,
4096,
)
import json
with open("data.json") as f:
DATA = tuple(json.load(f))
def display_intro() -> None:
@@ -245,7 +14,7 @@ def display_intro() -> None:
print("\n\n")
def tab(column) -> str:
def tab(column: int) -> str:
"""Emulates the TAB command in BASIC. Returns a string with ASCII
codes for setting the cursor to the specified column."""
return f"\r\33[{column}C"
+235
View File
@@ -0,0 +1,235 @@
[
2,
21,
14,
14,
25,
1,
2,
-1,
0,
2,
45,
50,
-1,
0,
5,
43,
52,
-1,
0,
7,
41,
52,
-1,
1,
9,
37,
50,
-1,
2,
11,
36,
50,
-1,
3,
13,
34,
49,
-1,
4,
14,
32,
48,
-1,
5,
15,
31,
47,
-1,
6,
16,
30,
45,
-1,
7,
17,
29,
44,
-1,
8,
19,
28,
43,
-1,
9,
20,
27,
41,
-1,
10,
21,
26,
40,
-1,
11,
22,
25,
38,
-1,
12,
22,
24,
36,
-1,
13,
34,
-1,
14,
33,
-1,
15,
31,
-1,
17,
29,
-1,
18,
27,
-1,
19,
26,
-1,
16,
28,
-1,
13,
30,
-1,
11,
31,
-1,
10,
32,
-1,
8,
33,
-1,
7,
34,
-1,
6,
13,
16,
34,
-1,
5,
12,
16,
35,
-1,
4,
12,
16,
35,
-1,
3,
12,
15,
35,
-1,
2,
35,
-1,
1,
35,
-1,
2,
34,
-1,
3,
34,
-1,
4,
33,
-1,
6,
33,
-1,
10,
32,
34,
34,
-1,
14,
17,
19,
25,
28,
31,
35,
35,
-1,
15,
19,
23,
30,
36,
36,
-1,
14,
18,
21,
21,
24,
30,
37,
37,
-1,
13,
18,
23,
29,
33,
38,
-1,
12,
29,
31,
33,
-1,
11,
13,
17,
17,
19,
19,
22,
22,
24,
31,
-1,
10,
11,
17,
18,
22,
22,
24,
24,
29,
29,
-1,
22,
23,
26,
29,
-1,
27,
29,
-1,
28,
29,
-1,
4096
]
+2 -2
View File
@@ -24,7 +24,7 @@ import random
def main() -> None:
WORDS = [
words = [
[
"Ability",
"Basal",
@@ -85,7 +85,7 @@ def main() -> None:
still_running = True
while still_running:
phrase = ""
for section in WORDS:
for section in words:
if len(phrase) > 0:
phrase += " "
phrase += section[random.randint(0, len(section) - 1)]
+4 -5
View File
@@ -65,7 +65,7 @@ def parse_input() -> Tuple[int, bool]:
return day, leap_day
def calendar(weekday, leap_year):
def calendar(weekday: int, leap_year: bool) -> None:
"""
function to print a year's calendar.
@@ -104,9 +104,8 @@ def calendar(weekday, leap_year):
for n in range(1, 13):
days_count += months_days[n - 1]
print(
"** {} ****************** {} ****************** {} **\n".format(
days_count, months_names[n - 1], years_day - days_count
)
f"** {days_count} ****************** {months_names[n - 1]} "
f"****************** {years_day - days_count} **\n"
)
print(days)
print(sep)
@@ -121,7 +120,7 @@ def calendar(weekday, leap_year):
break
if d2 <= 0:
print("{}".format(" "), end=" ")
print(" ", end=" ")
elif d2 < 10:
print(f" {d2}", end=" ")
else:
+5 -13
View File
@@ -16,23 +16,17 @@ def print_centered(msg: str) -> None:
def print_header(title: str) -> None:
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
def print_introduction() -> None:
print("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE")
print("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.")
print()
print()
print("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.\n\n")
def pennies_to_dollar_string(p):
def pennies_to_dollar_string(p: float) -> str:
d = p / 100
ds = f"${d:0.2f}"
return ds
return f"${d:0.2f}"
def compute_change() -> None:
@@ -95,9 +89,7 @@ def compute_change() -> None:
def print_thanks() -> None:
print("THANK YOU, COME AGAIN.")
print()
print()
print("THANK YOU, COME AGAIN.\n\n")
def main() -> None:
+4 -12
View File
@@ -37,10 +37,7 @@ def print_centered(msg: str) -> None:
def print_header(title: str) -> None:
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
def get_coordinates(prompt: str) -> Tuple[int, int]:
@@ -373,20 +370,15 @@ def print_instructions() -> None:
print("(7,0) IS THE LOWER RIGHT CORNER")
print("(7,7) IS THE UPPER RIGHT CORNER")
print("THE COMPUTER WILL TYPE '+TO' WHEN YOU HAVE ANOTHER")
print("JUMP. TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.")
print()
print()
print()
print("JUMP. TYPE TWO NEGATIVE NUMBERS IF YOU CANNOT JUMP.\n\n\n")
def print_human_won() -> None:
print()
print("YOU WIN.")
print("\nYOU WIN.")
def print_computer_won() -> None:
print()
print("I WIN.")
print("\nI WIN.")
def play_game() -> None:
+6 -10
View File
@@ -20,7 +20,7 @@ def print_with_tab(space_count: int, msg: str) -> None:
print(spaces + msg)
def play_scenario():
def play_scenario() -> bool:
acid_amount = random.randint(1, 50)
water_amount = 7 * acid_amount / 3
@@ -43,27 +43,23 @@ def play_scenario():
return True
def show_failure():
def show_failure() -> None:
print(" SIZZLE! YOU HAVE JUST BEEN DESALINATED INTO A BLOB")
print(" OF QUIVERING PROTOPLASM!")
def show_success():
print(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!")
print()
def show_success() -> None:
print(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!\n")
def show_ending():
def show_ending() -> None:
print(f" YOUR {MAX_LIVES} LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR")
print(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.")
def main() -> None:
print_with_tab(33, "CHEMIST")
print_with_tab(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_with_tab(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
print("THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE")
print("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID.")
@@ -1,5 +1,4 @@
def print_lightning_bolt() -> None:
print("*" * 36)
n = 24
while n > 16:
@@ -17,8 +16,7 @@ def print_lightning_bolt() -> None:
print("*" * 36)
def print_solution(n: int) -> None:
def print_solution(n: float) -> None:
print(f"\n{n} plus 3 gives {n + 3}. This Divided by 5 equals {(n + 3) / 5}")
print(f"This times 8 gives {((n + 3) / 5) * 8}. If we divide 5 and add 5.")
print(
@@ -27,20 +25,19 @@ def print_solution(n: int) -> None:
)
def Game():
def game() -> None:
print("\nTake a Number and ADD 3. Now, Divide this number by 5 and")
print("multiply by 8. Now, Divide by 5 and add the same. Subtract 1")
resp = float(input("\nWhat do you have? "))
comp_guess = (((resp - 4) * 5) / 8) * 5 - 3
resp2 = input(f"\nI bet your number was {comp_guess} was i right(Yes or No)? ")
resp2 = input(f"\nI bet your number was {comp_guess} was I right(Yes or No)? ")
if resp2 == "Yes" or resp2 == "YES" or resp2 == "yes":
if resp2.lower() == "yes":
print("\nHuh, I Knew I was unbeatable")
print("And here is how i did it")
print_solution(comp_guess)
input("")
else:
resp3 = float(input("\nHUH!! what was you original number? "))
@@ -52,7 +49,6 @@ def Game():
print("Here is how i did it")
print_solution(comp_guess)
input("")
else:
print("\nSo you think you're so smart, EH?")
print("Now, Watch")
@@ -60,10 +56,9 @@ def Game():
resp4 = input("\nNow do you believe me? ")
if resp4 == "Yes" or resp4 == "YES" or resp4 == "yes":
if resp4.lower() == "yes":
print("\nOk, Lets play again sometime bye!!!!")
input("")
else:
print("\nYOU HAVE MADE ME VERY MAD!!!!!")
print("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS")
@@ -74,11 +69,10 @@ def Game():
if __name__ == "__main__":
print("I am CHIEF NUMBERS FREEK, The GREAT INDIAN MATH GOD.")
play = input("\nAre you ready to take the test you called me out for(Yes or No)? ")
if play == "Yes" or play == "YES" or play == "yes":
Game()
if play.lower() == "yes":
game()
else:
print("Ok, Nevermind. Let me go back to my great slumber, Bye")
input("")
-1
View File
@@ -125,7 +125,6 @@ def main() -> None:
keep_playing = True
while keep_playing:
play_game()
keep_playing = input("\nAgain (1=Yes, 0=No!) ") == "1"
+11 -10
View File
@@ -5,9 +5,10 @@
import math
import random
from typing import Tuple
def show_welcome():
def show_welcome() -> None:
# Clear screen. chr(27) is `Esc`, and the control sequence is
# initiated by Ctrl+[
# `J` is "Erase in Display" and `2J` means clear the entire screen
@@ -18,14 +19,14 @@ def show_welcome():
print("Creative Computing Morristown, New Jersey\n\n".center(45))
def get_num_charges():
def get_num_charges() -> Tuple[int, int]:
print("Depth Charge game\n")
while True:
search_area = input("Dimensions of search area? ")
search_area_str = input("Dimensions of search area? ")
# Make sure the input is an integer
try:
search_area = int(search_area)
search_area = int(search_area_str)
break
except ValueError:
print("Must enter an integer number. Please try again...")
@@ -34,7 +35,7 @@ def get_num_charges():
return search_area, num_charges
def ask_for_new_game():
def ask_for_new_game() -> None:
answer = input("Another game (Y or N): ")
if answer.lower().strip()[0] == "y":
start_new_game()
@@ -43,7 +44,7 @@ def ask_for_new_game():
exit()
def show_shot_result(shot, location):
def show_shot_result(shot, location) -> None:
result = "Sonar reports shot was "
if shot[1] > location[1]: # y-direction
result += "north"
@@ -66,17 +67,17 @@ def show_shot_result(shot, location):
return
def get_shot_input():
def get_shot_input() -> Tuple[int, int, int]:
while True:
raw_guess = input("Enter coordinates: ")
try:
x, y, z = raw_guess.split()
xyz = raw_guess.split()
except ValueError:
print("Please enter coordinates separated by spaces")
print("Example: 3 2 1")
continue
try:
x, y, z = (int(num) for num in [x, y, z])
x, y, z = (int(num) for num in xyz)
return x, y, z
except ValueError:
print("Please enter whole numbers only")
@@ -111,7 +112,7 @@ def play_game(search_area, num_charges):
ask_for_new_game()
def start_new_game():
def start_new_game() -> None:
search_area, num_charges = get_num_charges()
play_game(search_area, num_charges)
+3 -2
View File
@@ -1,4 +1,5 @@
import random
from typing import List
def print_intro() -> None:
@@ -30,7 +31,7 @@ def print_instructions() -> None:
print()
def read_10_numbers():
def read_10_numbers() -> List[int]:
print("TEN NUMBERS, PLEASE ? ")
numbers = []
@@ -47,7 +48,7 @@ def read_10_numbers():
return numbers
def read_continue_choice():
def read_continue_choice() -> bool:
print("\nDO YOU WANT TO TRY AGAIN (1 FOR YES, 0 FOR NO) ? ")
try:
choice = int(input())
+2 -2
View File
@@ -28,7 +28,7 @@ def print_at_column(column: int, words: str) -> None:
print(spaces + words)
def show_introduction():
def show_introduction() -> None:
"""Show the player the introductory message"""
print("YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN ")
print("1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET")
@@ -39,7 +39,7 @@ def show_introduction():
print("")
def get_fort_choice():
def get_fort_choice() -> int:
"""Show the player the choices of Fort, get their input, if the
input is a valid choice (1,2,3) return it, otherwise keep
prompting the user."""
+9 -8
View File
@@ -1,31 +1,32 @@
from random import random, seed
def gen_random():
def gen_random() -> int:
return int(random() * 5) + 1
def bad_input_850():
def bad_input_850() -> None:
print("\nHAMURABI: I CANNOT DO WHAT YOU WISH.")
print("GET YOURSELF ANOTHER STEWARD!!!!!")
def bad_input_710(S):
def bad_input_710(grain_bushels: int) -> None:
print("HAMURABI: THINK AGAIN. YOU HAVE ONLY")
print(S, "BUSHELS OF GRAIN. NOW THEN,")
print(f"{grain_bushels} BUSHELS OF GRAIN. NOW THEN,")
def bad_input_720(A):
print("HAMURABI: THINK AGAIN. YOU OWN ONLY", A, "ACRES. NOW THEN,")
def bad_input_720(acres: float) -> None:
print(f"HAMURABI: THINK AGAIN. YOU OWN ONLY {acres} ACRES. NOW THEN,")
def national_fink():
def national_fink() -> None:
print("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY")
print("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE")
print("ALSO BEEN DECLARED NATIONAL FINK!!!!")
def b_input(promptstring): # emulate BASIC input. It rejects non-numeric values
def b_input(promptstring: str) -> int:
"""emulate BASIC input. It rejects non-numeric values"""
x = input(promptstring)
while x.isalpha():
x = input("?REDO FROM START\n? ")
+25 -21
View File
@@ -1,15 +1,19 @@
#!/usr/bin/env python3
# HANGMAN
#
# Converted from BASIC to Python by Trevor Hobson and Daniel Piron
"""
HANGMAN
Converted from BASIC to Python by Trevor Hobson and Daniel Piron
"""
import random
from typing import List
class Canvas:
"""For drawing text-based figures"""
def __init__(self, width=12, height=12, fill=" "):
def __init__(self, width: int = 12, height: int = 12, fill: str = " ") -> None:
self._buffer = []
for _ in range(height):
line = []
@@ -19,12 +23,12 @@ class Canvas:
self.clear()
def clear(self, fill=" "):
def clear(self, fill: str = " ") -> None:
for row in self._buffer:
for x in range(len(row)):
row[x] = fill
def render(self):
def render(self) -> str:
lines = []
for line in self._buffer:
# Joining by the empty string ("") smooshes all of the
@@ -32,13 +36,13 @@ class Canvas:
lines.append("".join(line))
return "\n".join(lines)
def put(self, s, x, y):
def put(self, s: str, x: int, y: int) -> None:
# In an effort to avoid distorting the drawn image, only write the
# first character of the given string to the buffer.
self._buffer[y][x] = s[0]
def init_gallows(canvas):
def init_gallows(canvas: Canvas) -> None:
for i in range(12):
canvas.put("X", 0, i)
for i in range(7):
@@ -46,7 +50,7 @@ def init_gallows(canvas):
canvas.put("X", 6, 1)
def draw_head(canvas):
def draw_head(canvas: Canvas) -> None:
canvas.put("-", 5, 2)
canvas.put("-", 6, 2)
canvas.put("-", 7, 2)
@@ -59,47 +63,47 @@ def draw_head(canvas):
canvas.put("-", 7, 4)
def draw_body(canvas):
def draw_body(canvas: Canvas) -> None:
for i in range(5, 9, 1):
canvas.put("X", 6, i)
def draw_right_arm(canvas):
def draw_right_arm(canvas: Canvas) -> None:
for i in range(3, 7):
canvas.put("\\", i - 1, i)
def draw_left_arm(canvas):
def draw_left_arm(canvas: Canvas) -> None:
canvas.put("/", 10, 3)
canvas.put("/", 9, 4)
canvas.put("/", 8, 5)
canvas.put("/", 7, 6)
def draw_right_leg(canvas):
def draw_right_leg(canvas: Canvas) -> None:
canvas.put("/", 5, 9)
canvas.put("/", 4, 10)
def draw_left_leg(canvas):
def draw_left_leg(canvas: Canvas) -> None:
canvas.put("\\", 7, 9)
canvas.put("\\", 8, 10)
def draw_left_hand(canvas):
def draw_left_hand(canvas: Canvas) -> None:
canvas.put("\\", 10, 2)
def draw_right_hand(canvas):
def draw_right_hand(canvas: Canvas) -> None:
canvas.put("/", 2, 2)
def draw_left_foot(canvas):
def draw_left_foot(canvas: Canvas) -> None:
canvas.put("\\", 9, 11)
canvas.put("-", 10, 11)
def draw_right_foot(canvas):
def draw_right_foot(canvas: Canvas) -> None:
canvas.put("-", 2, 11)
canvas.put("/", 3, 11)
@@ -172,11 +176,11 @@ words = [
]
def play_game(guess_target):
def play_game(guess_target: str) -> None:
"""Play one round of the game"""
wrong_guesses = 0
guess_progress = ["-"] * len(guess_target)
guess_list = []
guess_list: List[str] = []
gallows = Canvas()
init_gallows(gallows)
@@ -206,7 +210,7 @@ def play_game(guess_target):
]
for i in indices:
guess_progress[i] = guess_letter
if guess_progress == guess_target:
if "".join(guess_progress) == guess_target:
print("You found the word!")
break
else:
+12 -11
View File
@@ -9,6 +9,7 @@ Ported by Dave LeCompte
"""
import time
from typing import Optional, Tuple
def print_with_tab(space_count: int, msg: str) -> None:
@@ -19,7 +20,7 @@ def print_with_tab(space_count: int, msg: str) -> None:
print(spaces + msg)
def get_yes_or_no():
def get_yes_or_no() -> Tuple[bool, Optional[bool], str]:
msg = input()
if msg.upper() == "YES":
return True, True, msg
@@ -58,7 +59,7 @@ def prompt_for_problems(user_name):
return problem_type
def prompt_too_much_or_too_little():
def prompt_too_much_or_too_little() -> Tuple[bool, Optional[bool]]:
answer = input().upper()
if answer == "TOO MUCH":
return True, True
@@ -67,7 +68,7 @@ def prompt_too_much_or_too_little():
return False, None
def solve_sex_problem(user_name):
def solve_sex_problem(user_name: str) -> None:
print("IS YOUR PROBLEM TOO MUCH OR TOO LITTLE?")
while True:
valid, too_much = prompt_too_much_or_too_little()
@@ -85,31 +86,31 @@ def solve_sex_problem(user_name):
print("WITH 'TOO MUCH' OR 'TOO LITTLE'. WHICH IS IT?")
def solve_money_problem(user_name):
def solve_money_problem(user_name: str) -> None:
print(f"SORRY, {user_name}, I'M BROKE TOO. WHY DON'T YOU SELL")
print("ENCYCLOPEADIAS OR MARRY SOMEONE RICH OR STOP EATING")
print("SO YOU WON'T NEED SO MUCH MONEY?")
def solve_health_problem(user_name):
def solve_health_problem(user_name: str) -> None:
print(f"MY ADVICE TO YOU {user_name} IS:")
print(" 1. TAKE TWO ASPRIN")
print(" 2. DRINK PLENTY OF FLUIDS (ORANGE JUICE, NOT BEER!)")
print(" 3. GO TO BED (ALONE)")
def solve_job_problem(user_name):
def solve_job_problem(user_name: str) -> None:
print(f"I CAN SYMPATHIZE WITH YOU {user_name}. I HAVE TO WORK")
print("VERY LONG HOURS FOR NO PAY -- AND SOME OF MY BOSSES")
print(f"REALLY BEAT ON MY KEYBOARD. MY ADVICE TO YOU, {user_name},")
print("IS TO OPEN A RETAIL COMPUTER STORE. IT'S GREAT FUN.")
def alert_unknown_problem_type(user_name, problem_type):
def alert_unknown_problem_type(user_name: str, problem_type: str) -> None:
print(f"OH, {user_name}, YOUR ANSWER OF {problem_type} IS GREEK TO ME.")
def ask_question_loop(user_name):
def ask_question_loop(user_name: str) -> None:
while True:
problem_type = prompt_for_problems(user_name)
if problem_type == "SEX":
@@ -137,7 +138,7 @@ def ask_question_loop(user_name):
print(f"JUST A SIMPLE 'YES' OR 'NO' PLEASE, {user_name}.")
def ask_for_fee(user_name):
def ask_for_fee(user_name: str) -> None:
print()
print(f"THAT WILL BE $5.00 FOR THE ADVICE, {user_name}.")
print("PLEASE LEAVE THE MONEY ON THE TERMINAL.")
@@ -166,14 +167,14 @@ def ask_for_fee(user_name):
print("PLEASE RESPOND WITH 'YES' or 'NO'.")
def unhappy_goodbye(user_name):
def unhappy_goodbye(user_name: str) -> None:
print()
print(f"TAKE A WALK, {user_name}.")
print()
print()
def happy_goodbye(user_name):
def happy_goodbye(user_name: str) -> None:
print(f"NICE MEETING YOU, {user_name}, HAVE A NICE DAY.")
+49 -45
View File
@@ -44,8 +44,8 @@ Port to Python by Dave LeCompte
# BoardLayout matches the current board, as well as removing losing move
# have been moved into methods of this class.
import collections
import random
from typing import Iterator, List, NamedTuple, Optional, Tuple
PAGE_WIDTH = 64
@@ -53,9 +53,13 @@ HUMAN_PIECE = 1
EMPTY_SPACE = 0
COMPUTER_PIECE = -1
ComputerMove = collections.namedtuple(
"ComputerMove", ["board_index", "move_index", "m1", "m2"]
)
class ComputerMove(NamedTuple):
board_index: int
move_index: int
m1: int
m2: int
wins = 0
losses = 0
@@ -68,10 +72,7 @@ def print_centered(msg: str) -> None:
def print_header(title: str) -> None:
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
def print_instructions() -> None:
@@ -110,7 +111,7 @@ GO FIRST.
)
def prompt_yes_no(msg):
def prompt_yes_no(msg: str) -> bool:
while True:
print(msg)
response = input().upper()
@@ -120,7 +121,7 @@ def prompt_yes_no(msg):
return False
def reverse_space_name(space_name):
def reverse_space_name(space_name: int) -> int:
# reverse a space name in the range 1-9 left to right
assert 1 <= space_name <= 9
@@ -128,36 +129,38 @@ def reverse_space_name(space_name):
return reflections[space_name]
def is_space_in_center_column(space_name):
def is_space_in_center_column(space_name: int) -> bool:
return reverse_space_name(space_name) == space_name
class BoardLayout:
def __init__(self, cells, move_list):
def __init__(self, cells: List[int], move_list: List[Tuple[int, int]]) -> None:
self.cells = cells
self.moves = move_list
def _check_match_no_mirror(self, cell_list):
def _check_match_no_mirror(self, cell_list: List[int]) -> bool:
return all(
board_contents == cell_list[space_index]
for space_index, board_contents in enumerate(self.cells)
)
def _check_match_with_mirror(self, cell_list):
def _check_match_with_mirror(self, cell_list: List[int]) -> bool:
for space_index, board_contents in enumerate(self.cells):
reversed_space_index = reverse_space_name(space_index + 1) - 1
if board_contents != cell_list[reversed_space_index]:
return False
return True
def check_match(self, cell_list):
def check_match(self, cell_list: List[int]) -> Tuple[bool, Optional[bool]]:
if self._check_match_with_mirror(cell_list):
return True, True
elif self._check_match_no_mirror(cell_list):
return True, False
return False, None
def get_random_move(self, reverse_board):
def get_random_move(
self, reverse_board: Optional[bool]
) -> Optional[Tuple[int, int, int]]:
if not self.moves:
return None
move_index = random.randrange(len(self.moves))
@@ -193,7 +196,7 @@ boards = [
]
def get_move(board_index, move_index):
def get_move(board_index: int, move_index: int) -> Tuple[int, int]:
assert board_index >= 0 and board_index < len(boards)
board = boards[board_index]
@@ -202,7 +205,7 @@ def get_move(board_index, move_index):
return board.moves[move_index]
def remove_move(board_index, move_index):
def remove_move(board_index: int, move_index: int) -> None:
assert board_index >= 0 and board_index < len(boards)
board = boards[board_index]
@@ -211,11 +214,11 @@ def remove_move(board_index, move_index):
del board.moves[move_index]
def init_board():
def init_board() -> List[int]:
return [COMPUTER_PIECE] * 3 + [EMPTY_SPACE] * 3 + [HUMAN_PIECE] * 3
def print_board(board) -> None:
def print_board(board: List[int]) -> None:
piece_dict = {COMPUTER_PIECE: "X", EMPTY_SPACE: ".", HUMAN_PIECE: "O"}
space = " " * 10
@@ -231,7 +234,7 @@ def print_board(board) -> None:
print()
def get_coordinates():
def get_coordinates() -> Tuple[int, int]:
while True:
try:
print("YOUR MOVE?")
@@ -246,15 +249,15 @@ def print_illegal() -> None:
print("ILLEGAL MOVE.")
def board_contents(board, space_number):
def board_contents(board: List[int], space_number: int) -> int:
return board[space_number - 1]
def set_board(board, space_number, new_value):
def set_board(board: List[int], space_number: int, new_value: int) -> None:
board[space_number - 1] = new_value
def is_legal_human_move(board, m1, m2):
def is_legal_human_move(board: List[int], m1: int, m2: int) -> bool:
if board_contents(board, m1) != HUMAN_PIECE:
# Start space doesn't contain player's piece
return False
@@ -285,30 +288,30 @@ def is_legal_human_move(board, m1, m2):
return True
def player_piece_on_back_row(board):
def player_piece_on_back_row(board: List[int]) -> bool:
return any(board_contents(board, space) == HUMAN_PIECE for space in range(1, 4))
def computer_piece_on_front_row(board):
def computer_piece_on_front_row(board: List[int]) -> bool:
return any(board_contents(board, space) == COMPUTER_PIECE for space in range(7, 10))
def all_human_pieces_captured(board):
def all_human_pieces_captured(board: List[int]) -> bool:
return len(list(get_human_spaces(board))) == 0
def all_computer_pieces_captured(board):
def all_computer_pieces_captured(board: List[int]) -> bool:
return len(list(get_computer_spaces(board))) == 0
def human_win(last_computer_move):
def human_win(last_computer_move: ComputerMove) -> None:
print("YOU WIN")
remove_move(last_computer_move.board_index, last_computer_move.move_index)
global losses
losses += 1
def computer_win(has_moves):
def computer_win(has_moves: bool) -> None:
if not has_moves:
msg = "YOU CAN'T MOVE, SO "
else:
@@ -319,12 +322,11 @@ def computer_win(has_moves):
wins += 1
def show_scores():
print(f"I HAVE WON {wins} AND YOU {losses} OUT OF {wins + losses} GAMES.")
print()
def show_scores() -> None:
print(f"I HAVE WON {wins} AND YOU {losses} OUT OF {wins + losses} GAMES.\n")
def human_has_move(board):
def human_has_move(board: List[int]) -> bool:
for i in get_human_spaces(board):
if board_contents(board, i - 3) == EMPTY_SPACE:
# can move piece forward
@@ -353,31 +355,31 @@ def human_has_move(board):
return False
def get_board_spaces():
def get_board_spaces() -> Iterator[int]:
"""generates the space names (1-9)"""
yield from range(1, 10)
def get_board_spaces_with(board, val):
def get_board_spaces_with(board: List[int], val: int) -> Iterator[int]:
"""generates spaces containing pieces of type val"""
for i in get_board_spaces():
if board_contents(board, i) == val:
yield i
def get_human_spaces(board):
def get_human_spaces(board: List[int]) -> Iterator[int]:
yield from get_board_spaces_with(board, HUMAN_PIECE)
def get_empty_spaces(board):
def get_empty_spaces(board: List[int]) -> Iterator[int]:
yield from get_board_spaces_with(board, EMPTY_SPACE)
def get_computer_spaces(board):
def get_computer_spaces(board: List[int]) -> Iterator[int]:
yield from get_board_spaces_with(board, COMPUTER_PIECE)
def has_computer_move(board):
def has_computer_move(board: List[int]) -> bool:
for i in get_computer_spaces(board):
if board_contents(board, i + 3) == EMPTY_SPACE:
# can move forward (down)
@@ -406,7 +408,7 @@ def has_computer_move(board):
return False
def find_board_index_that_matches_board(board):
def find_board_index_that_matches_board(board: List[int]) -> Tuple[int, Optional[bool]]:
for board_index, board_layout in enumerate(boards):
matches, is_reversed = board_layout.check_match(board)
if matches:
@@ -417,7 +419,7 @@ def find_board_index_that_matches_board(board):
raise RuntimeError("ILLEGAL BOARD PATTERN.")
def pick_computer_move(board):
def pick_computer_move(board: List[int]) -> Optional[ComputerMove]:
if not has_computer_move(board):
return None
@@ -434,7 +436,7 @@ def pick_computer_move(board):
return ComputerMove(board_index, move_index, m1, m2)
def get_human_move(board):
def get_human_move(board: List[int]) -> Tuple[int, int]:
while True:
m1, m2 = get_coordinates()
@@ -444,12 +446,12 @@ def get_human_move(board):
return m1, m2
def apply_move(board, m1, m2, piece_value):
def apply_move(board: List[int], m1: int, m2: int, piece_value: int) -> None:
set_board(board, m1, EMPTY_SPACE)
set_board(board, m2, piece_value)
def play_game():
def play_game() -> None:
last_computer_move = None
board = init_board()
@@ -464,11 +466,13 @@ def play_game():
print_board(board)
if player_piece_on_back_row(board) or all_computer_pieces_captured(board):
assert last_computer_move is not None
human_win(last_computer_move)
return
computer_move = pick_computer_move(board)
if computer_move is None:
assert last_computer_move is not None
human_win(last_computer_move)
return
+4 -3
View File
@@ -1,6 +1,7 @@
import math
import random
import time
from typing import List
def basic_print(*zones, **kwargs) -> None:
@@ -17,7 +18,7 @@ def basic_print(*zones, **kwargs) -> None:
print(" " * identation + line, end=end)
def basic_input(prompt, type_conversion=None):
def basic_input(prompt: str, type_conversion=None):
"""BASIC INPUT command with optional type conversion"""
while True:
@@ -45,7 +46,7 @@ HORSE_NAMES = [
]
def introduction():
def introduction() -> None:
"""Print the introduction, and optional the instructions"""
basic_print("HORSERACE", indent=31)
@@ -66,7 +67,7 @@ def introduction():
basic_print("")
def setup_players():
def setup_players() -> List[str]:
"""Gather the number of players and their names"""
# ensure we get an integer value from the user
+91 -96
View File
@@ -6,8 +6,8 @@ Lunar landing simulation
Ported by Dave LeCompte
"""
import collections
import math
from typing import Any, NamedTuple
PAGE_WIDTH = 64
@@ -32,7 +32,10 @@ FUEL_RIGHT = FUEL_LEFT + FUEL_WIDTH
BURN_LEFT = FUEL_RIGHT + COLUMN_WIDTH
BURN_RIGHT = BURN_LEFT + BURN_WIDTH
PhysicalState = collections.namedtuple("PhysicalState", ["velocity", "altitude"])
class PhysicalState(NamedTuple):
velocity: float
altitude: float
def print_centered(msg: str) -> None:
@@ -42,29 +45,24 @@ def print_centered(msg: str) -> None:
def print_header(title: str) -> None:
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
def add_rjust(line, s, pos):
# adds a new field to a line right justified to end at pos
s = str(s)
slen = len(s)
def add_rjust(line: str, s: Any, pos: int) -> str:
"""Add a new field to a line right justified to end at pos"""
s_str = str(s)
slen = len(s_str)
if len(line) + slen > pos:
new_len = pos - slen
line = line[:new_len]
if len(line) + slen < pos:
spaces = " " * (pos - slen - len(line))
line = line + spaces
return line + s
return line + s_str
def add_ljust(line, s, pos):
# adds a new field to a line left justified starting at pos
def add_ljust(line: str, s: str, pos: int) -> str:
"""Add a new field to a line left justified starting at pos"""
s = str(s)
if len(line) > pos:
line = line[:pos]
@@ -75,59 +73,30 @@ def add_ljust(line, s, pos):
def print_instructions() -> None:
# Somebody had a bad experience with Xerox.
"""Somebody had a bad experience with Xerox."""
print("THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR")
print("LANDING CAPSULE.")
print()
print()
print("LANDING CAPSULE.\n\n")
print("THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY")
print("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.")
print()
print("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.\n")
def print_intro() -> None:
print("SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN")
print("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.")
print("SET NEW BURN RATE EVERY 10 SECONDS.")
print()
print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.")
print()
print()
print()
print("GOOD LUCK")
print()
print("SET NEW BURN RATE EVERY 10 SECONDS.\n")
print("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.\n\n\n")
print("GOOD LUCK\n")
def show_landing(sim_clock, capsule):
w = 3600 * capsule.v
print(
f"ON MOON AT {sim_clock.elapsed_time:.2f} SECONDS - IMPACT VELOCITY {w:.2f} MPH"
)
if w < 1.2:
print("PERFECT LANDING!")
elif w < 10:
print("GOOD LANDING (COULD BE BETTER)")
elif w <= 60:
print("CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE")
print("PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!")
else:
print("SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!")
print(f"IN FACT, YOU BLASTED A NEW LUNAR CRATER {w*.227:.2f} FEET DEEP!")
end_sim()
def show_out_of_fuel(sim_clock, capsule):
print(f"FUEL OUT AT {sim_clock.elapsed_time} SECONDS")
delta_t = (
-capsule.v + math.sqrt(capsule.v**2 + 2 * capsule.a * capsule.g)
) / capsule.g
capsule.v += capsule.g * delta_t
sim_clock.advance(delta_t)
show_landing(sim_clock, capsule)
def format_line_for_report(t, miles, feet, velocity, fuel, burn_rate, is_header) -> str:
def format_line_for_report(
t: Any,
miles: Any,
feet: Any,
velocity: Any,
fuel: Any,
burn_rate: str,
is_header: bool,
) -> str:
line = add_rjust("", t, SECONDS_RIGHT)
line = add_rjust(line, miles, ALT_MI_RIGHT)
line = add_rjust(line, feet, ALT_FT_RIGHT)
@@ -140,42 +109,57 @@ def format_line_for_report(t, miles, feet, velocity, fuel, burn_rate, is_header)
return line
class SimulationClock:
def __init__(self, elapsed_time: float, time_until_next_prompt: float) -> None:
self.elapsed_time = elapsed_time
self.time_until_next_prompt = time_until_next_prompt
def time_for_prompt(self) -> bool:
return self.time_until_next_prompt < 1e-3
def advance(self, delta_t: float) -> None:
self.elapsed_time += delta_t
self.time_until_next_prompt -= delta_t
class Capsule:
def __init__(
self,
altitude=120,
velocity=1,
mass_with_fuel=33000,
mass_without_fuel=16500,
g=1e-3,
z=1.8,
):
altitude: float = 120,
velocity: float = 1,
mass_with_fuel: float = 33000,
mass_without_fuel: float = 16500,
g: float = 1e-3,
z: float = 1.8,
) -> None:
self.a = altitude # in miles above the surface
self.v = velocity # downward
self.m = mass_with_fuel
self.n = mass_without_fuel
self.g = g
self.z = z
self.fuel_per_second = 0
self.fuel_per_second: float = 0
def remaining_fuel(self):
def remaining_fuel(self) -> float:
return self.m - self.n
def is_out_of_fuel(self):
def is_out_of_fuel(self) -> bool:
return self.remaining_fuel() < 1e-3
def update_state(self, sim_clock, delta_t, new_state):
def update_state(
self, sim_clock: SimulationClock, delta_t: float, new_state: PhysicalState
) -> None:
sim_clock.advance(delta_t)
self.m = self.m - delta_t * self.fuel_per_second
self.a = new_state.altitude
self.v = new_state.velocity
def fuel_time_remaining(self):
def fuel_time_remaining(self) -> float:
# extrapolates out how many seconds we have at the current fuel burn rate
assert self.fuel_per_second > 0
return self.remaining_fuel() / self.fuel_per_second
def predict_motion(self, delta_t):
def predict_motion(self, delta_t: float) -> PhysicalState:
# Perform an Euler's Method numerical integration of the equations of motion.
q = delta_t * self.fuel_per_second / self.m
@@ -199,7 +183,7 @@ class Capsule:
return PhysicalState(altitude=new_altitude, velocity=new_velocity)
def make_state_display_string(self, sim_clock) -> str:
def make_state_display_string(self, sim_clock: SimulationClock) -> str:
seconds = sim_clock.elapsed_time
miles = int(self.a)
feet = int(5280 * (self.a - miles))
@@ -211,27 +195,44 @@ class Capsule:
seconds, miles, feet, velocity, fuel, burn_rate, False
)
def prompt_for_burn(self, sim_clock):
def prompt_for_burn(self, sim_clock: SimulationClock) -> None:
msg = self.make_state_display_string(sim_clock)
self.fuel_per_second = float(input(msg))
sim_clock.time_until_next_prompt = 10
class SimulationClock:
def __init__(self, elapsed_time, time_until_next_prompt):
self.elapsed_time = elapsed_time
self.time_until_next_prompt = time_until_next_prompt
def time_for_prompt(self):
return self.time_until_next_prompt < 1e-3
def advance(self, delta_t):
self.elapsed_time += delta_t
self.time_until_next_prompt -= delta_t
def show_landing(sim_clock: SimulationClock, capsule: Capsule) -> None:
w = 3600 * capsule.v
print(
f"ON MOON AT {sim_clock.elapsed_time:.2f} SECONDS - IMPACT VELOCITY {w:.2f} MPH"
)
if w < 1.2:
print("PERFECT LANDING!")
elif w < 10:
print("GOOD LANDING (COULD BE BETTER)")
elif w <= 60:
print("CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE")
print("PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!")
else:
print("SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!")
print(f"IN FACT, YOU BLASTED A NEW LUNAR CRATER {w*.227:.2f} FEET DEEP!")
end_sim()
def process_final_tick(delta_t, sim_clock, capsule):
def show_out_of_fuel(sim_clock: SimulationClock, capsule: Capsule) -> None:
print(f"FUEL OUT AT {sim_clock.elapsed_time} SECONDS")
delta_t = (
-capsule.v + math.sqrt(capsule.v**2 + 2 * capsule.a * capsule.g)
) / capsule.g
capsule.v += capsule.g * delta_t
sim_clock.advance(delta_t)
show_landing(sim_clock, capsule)
def process_final_tick(
delta_t: float, sim_clock: SimulationClock, capsule: Capsule
) -> None:
# When we extrapolated our position based on our velocity
# and delta_t, we overshot the surface. For better
# accuracy, we will back up and do shorter time advances.
@@ -255,7 +256,7 @@ def process_final_tick(delta_t, sim_clock, capsule):
capsule.update_state(sim_clock, delta_t, new_state)
def handle_flyaway(sim_clock, capsule):
def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
"""
The user has started flying away from the moon. Since this is a
lunar LANDING simulation, we wait until the capsule's velocity is
@@ -289,17 +290,11 @@ def handle_flyaway(sim_clock, capsule):
return False
def end_sim():
print()
print()
print()
print("TRY AGAIN??")
print()
print()
print()
def end_sim() -> None:
print("\n\n\nTRY AGAIN??\n\n\n")
def run_simulation():
def run_simulation() -> None:
print()
print(
format_line_for_report("SEC", "MI", "FT", "MPH", "LB FUEL", "BURN RATE", True)
+2 -2
View File
@@ -15,9 +15,9 @@ def print_with_tab(space_count: int, msg: str) -> None:
print(spaces + msg)
def is_yes_ish(answer):
def is_yes_ish(answer: str) -> bool:
cleaned = answer.strip().upper()
if cleaned == "Y" or cleaned == "YES":
if cleaned in ["Y", "YES"]:
return True
return False
+4 -7
View File
@@ -81,7 +81,7 @@ GOOD LUCK. THE FEDERATION IS COUNTING ON YOU.
)
def get_yes_or_no():
def get_yes_or_no() -> bool:
while True:
response = input().upper()
if response == "YES":
@@ -92,7 +92,7 @@ def get_yes_or_no():
print("PLEASE TYPE 'YES' OR 'NO'")
def game_over(is_success):
def game_over(is_success: bool) -> bool:
if is_success:
print("YOU HAVE SUCCESSFULLY COMPLETED YOUR MISSION.")
else:
@@ -103,7 +103,7 @@ def game_over(is_success):
return get_yes_or_no()
def play_game():
def play_game() -> bool:
rom_angle = random.randint(0, 359)
rom_distance = random.randint(100, 300)
rom_angular_velocity = random.randint(10, 30)
@@ -145,10 +145,7 @@ def play_game():
def main() -> None:
print_centered("ORBIT")
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n")
print_instructions()
+1 -1
View File
@@ -192,7 +192,7 @@ if __name__ == "__main__":
help = input("\nDO YOU WANT INSTRUCTIONS(YES OR NO)? ")
# Printing Instruction
if help == "YES" or help == "yes" or help == "Yes":
if help.lower() == "yes":
print_instruction()
# Initialize Game
+28 -25
View File
@@ -1,15 +1,17 @@
# **** **** STAR TREK **** ****
# **** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE,
# **** AS SEEN ON THE STAR TREK TV SHOW.
# **** ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION
# **** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL.
# **** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB
# **** LEEDOM - APRIL & DECEMBER 1974,
# **** WITH A LITTLE HELP FROM HIS FRIENDS . . .
#
# Python translation by Jack Boyce - February 2021
# Output is identical to BASIC version except for a few
# fixes (as noted, search `bug`) and minor cleanup.
"""
**** **** STAR TREK **** ****
**** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE,
**** AS SEEN ON THE STAR TREK TV SHOW.
**** ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION
**** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL.
**** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB
**** LEEDOM - APRIL & DECEMBER 1974,
**** WITH A LITTLE HELP FROM HIS FRIENDS . . .
Python translation by Jack Boyce - February 2021
Output is identical to BASIC version except for a few
fixes (as noted, search `bug`) and minor cleanup.
"""
import random
@@ -20,7 +22,7 @@ from typing import Any, Callable, Dict, List, Tuple
restart = False
s = 0
e = 0
d: List[int] = []
d: List[float] = []
k: List[List[float]] = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] # Klingons in current quadrant
devices = [
"WARP ENGINES",
@@ -53,6 +55,7 @@ qs = " " * 192 # quadrant string
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: float
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
@@ -71,12 +74,12 @@ d4 = 0.5 * random.random() # extra delay in repairs at base
# -------------------------------------------------------------------------
def fnr():
def fnr() -> int:
# Generate a random integer from 0 to 7 inclusive.
return random.randint(0, 7)
def quadrant_name(row, col, region_only=False):
def quadrant_name(row: int, col: int, region_only: bool = False) -> str:
# Return quadrant name visible on scans, etc.
region1 = [
"ANTARES",
@@ -108,7 +111,7 @@ def quadrant_name(row, col, region_only=False):
return quadrant
def insert_marker(row, col, marker):
def insert_marker(row: float, col: float, marker: str) -> None:
# Insert a marker into a given position in the quadrant string `qs`. The
# contents of a quadrant (Enterprise, stars, etc.) are stored in `qs`.
global qs
@@ -121,7 +124,7 @@ def insert_marker(row, col, marker):
qs = qs[0:pos] + marker + qs[(pos + 3) : 192]
def compare_marker(row, col, test_marker):
def compare_marker(row: float, col: float, test_marker: str) -> bool:
# Check whether the position in the current quadrant is occupied with a
# given marker.
pos = round(col) * 3 + round(row) * 24
@@ -192,9 +195,9 @@ def navigation() -> None:
line = ""
for i in range(8):
if d[i] < 0:
d[i] += min(warp, 1) # type: ignore
d[i] += min(warp, 1)
if -0.1 < d[i] < 0:
d[i] = -0.1 # type: ignore
d[i] = -0.1
elif d[i] >= 0:
if len(line) == 0:
line = "DAMAGE CONTROL REPORT:"
@@ -282,7 +285,7 @@ def navigation() -> None:
insert_marker(int(s1), int(s2), "<*>")
maneuver_energy(n)
t += 0.1 * int(10 * warp) if warp < 1 else 1 # type: ignore
t += 0.1 * int(10 * warp) if warp < 1 else 1
if t > t0 + t9:
end_game(won=False, quit=False)
return
@@ -290,7 +293,7 @@ def navigation() -> None:
short_range_scan()
def maneuver_energy(n):
def maneuver_energy(n: int) -> None:
# Deduct the energy for navigation from energy/shields.
global e, s
@@ -534,12 +537,12 @@ def photon_torpedoes() -> None:
klingons_fire()
def fnd(i):
def fnd(i: int) -> float:
# Find distance between Enterprise and i'th Klingon warship.
return sqrt((k[i][0] - s1) ** 2 + (k[i][1] - s2) ** 2)
def klingons_fire():
def klingons_fire() -> None:
# Process nearby Klingons firing on Enterprise.
global s, k, d
@@ -601,7 +604,7 @@ def shield_control() -> None:
print(f" 'SHIELDS NOW AT {s} UNITS PER YOUR COMMAND.'")
def damage_control():
def damage_control() -> None:
# Print a damage control report.
global d, t
@@ -762,7 +765,7 @@ def computer() -> None:
)
def print_direction(from1, from2, to1, to2) -> None:
def print_direction(from1: float, from2: float, to1: float, to2: float) -> None:
# Print direction and distance between two locations in the grid.
delta1 = -(to1 - from1) # flip so positive is up (heading = 3)
delta2 = to2 - from2
@@ -8,7 +8,7 @@ Ported by Dave LeCompte
"""
def get_yes_no(prompt):
def get_yes_no(prompt: str) -> bool:
response = input(prompt).upper()
return response[0] != "N"