mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
Use NamedTuple; Fix camelCase->snake_case
This commit is contained in:
@@ -7,16 +7,15 @@ From: BASIC Computer Games (1978)
|
||||
Python port by Aviyam Fischer, 2022
|
||||
"""
|
||||
|
||||
from typing import List, Literal, TypeAlias, get_args
|
||||
from typing import List, Literal, NamedTuple, TypeAlias, get_args
|
||||
|
||||
Suit: TypeAlias = Literal["\u2665", "\u2666", "\u2663", "\u2660"]
|
||||
Rank: TypeAlias = Literal[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
|
||||
class Card:
|
||||
def __init__(self, suit: Suit, rank: Rank) -> None:
|
||||
self.suit = suit
|
||||
self.rank = rank
|
||||
class Card(NamedTuple):
|
||||
suit: Suit
|
||||
rank: Rank
|
||||
|
||||
def __str__(self) -> str:
|
||||
r = str(self.rank)
|
||||
|
||||
@@ -7,11 +7,7 @@ from typing import List, Tuple
|
||||
|
||||
|
||||
class Maze:
|
||||
def __init__(
|
||||
self,
|
||||
width: int,
|
||||
length: int,
|
||||
):
|
||||
def __init__(self, width: int, length: int) -> None:
|
||||
assert width >= 2 and length >= 2
|
||||
used: List[List[int]] = []
|
||||
walls: List[List[int]] = []
|
||||
@@ -117,7 +113,7 @@ def build_maze(width: int, length: int) -> Maze:
|
||||
else:
|
||||
while True:
|
||||
if position.col != width - 1:
|
||||
position.col = position.col + 1
|
||||
position.col += 1
|
||||
elif position.row != length - 1:
|
||||
position.row, position.col = position.row + 1, 0
|
||||
else:
|
||||
|
||||
@@ -86,10 +86,10 @@ def print_banner() -> None:
|
||||
|
||||
for statement_char in statement:
|
||||
s = letters[statement_char].copy()
|
||||
xStr = character
|
||||
x_str = character
|
||||
if character == "ALL":
|
||||
xStr = statement_char
|
||||
if xStr == " ":
|
||||
x_str = statement_char
|
||||
if x_str == " ":
|
||||
print("\n" * (7 * horizontal))
|
||||
else:
|
||||
for u in range(0, 7):
|
||||
@@ -103,13 +103,13 @@ def print_banner() -> None:
|
||||
f[u] = 8 - k
|
||||
break
|
||||
for _t1 in range(1, horizontal + 1):
|
||||
line_str = " " * int((63 - 4.5 * vertical) * g1 / len(xStr) + 1)
|
||||
line_str = " " * int((63 - 4.5 * vertical) * g1 / len(x_str) + 1)
|
||||
for b in range(0, f[u] + 1):
|
||||
if j[b] == 0:
|
||||
for _ in range(1, vertical + 1):
|
||||
line_str = line_str + " " * len(xStr)
|
||||
line_str = line_str + " " * len(x_str)
|
||||
else:
|
||||
line_str = line_str + xStr * vertical
|
||||
line_str = line_str + x_str * vertical
|
||||
print(line_str)
|
||||
print("\n" * (2 * horizontal - 1))
|
||||
# print("\n" * 75) # Feed some more paper from the printer
|
||||
|
||||
@@ -64,12 +64,12 @@ def get_params() -> Tuple[int, int, int, StartOptions, WinOptions]:
|
||||
"""This requests the necessary parameters to play the game.
|
||||
|
||||
Returns a set with the five game parameters:
|
||||
pileSize - the starting size of the object pile
|
||||
minSelect - minimum selection that can be made on each turn
|
||||
maxSelect - maximum selection that can be made on each turn
|
||||
startOption - 1 if the computer is first
|
||||
pile_size - the starting size of the object pile
|
||||
min_select - minimum selection that can be made on each turn
|
||||
max_select - maximum selection that can be made on each turn
|
||||
start_option - 1 if the computer is first
|
||||
or 2 if the player is first
|
||||
winOption - 1 if the goal is to take the last object
|
||||
win_option - 1 if the goal is to take the last object
|
||||
or 2 if the goal is to not take the last object
|
||||
"""
|
||||
pile_size = get_pile_size()
|
||||
@@ -123,7 +123,7 @@ def player_move(
|
||||
to take and doing some basic validation around that input. Then it
|
||||
checks for any win conditions.
|
||||
|
||||
Returns a boolean indicating whether the game is over and the new pileSize."""
|
||||
Returns a boolean indicating whether the game is over and the new pile_size."""
|
||||
player_done = False
|
||||
while not player_done:
|
||||
player_move = int(input("YOUR MOVE "))
|
||||
@@ -167,7 +167,7 @@ def computer_move(
|
||||
win/lose conditions and then calculating how many objects
|
||||
the computer will take.
|
||||
|
||||
Returns a boolean indicating whether the game is over and the new pileSize."""
|
||||
Returns a boolean indicating whether the game is over and the new pile_size."""
|
||||
# First, check for win conditions on this move
|
||||
# In this case, we win by taking the last object and
|
||||
# the remaining pile is less than max select
|
||||
@@ -200,7 +200,7 @@ def play_game(
|
||||
of the win/lose conditions is met.
|
||||
"""
|
||||
game_over = False
|
||||
# playersTurn is a boolean keeping track of whether it's the
|
||||
# players_turn is a boolean keeping track of whether it's the
|
||||
# player's or computer's turn
|
||||
players_turn = start_option == StartOptions.PlayerFirst
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ def game() -> None:
|
||||
print("\nHuh, I Knew I was unbeatable")
|
||||
print("And here is how i did it")
|
||||
print_solution(comp_guess)
|
||||
input("")
|
||||
input()
|
||||
else:
|
||||
resp3 = float(input("\nHUH!! what was you original number? "))
|
||||
|
||||
@@ -48,7 +48,7 @@ def game() -> None:
|
||||
)
|
||||
print("Here is how i did it")
|
||||
print_solution(comp_guess)
|
||||
input("")
|
||||
input()
|
||||
else:
|
||||
print("\nSo you think you're so smart, EH?")
|
||||
print("Now, Watch")
|
||||
@@ -58,14 +58,14 @@ def game() -> None:
|
||||
|
||||
if resp4.lower() == "yes":
|
||||
print("\nOk, Lets play again sometime bye!!!!")
|
||||
input("")
|
||||
input()
|
||||
else:
|
||||
print("\nYOU HAVE MADE ME VERY MAD!!!!!")
|
||||
print("BY THE WRATH OF THE MATHEMATICS AND THE RAGE OF THE GODS")
|
||||
print("THERE SHALL BE LIGHTNING!!!!!!!")
|
||||
print_lightning_bolt()
|
||||
print("\nI Hope you believe me now, for your own sake")
|
||||
input("")
|
||||
input()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -75,4 +75,4 @@ if __name__ == "__main__":
|
||||
game()
|
||||
else:
|
||||
print("Ok, Nevermind. Let me go back to my great slumber, Bye")
|
||||
input("")
|
||||
input()
|
||||
|
||||
@@ -8,7 +8,7 @@ Ported by Dave LeCompte
|
||||
|
||||
|
||||
def print_diamond(begin_width, end_width, step, width, count) -> None:
|
||||
edgeString = "CC"
|
||||
edge_string = "CC"
|
||||
fill = "!"
|
||||
|
||||
n = begin_width
|
||||
@@ -16,10 +16,10 @@ def print_diamond(begin_width, end_width, step, width, count) -> None:
|
||||
line_buffer = " " * ((width - n) // 2)
|
||||
for across in range(count):
|
||||
for a in range(n):
|
||||
if a >= len(edgeString):
|
||||
if a >= len(edge_string):
|
||||
line_buffer += fill
|
||||
else:
|
||||
line_buffer += edgeString[a]
|
||||
line_buffer += edge_string[a]
|
||||
line_buffer += " " * (
|
||||
(width * (across + 1) + (width - n) // 2) - len(line_buffer)
|
||||
)
|
||||
|
||||
@@ -129,8 +129,8 @@ def clear_console() -> None:
|
||||
|
||||
|
||||
class Point(NamedTuple):
|
||||
X: int
|
||||
Y: int
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
class GameObjType(enum.Enum):
|
||||
@@ -183,14 +183,14 @@ class HoleGeometry(NamedTuple):
|
||||
|
||||
@dataclass
|
||||
class Plot:
|
||||
X: int
|
||||
Y: int
|
||||
Offline: int
|
||||
x: int
|
||||
y: int
|
||||
offline: int
|
||||
|
||||
|
||||
def get_distance(pt1: Point, pt2: Point) -> float:
|
||||
"""distance between 2 points"""
|
||||
return math.sqrt(math.pow((pt2.X - pt1.X), 2) + math.pow((pt2.Y - pt1.Y), 2))
|
||||
return math.sqrt(math.pow((pt2.x - pt1.x), 2) + math.pow((pt2.y - pt1.y), 2))
|
||||
|
||||
|
||||
def is_in_rectangle(pt: CircleGameObj, rect: RectGameObj) -> bool:
|
||||
@@ -392,9 +392,9 @@ ace = 0b10000000000000
|
||||
|
||||
|
||||
class Golf:
|
||||
BALL: Ball
|
||||
HOLE_NUM: int = 0
|
||||
STROKE_NUM: int = 0
|
||||
ball: Ball
|
||||
hole_num: int = 0
|
||||
stroke_num: int = 0
|
||||
handicap: int = 0
|
||||
player_difficulty: int = 0
|
||||
hole_geometry: HoleGeometry
|
||||
@@ -491,10 +491,10 @@ class Golf:
|
||||
self.new_hole()
|
||||
|
||||
def new_hole(self) -> None:
|
||||
self.HOLE_NUM += 1
|
||||
self.STROKE_NUM = 0
|
||||
self.hole_num += 1
|
||||
self.stroke_num = 0
|
||||
|
||||
info: HoleInfo = CourseInfo[self.HOLE_NUM]
|
||||
info: HoleInfo = CourseInfo[self.hole_num]
|
||||
|
||||
yards: int = info.yards
|
||||
# from tee to cup
|
||||
@@ -517,19 +517,19 @@ class Golf:
|
||||
GameObjType.ROUGH,
|
||||
)
|
||||
|
||||
self.BALL = Ball(0, yards, 0, GameObjType.BALL)
|
||||
self.ball = Ball(0, yards, 0, GameObjType.BALL)
|
||||
|
||||
self.score_card_start_new_hole()
|
||||
|
||||
self.hole_geometry = HoleGeometry(cup, green, fairway, rough, info.hazards)
|
||||
|
||||
print(f" |> {self.HOLE_NUM}")
|
||||
print(f" |> {self.hole_num}")
|
||||
print(" | ")
|
||||
print(" | ")
|
||||
print(" ^^^^^^^^^^^^^^^")
|
||||
|
||||
print(
|
||||
f"Hole #{self.HOLE_NUM}. You are at the tee. Distance {info.yards} yards, par {info.par}."
|
||||
f"Hole #{self.hole_num}. You are at the tee. Distance {info.yards} yards, par {info.par}."
|
||||
)
|
||||
print(info.description)
|
||||
|
||||
@@ -560,8 +560,8 @@ class Golf:
|
||||
def tee_up(self) -> None:
|
||||
# on the green? automatically select putter
|
||||
# otherwise Ask club and swing strength
|
||||
if self.is_on_green(self.BALL) and not self.is_in_hazard(
|
||||
self.BALL, GameObjType.SAND
|
||||
if self.is_on_green(self.ball) and not self.is_in_hazard(
|
||||
self.ball, GameObjType.SAND
|
||||
):
|
||||
self.putt = 10
|
||||
print("[PUTTER: average 10 yards]")
|
||||
@@ -579,13 +579,13 @@ class Golf:
|
||||
else:
|
||||
self.ask("What club do you choose? (1-10)", 1, 10, self.ask_gauge)
|
||||
|
||||
def stroke(self, clubAmt: float, clubIndex: int) -> None:
|
||||
self.STROKE_NUM += 1
|
||||
def stroke(self, club_amt: float, club_index: int) -> None:
|
||||
self.stroke_num += 1
|
||||
|
||||
flags = 0b000000000000
|
||||
|
||||
# fore! only when driving
|
||||
if (self.STROKE_NUM == 1) and (clubAmt > 210) and odds(30):
|
||||
if (self.stroke_num == 1) and (club_amt > 210) and odds(30):
|
||||
print('"...Fore !"')
|
||||
|
||||
# dub
|
||||
@@ -596,37 +596,37 @@ class Golf:
|
||||
# if you're in the rough, or sand, you really should be using a wedge
|
||||
if (
|
||||
(
|
||||
self.is_in_rough(self.BALL)
|
||||
or self.is_in_hazard(self.BALL, GameObjType.SAND)
|
||||
self.is_in_rough(self.ball)
|
||||
or self.is_in_hazard(self.ball, GameObjType.SAND)
|
||||
)
|
||||
and not (clubIndex == 8 or clubIndex == 9)
|
||||
and not (club_index == 8 or club_index == 9)
|
||||
and odds(40)
|
||||
):
|
||||
flags |= dub
|
||||
|
||||
# trap difficulty
|
||||
if (
|
||||
self.is_in_hazard(self.BALL, GameObjType.SAND)
|
||||
self.is_in_hazard(self.ball, GameObjType.SAND)
|
||||
and self.player_difficulty == 4
|
||||
) and odds(20):
|
||||
flags |= dub
|
||||
|
||||
# hook/slice
|
||||
# There's 10% chance of a hook or slice
|
||||
# if it's a known playerDifficulty then increase chance to 30%
|
||||
# if it's a putt & putting is a playerDifficulty increase to 30%
|
||||
# if it's a known player_difficulty then increase chance to 30%
|
||||
# if it's a putt & putting is a player_difficulty increase to 30%
|
||||
|
||||
randHookSlice: bool
|
||||
rand_hook_slice: bool
|
||||
if (
|
||||
self.player_difficulty == 1
|
||||
or self.player_difficulty == 2
|
||||
or (self.player_difficulty == 5 and self.is_on_green(self.BALL))
|
||||
or (self.player_difficulty == 5 and self.is_on_green(self.ball))
|
||||
):
|
||||
randHookSlice = odds(30)
|
||||
rand_hook_slice = odds(30)
|
||||
else:
|
||||
randHookSlice = odds(10)
|
||||
rand_hook_slice = odds(10)
|
||||
|
||||
if randHookSlice:
|
||||
if rand_hook_slice:
|
||||
if self.player_difficulty == 1:
|
||||
if odds(80):
|
||||
flags |= hook
|
||||
@@ -650,7 +650,7 @@ class Golf:
|
||||
|
||||
# ace
|
||||
# there's a 10% chance of an Ace on a par 3
|
||||
if CourseInfo[self.HOLE_NUM].par == 3 and odds(10) and self.STROKE_NUM == 1:
|
||||
if CourseInfo[self.hole_num].par == 3 and odds(10) and self.stroke_num == 1:
|
||||
flags |= ace
|
||||
|
||||
# distance:
|
||||
@@ -659,29 +659,29 @@ class Golf:
|
||||
# If handicap is > 15, there's a 25% chance of reaching club average,
|
||||
# and 75% chance of falling short
|
||||
# The greater the handicap, the more the ball falls short
|
||||
# If poor distance is a known playerDifficulty, then reduce distance by 10%
|
||||
# If poor distance is a known player_difficulty, then reduce distance by 10%
|
||||
|
||||
distance: float
|
||||
rnd = random.randint(1, 101)
|
||||
|
||||
if self.handicap < 15:
|
||||
if rnd <= 25:
|
||||
distance = clubAmt - (clubAmt * (self.handicap / 100.0))
|
||||
distance = club_amt - (club_amt * (self.handicap / 100.0))
|
||||
elif rnd > 25 and rnd <= 75:
|
||||
distance = clubAmt
|
||||
distance = club_amt
|
||||
else:
|
||||
distance = clubAmt + (clubAmt * 0.10)
|
||||
distance = club_amt + (club_amt * 0.10)
|
||||
else:
|
||||
if rnd <= 75:
|
||||
distance = clubAmt - (clubAmt * (self.handicap / 100.0))
|
||||
distance = club_amt - (club_amt * (self.handicap / 100.0))
|
||||
else:
|
||||
distance = clubAmt
|
||||
distance = club_amt
|
||||
|
||||
if self.player_difficulty == 3 and odds(80): # poor distance
|
||||
distance = distance * 0.80
|
||||
|
||||
if (flags & luck) == luck:
|
||||
distance = clubAmt
|
||||
distance = club_amt
|
||||
|
||||
# angle
|
||||
# For all strokes, there's a possible "drift" of 4 degrees
|
||||
@@ -695,43 +695,45 @@ class Golf:
|
||||
if (flags & luck) == luck:
|
||||
angle = 0
|
||||
|
||||
plot = self.plot_ball(self.BALL, distance, angle)
|
||||
plot = self.plot_ball(self.ball, distance, angle)
|
||||
# calculate a new location
|
||||
if (flags & luck) == luck and plot.Y > 0:
|
||||
plot.Y = 2
|
||||
if (flags & luck) == luck and plot.y > 0:
|
||||
plot.y = 2
|
||||
|
||||
flags = self.find_ball(
|
||||
Ball(plot.X, plot.Y, plot.Offline, GameObjType.BALL), flags
|
||||
Ball(plot.x, plot.y, plot.offline, GameObjType.BALL), flags
|
||||
)
|
||||
|
||||
self.interpret_results(plot, flags)
|
||||
|
||||
def plot_ball(self, ball: Ball, strokeDistance: float, degreesOff: float) -> Plot:
|
||||
cupVector = Point(0, -1)
|
||||
radFromCup = math.atan2(ball.Y, ball.X) - math.atan2(cupVector.Y, cupVector.X)
|
||||
radFromBall = radFromCup - math.pi
|
||||
def plot_ball(self, ball: Ball, stroke_distance: float, degrees_off: float) -> Plot:
|
||||
cup_vector = Point(0, -1)
|
||||
rad_from_cup = math.atan2(ball.Y, ball.X) - math.atan2(
|
||||
cup_vector.y, cup_vector.x
|
||||
)
|
||||
rad_from_ball = rad_from_cup - math.pi
|
||||
|
||||
hypotenuse = strokeDistance
|
||||
adjacent = math.cos(radFromBall + to_radians(degreesOff)) * hypotenuse
|
||||
hypotenuse = stroke_distance
|
||||
adjacent = math.cos(rad_from_ball + to_radians(degrees_off)) * hypotenuse
|
||||
opposite = math.sqrt(math.pow(hypotenuse, 2) - math.pow(adjacent, 2))
|
||||
|
||||
newPos: Point
|
||||
if to_degrees_360(radFromBall + to_radians(degreesOff)) > 180:
|
||||
newPos = Point(int(ball.X - opposite), int(ball.Y - adjacent))
|
||||
new_pos: Point
|
||||
if to_degrees_360(rad_from_ball + to_radians(degrees_off)) > 180:
|
||||
new_pos = Point(int(ball.X - opposite), int(ball.Y - adjacent))
|
||||
else:
|
||||
newPos = Point(int(ball.X + opposite), int(ball.Y - adjacent))
|
||||
new_pos = Point(int(ball.X + opposite), int(ball.Y - adjacent))
|
||||
|
||||
return Plot(newPos.X, newPos.Y, int(opposite))
|
||||
return Plot(new_pos.x, new_pos.y, int(opposite))
|
||||
|
||||
def interpret_results(self, plot: Plot, flags: int) -> None:
|
||||
cupDistance: int = int(
|
||||
cup_distance: int = int(
|
||||
get_distance(
|
||||
Point(plot.X, plot.Y),
|
||||
Point(plot.x, plot.y),
|
||||
Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
|
||||
)
|
||||
)
|
||||
travelDistance: int = int(
|
||||
get_distance(Point(plot.X, plot.Y), Point(self.BALL.X, self.BALL.Y))
|
||||
travel_distance: int = int(
|
||||
get_distance(Point(plot.x, plot.y), Point(self.ball.X, self.ball.Y))
|
||||
)
|
||||
|
||||
print(" ")
|
||||
@@ -744,7 +746,7 @@ class Golf:
|
||||
|
||||
if (flags & in_trees) == in_trees:
|
||||
print("Your ball is lost in the trees. Take a penalty stroke.")
|
||||
self.score_card_record_stroke(self.BALL)
|
||||
self.score_card_record_stroke(self.ball)
|
||||
self.tee_up()
|
||||
return
|
||||
|
||||
@@ -754,19 +756,19 @@ class Golf:
|
||||
else:
|
||||
msg = "Your ball is lost in the water."
|
||||
print(msg + " Take a penalty stroke.")
|
||||
self.score_card_record_stroke(self.BALL)
|
||||
self.score_card_record_stroke(self.ball)
|
||||
self.tee_up()
|
||||
return
|
||||
|
||||
if (flags & out_of_bounds) == out_of_bounds:
|
||||
print("Out of bounds. Take a penalty stroke.")
|
||||
self.score_card_record_stroke(self.BALL)
|
||||
self.score_card_record_stroke(self.ball)
|
||||
self.tee_up()
|
||||
return
|
||||
|
||||
if (flags & dub) == dub:
|
||||
print("You dubbed it.")
|
||||
self.score_card_record_stroke(self.BALL)
|
||||
self.score_card_record_stroke(self.ball)
|
||||
self.tee_up()
|
||||
return
|
||||
|
||||
@@ -776,7 +778,7 @@ class Golf:
|
||||
else:
|
||||
msg = "It's in!"
|
||||
print(msg)
|
||||
self.score_card_record_stroke(Ball(plot.X, plot.Y, 0, GameObjType.BALL))
|
||||
self.score_card_record_stroke(Ball(plot.x, plot.y, 0, GameObjType.BALL))
|
||||
self.report_current_score()
|
||||
return
|
||||
|
||||
@@ -785,22 +787,22 @@ class Golf:
|
||||
bad = "badly"
|
||||
else:
|
||||
bad = ""
|
||||
print(f"You sliced{bad}: {plot.Offline} yards offline.")
|
||||
print(f"You sliced{bad}: {plot.offline} yards offline.")
|
||||
|
||||
if ((flags & hook) == hook) and not ((flags & on_green) == on_green):
|
||||
if (flags & out_of_bounds) == out_of_bounds:
|
||||
bad = "badly"
|
||||
else:
|
||||
bad = ""
|
||||
print(f"You hooked{bad}: {plot.Offline} yards offline.")
|
||||
print(f"You hooked{bad}: {plot.offline} yards offline.")
|
||||
|
||||
if self.STROKE_NUM > 1:
|
||||
prevBall = self.score_card_get_previous_stroke()
|
||||
if self.stroke_num > 1:
|
||||
prev_ball = self.score_card_get_previous_stroke()
|
||||
d1 = get_distance(
|
||||
Point(prevBall.X, prevBall.Y),
|
||||
Point(prev_ball.X, prev_ball.Y),
|
||||
Point(self.hole_geometry.cup.X, self.hole_geometry.cup.Y),
|
||||
)
|
||||
d2 = cupDistance
|
||||
d2 = cup_distance
|
||||
if d2 > d1:
|
||||
print("Too much club.")
|
||||
|
||||
@@ -811,55 +813,55 @@ class Golf:
|
||||
print("You're in a sand trap.")
|
||||
|
||||
if (flags & on_green) == on_green:
|
||||
if cupDistance < 4:
|
||||
pd = str(cupDistance * 3) + " feet"
|
||||
if cup_distance < 4:
|
||||
pd = str(cup_distance * 3) + " feet"
|
||||
else:
|
||||
pd = f"{cupDistance} yards"
|
||||
pd = f"{cup_distance} yards"
|
||||
print(f"You're on the green. It's {pd} from the pin.")
|
||||
|
||||
if ((flags & on_fairway) == on_fairway) or ((flags & in_rough) == in_rough):
|
||||
print(
|
||||
f"Shot went {travelDistance} yards. "
|
||||
f"It's {cupDistance} yards from the cup."
|
||||
f"Shot went {travel_distance} yards. "
|
||||
f"It's {cup_distance} yards from the cup."
|
||||
)
|
||||
|
||||
self.score_card_record_stroke(Ball(plot.X, plot.Y, 0, GameObjType.BALL))
|
||||
self.score_card_record_stroke(Ball(plot.x, plot.y, 0, GameObjType.BALL))
|
||||
|
||||
self.BALL = Ball(plot.X, plot.Y, 0, GameObjType.BALL)
|
||||
self.ball = Ball(plot.x, plot.y, 0, GameObjType.BALL)
|
||||
|
||||
self.tee_up()
|
||||
|
||||
def report_current_score(self) -> None:
|
||||
par = CourseInfo[self.HOLE_NUM].par
|
||||
if len(self.score_card[self.HOLE_NUM]) == par + 1:
|
||||
par = CourseInfo[self.hole_num].par
|
||||
if len(self.score_card[self.hole_num]) == par + 1:
|
||||
print("A bogey. One above par.")
|
||||
if len(self.score_card[self.HOLE_NUM]) == par:
|
||||
if len(self.score_card[self.hole_num]) == par:
|
||||
print("Par. Nice.")
|
||||
if len(self.score_card[self.HOLE_NUM]) == (par - 1):
|
||||
if len(self.score_card[self.hole_num]) == (par - 1):
|
||||
print("A birdie! One below par.")
|
||||
if len(self.score_card[self.HOLE_NUM]) == (par - 2):
|
||||
if len(self.score_card[self.hole_num]) == (par - 2):
|
||||
print("An Eagle! Two below par.")
|
||||
if len(self.score_card[self.HOLE_NUM]) == (par - 3):
|
||||
if len(self.score_card[self.hole_num]) == (par - 3):
|
||||
print("Double Eagle! Unbelievable.")
|
||||
|
||||
totalPar: int = 0
|
||||
for i in range(1, self.HOLE_NUM + 1):
|
||||
totalPar += CourseInfo[i].par
|
||||
total_par: int = 0
|
||||
for i in range(1, self.hole_num + 1):
|
||||
total_par += CourseInfo[i].par
|
||||
|
||||
print(" ")
|
||||
print("-----------------------------------------------------")
|
||||
if self.HOLE_NUM > 1:
|
||||
if self.hole_num > 1:
|
||||
hole_str = "holes"
|
||||
else:
|
||||
hole_str = "hole"
|
||||
print(
|
||||
f" Total par for {self.HOLE_NUM} {hole_str} is: {totalPar}. "
|
||||
f" Total par for {self.hole_num} {hole_str} is: {total_par}. "
|
||||
f"Your total is: {self.score_card_get_total()}."
|
||||
)
|
||||
print("-----------------------------------------------------")
|
||||
print(" ")
|
||||
|
||||
if self.HOLE_NUM == 18:
|
||||
if self.hole_num == 18:
|
||||
self.game_over()
|
||||
else:
|
||||
time.sleep(2)
|
||||
@@ -930,10 +932,10 @@ class Golf:
|
||||
|
||||
def score_card_record_stroke(self, ball: Ball) -> None:
|
||||
clone = Ball(ball.X, ball.Y, 0, GameObjType.BALL)
|
||||
self.score_card[self.HOLE_NUM].append(clone)
|
||||
self.score_card[self.hole_num].append(clone)
|
||||
|
||||
def score_card_get_previous_stroke(self) -> Ball:
|
||||
return self.score_card[self.HOLE_NUM][len(self.score_card[self.HOLE_NUM]) - 1]
|
||||
return self.score_card[self.hole_num][len(self.score_card[self.hole_num]) - 1]
|
||||
|
||||
def score_card_get_total(self) -> int:
|
||||
total: int = 0
|
||||
|
||||
@@ -62,10 +62,10 @@ def initialize_board(n: int) -> List[List[int]]:
|
||||
# Initialize the board
|
||||
board = []
|
||||
for _x in range(n):
|
||||
subA = []
|
||||
sub_a = []
|
||||
for _y in range(n):
|
||||
subA.append(0)
|
||||
board.append(subA)
|
||||
sub_a.append(0)
|
||||
board.append(sub_a)
|
||||
return board
|
||||
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ def play_game() -> None:
|
||||
print("GOOD JOB !!!!!")
|
||||
|
||||
if BELLS_ON_SUCCESS:
|
||||
bellStr = chr(7) * 15
|
||||
print(bellStr)
|
||||
bell_str = chr(7) * 15
|
||||
print(bell_str)
|
||||
|
||||
print()
|
||||
print("LET'S PLAY AGAIN.....")
|
||||
|
||||
@@ -6,18 +6,17 @@ A children's literature quiz
|
||||
Ported by Dave LeCompte
|
||||
"""
|
||||
|
||||
from typing import List, NamedTuple
|
||||
|
||||
PAGE_WIDTH = 64
|
||||
|
||||
|
||||
class Question:
|
||||
def __init__(
|
||||
self, question, answer_list, correct_number, incorrect_message, correct_message
|
||||
):
|
||||
self.question = question
|
||||
self.answer_list = answer_list
|
||||
self.correct_number = correct_number
|
||||
self.incorrect_message = incorrect_message
|
||||
self.correct_message = correct_message
|
||||
class Question(NamedTuple):
|
||||
question: str
|
||||
answer_list: List[str]
|
||||
correct_number: int
|
||||
incorrect_message: str
|
||||
correct_message: str
|
||||
|
||||
def ask(self) -> bool:
|
||||
print(self.question)
|
||||
@@ -69,7 +68,6 @@ questions = [
|
||||
|
||||
def print_centered(msg: str) -> None:
|
||||
spaces = " " * ((64 - len(msg)) // 2)
|
||||
|
||||
print(spaces + msg)
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Ported by Dave LeCompte
|
||||
"""
|
||||
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
PAGE_WIDTH = 64
|
||||
@@ -122,23 +123,15 @@ class SimulationClock:
|
||||
self.time_until_next_prompt -= delta_t
|
||||
|
||||
|
||||
@dataclass
|
||||
class Capsule:
|
||||
def __init__(
|
||||
self,
|
||||
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: float = 0
|
||||
altitude: float = 120 # in miles above the surface
|
||||
velocity: float = 1 # downward
|
||||
m: float = 33000 # mass_with_fuel
|
||||
n: float = 16500 # mass_without_fuel
|
||||
g: float = 1e-3
|
||||
z: float = 1.8
|
||||
fuel_per_second: float = 0
|
||||
|
||||
def remaining_fuel(self) -> float:
|
||||
return self.m - self.n
|
||||
@@ -151,8 +144,8 @@ class Capsule:
|
||||
) -> 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
|
||||
self.altitude = new_state.altitude
|
||||
self.velocity = new_state.velocity
|
||||
|
||||
def fuel_time_remaining(self) -> float:
|
||||
# extrapolates out how many seconds we have at the current fuel burn rate
|
||||
@@ -166,16 +159,16 @@ class Capsule:
|
||||
|
||||
# new velocity
|
||||
new_velocity = (
|
||||
self.v
|
||||
self.velocity
|
||||
+ self.g * delta_t
|
||||
+ self.z * (-q - q**2 / 2 - q**3 / 3 - q**4 / 4 - q**5 / 5)
|
||||
)
|
||||
|
||||
# new altitude
|
||||
new_altitude = (
|
||||
self.a
|
||||
self.altitude
|
||||
- self.g * delta_t**2 / 2
|
||||
- self.v * delta_t
|
||||
- self.velocity * delta_t
|
||||
+ self.z
|
||||
* delta_t
|
||||
* (q / 2 + q**2 / 6 + q**3 / 12 + q**4 / 20 + q**5 / 30)
|
||||
@@ -185,9 +178,9 @@ class Capsule:
|
||||
|
||||
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))
|
||||
velocity = int(3600 * self.v)
|
||||
miles = int(self.altitude)
|
||||
feet = int(5280 * (self.altitude - miles))
|
||||
velocity = int(3600 * self.velocity)
|
||||
fuel = int(self.remaining_fuel())
|
||||
burn_rate = " ? "
|
||||
|
||||
@@ -203,7 +196,7 @@ class Capsule:
|
||||
|
||||
|
||||
def show_landing(sim_clock: SimulationClock, capsule: Capsule) -> None:
|
||||
w = 3600 * capsule.v
|
||||
w = 3600 * capsule.velocity
|
||||
print(
|
||||
f"ON MOON AT {sim_clock.elapsed_time:.2f} SECONDS - IMPACT VELOCITY {w:.2f} MPH"
|
||||
)
|
||||
@@ -223,9 +216,10 @@ def show_landing(sim_clock: SimulationClock, capsule: Capsule) -> None:
|
||||
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.velocity
|
||||
+ math.sqrt(capsule.velocity**2 + 2 * capsule.altitude * capsule.g)
|
||||
) / capsule.g
|
||||
capsule.v += capsule.g * delta_t
|
||||
capsule.velocity += capsule.g * delta_t
|
||||
sim_clock.advance(delta_t)
|
||||
show_landing(sim_clock, capsule)
|
||||
|
||||
@@ -243,15 +237,15 @@ def process_final_tick(
|
||||
return
|
||||
# line 35
|
||||
average_vel = (
|
||||
capsule.v
|
||||
capsule.velocity
|
||||
+ math.sqrt(
|
||||
capsule.v**2
|
||||
capsule.velocity**2
|
||||
+ 2
|
||||
* capsule.a
|
||||
* capsule.altitude
|
||||
* (capsule.g - capsule.z * capsule.fuel_per_second / capsule.m)
|
||||
)
|
||||
) / 2
|
||||
delta_t = capsule.a / average_vel
|
||||
delta_t = capsule.altitude / average_vel
|
||||
new_state = capsule.predict_motion(delta_t)
|
||||
capsule.update_state(sim_clock, delta_t, new_state)
|
||||
|
||||
@@ -269,11 +263,11 @@ def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
|
||||
w = (1 - capsule.m * capsule.g / (capsule.z * capsule.fuel_per_second)) / 2
|
||||
delta_t = (
|
||||
capsule.m
|
||||
* capsule.v
|
||||
* capsule.velocity
|
||||
/ (
|
||||
capsule.z
|
||||
* capsule.fuel_per_second
|
||||
* math.sqrt(w**2 + capsule.v / capsule.z)
|
||||
* math.sqrt(w**2 + capsule.velocity / capsule.z)
|
||||
)
|
||||
) + 0.05
|
||||
|
||||
@@ -285,7 +279,7 @@ def handle_flyaway(sim_clock: SimulationClock, capsule: Capsule) -> bool:
|
||||
|
||||
capsule.update_state(sim_clock, delta_t, new_state)
|
||||
|
||||
if (new_state.velocity > 0) or (capsule.v <= 0):
|
||||
if (new_state.velocity > 0) or (capsule.velocity <= 0):
|
||||
# return to normal sim
|
||||
return False
|
||||
|
||||
@@ -329,7 +323,7 @@ def run_simulation() -> None:
|
||||
process_final_tick(delta_t, sim_clock, capsule)
|
||||
return
|
||||
|
||||
if capsule.v > 0 and new_state.velocity < 0:
|
||||
if capsule.velocity > 0 and new_state.velocity < 0:
|
||||
# moving away from the moon
|
||||
|
||||
landed = handle_flyaway(sim_clock, capsule)
|
||||
|
||||
@@ -75,8 +75,8 @@ def query_bets() -> Tuple[List[int], List[int]]:
|
||||
for i in range(bet_count):
|
||||
while bet_ids[i] == -1:
|
||||
try:
|
||||
inString = input("NUMBER " + str(i + 1) + "? ").split(",")
|
||||
id_, val = int(inString[0]), int(inString[1])
|
||||
in_string = input("NUMBER " + str(i + 1) + "? ").split(",")
|
||||
id_, val = int(in_string[0]), int(in_string[1])
|
||||
|
||||
# check other bet_IDs
|
||||
for j in range(i):
|
||||
|
||||
@@ -356,7 +356,7 @@ class Qubit:
|
||||
break
|
||||
print("Incorrect answer. Please type 'yes' or 'no'.")
|
||||
|
||||
skipHuman = s[0] in "nN"
|
||||
skip_human = s[0] in "nN"
|
||||
|
||||
move_text = [
|
||||
"Machine moves to",
|
||||
@@ -368,9 +368,9 @@ class Qubit:
|
||||
]
|
||||
|
||||
while True:
|
||||
if not skipHuman and not self.human_move(board):
|
||||
if not skip_human and not self.human_move(board):
|
||||
break
|
||||
skipHuman = False
|
||||
skip_human = False
|
||||
|
||||
m = board.machine_move()
|
||||
assert m is not None
|
||||
|
||||
Reference in New Issue
Block a user