mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
MAINT: Add type annotations / use functions
This commit is contained in:
4
01_Acey_Ducey/python/acey_ducey.py
Normal file → Executable file
4
01_Acey_Ducey/python/acey_ducey.py
Normal file → Executable file
@@ -23,7 +23,7 @@ cards = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def play_game():
|
def play_game() -> None:
|
||||||
"""Play the game"""
|
"""Play the game"""
|
||||||
cash = 100
|
cash = 100
|
||||||
while cash > 0:
|
while cash > 0:
|
||||||
@@ -63,7 +63,7 @@ def play_game():
|
|||||||
print("Sorry, friend, but you blew your wad")
|
print("Sorry, friend, but you blew your wad")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
"""Main"""
|
"""Main"""
|
||||||
keep_playing = True
|
keep_playing = True
|
||||||
|
|
||||||
|
|||||||
@@ -11,41 +11,43 @@
|
|||||||
#
|
#
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
class Card:
|
class Card:
|
||||||
def __init__(self, suit, rank):
|
def __init__(self, suit: str, rank: int):
|
||||||
self.suit = suit
|
self.suit = suit
|
||||||
self.rank = rank
|
self.rank = rank
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
r = self.rank
|
r = str(self.rank)
|
||||||
if r == 11:
|
if r == "11":
|
||||||
r = "J"
|
r = "J"
|
||||||
elif r == 12:
|
elif r == "12":
|
||||||
r = "Q"
|
r = "Q"
|
||||||
elif r == 13:
|
elif r == "13":
|
||||||
r = "K"
|
r = "K"
|
||||||
elif r == 14:
|
elif r == "14":
|
||||||
r = "A"
|
r = "A"
|
||||||
return f"{r}{self.suit}"
|
return f"{r}{self.suit}"
|
||||||
|
|
||||||
|
|
||||||
class Deck:
|
class Deck:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cards = []
|
self.cards: List[Card] = []
|
||||||
self.build()
|
self.build()
|
||||||
|
|
||||||
def build(self):
|
def build(self) -> None:
|
||||||
for suit in ["\u2665", "\u2666", "\u2663", "\u2660"]:
|
for suit in ["\u2665", "\u2666", "\u2663", "\u2660"]:
|
||||||
for rank in range(2, 15):
|
for rank in range(2, 15):
|
||||||
self.cards.append(Card(suit, rank))
|
self.cards.append(Card(suit, rank))
|
||||||
|
|
||||||
def shuffle(self):
|
def shuffle(self) -> None:
|
||||||
import random
|
import random
|
||||||
|
|
||||||
random.shuffle(self.cards)
|
random.shuffle(self.cards)
|
||||||
|
|
||||||
def deal(self):
|
def deal(self) -> Card:
|
||||||
return self.cards.pop()
|
return self.cards.pop()
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +60,7 @@ class Game:
|
|||||||
self.money = 100
|
self.money = 100
|
||||||
self.not_done = True
|
self.not_done = True
|
||||||
|
|
||||||
def play(self):
|
def play(self) -> None:
|
||||||
while self.not_done:
|
while self.not_done:
|
||||||
while self.money > 0:
|
while self.money > 0:
|
||||||
card_a = self.card_a
|
card_a = self.card_a
|
||||||
@@ -90,9 +92,9 @@ class Game:
|
|||||||
print("Chicken!")
|
print("Chicken!")
|
||||||
print(f"Your deal should have been: {player_card}")
|
print(f"Your deal should have been: {player_card}")
|
||||||
if card_a.rank < player_card.rank < card_b.rank:
|
if card_a.rank < player_card.rank < card_b.rank:
|
||||||
print(f"You could have won!")
|
print("You could have won!")
|
||||||
else:
|
else:
|
||||||
print(f"You would lose, so it was wise of you to chicken out!")
|
print("You would lose, so it was wise of you to chicken out!")
|
||||||
|
|
||||||
self.not_done = False
|
self.not_done = False
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import random
|
|||||||
# to start with more or less than $100."
|
# to start with more or less than $100."
|
||||||
DEFAULT_BANKROLL = 100
|
DEFAULT_BANKROLL = 100
|
||||||
|
|
||||||
# functions
|
|
||||||
def deal_card_num():
|
def deal_card_num() -> int:
|
||||||
"""Get card number"""
|
"""Get card number"""
|
||||||
return random.randint(0, 12)
|
return random.randint(0, 12)
|
||||||
|
|
||||||
|
|
||||||
def get_card_name(number):
|
def get_card_name(number: int) -> str:
|
||||||
"""Get card name"""
|
"""Get card name"""
|
||||||
card_names = (
|
card_names = (
|
||||||
" 2",
|
" 2",
|
||||||
@@ -56,7 +56,7 @@ def get_card_name(number):
|
|||||||
return card_names[number]
|
return card_names[number]
|
||||||
|
|
||||||
|
|
||||||
def display_bankroll(bank_roll):
|
def display_bankroll(bank_roll: int) -> None:
|
||||||
"""Print current bankroll"""
|
"""Print current bankroll"""
|
||||||
if BANK_ROLL > 0:
|
if BANK_ROLL > 0:
|
||||||
print("You now have %s dollars\n" % bank_roll)
|
print("You now have %s dollars\n" % bank_roll)
|
||||||
@@ -103,9 +103,9 @@ while KEEP_PLAYING:
|
|||||||
# Get and handle player bet choice
|
# Get and handle player bet choice
|
||||||
BET_IS_VALID = False
|
BET_IS_VALID = False
|
||||||
while not BET_IS_VALID:
|
while not BET_IS_VALID:
|
||||||
curr_bet = input("What is your bet? ")
|
curr_bet_str = input("What is your bet? ")
|
||||||
try:
|
try:
|
||||||
curr_bet = int(curr_bet)
|
curr_bet = int(curr_bet_str)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# Bad input? Just loop back up and ask again...
|
# Bad input? Just loop back up and ask again...
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,118 +1,147 @@
|
|||||||
import random
|
import random
|
||||||
|
from typing import List, NamedTuple, Tuple
|
||||||
|
|
||||||
# Python translation by Frank Palazzolo - 2/2021
|
# Python translation by Frank Palazzolo - 2/2021
|
||||||
|
|
||||||
print(" " * 28 + "AMAZING PROGRAM")
|
|
||||||
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
|
|
||||||
print()
|
|
||||||
print()
|
|
||||||
print()
|
|
||||||
|
|
||||||
while True:
|
class Maze(NamedTuple):
|
||||||
width, length = input("What are your width and length?").split(",")
|
used: List[List[int]]
|
||||||
width = int(width)
|
walls: List[List[int]]
|
||||||
length = int(length)
|
enter_col: int
|
||||||
if width != 1 and length != 1:
|
width: int
|
||||||
break
|
length: int
|
||||||
print("Meaningless dimensions. Try again.")
|
|
||||||
|
|
||||||
# Build two 2D arrays
|
|
||||||
#
|
|
||||||
# used:
|
|
||||||
# Initially set to zero, unprocessed cells
|
|
||||||
# Filled in with consecutive non-zero numbers as cells are processed
|
|
||||||
#
|
|
||||||
# walls:
|
|
||||||
# Initially set to zero, (all paths blocked)
|
|
||||||
# Remains 0 if there is no exit down or right
|
|
||||||
# Set to 1 if there is an exit down
|
|
||||||
# Set to 2 if there is an exit right
|
|
||||||
# Set to 3 if there are exits down and right
|
|
||||||
|
|
||||||
used = []
|
def main() -> None:
|
||||||
walls = []
|
welcome_header()
|
||||||
for i in range(length):
|
width, length = get_maze_dimensions()
|
||||||
used.append([0] * width)
|
maze = build_maze(width, length)
|
||||||
walls.append([0] * width)
|
print_maze(maze)
|
||||||
|
|
||||||
# Use direction variables with nice names
|
|
||||||
GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN = [0, 1, 2, 3]
|
|
||||||
# Give Exit directions nice names
|
|
||||||
EXIT_DOWN = 1
|
|
||||||
EXIT_RIGHT = 2
|
|
||||||
|
|
||||||
# Pick a random entrance, mark as used
|
def welcome_header() -> None:
|
||||||
enter_col = random.randint(0, width - 1)
|
print(" " * 28 + "AMAZING PROGRAM")
|
||||||
row, col = 0, enter_col
|
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
|
||||||
count = 1
|
|
||||||
used[row][col] = count
|
|
||||||
count = count + 1
|
|
||||||
|
|
||||||
while count != width * length + 1:
|
|
||||||
# remove possible directions that are blocked or
|
|
||||||
# hit cells that we have already processed
|
|
||||||
possible_dirs = [GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN]
|
|
||||||
if col == 0 or used[row][col - 1] != 0:
|
|
||||||
possible_dirs.remove(GO_LEFT)
|
|
||||||
if row == 0 or used[row - 1][col] != 0:
|
|
||||||
possible_dirs.remove(GO_UP)
|
|
||||||
if col == width - 1 or used[row][col + 1] != 0:
|
|
||||||
possible_dirs.remove(GO_RIGHT)
|
|
||||||
if row == length - 1 or used[row + 1][col] != 0:
|
|
||||||
possible_dirs.remove(GO_DOWN)
|
|
||||||
|
|
||||||
# If we can move in a direction, move and make opening
|
|
||||||
if len(possible_dirs) != 0:
|
|
||||||
direction = random.choice(possible_dirs)
|
|
||||||
if direction == GO_LEFT:
|
|
||||||
col = col - 1
|
|
||||||
walls[row][col] = EXIT_RIGHT
|
|
||||||
elif direction == GO_UP:
|
|
||||||
row = row - 1
|
|
||||||
walls[row][col] = EXIT_DOWN
|
|
||||||
elif direction == GO_RIGHT:
|
|
||||||
walls[row][col] = walls[row][col] + EXIT_RIGHT
|
|
||||||
col = col + 1
|
|
||||||
elif direction == GO_DOWN:
|
|
||||||
walls[row][col] = walls[row][col] + EXIT_DOWN
|
|
||||||
row = row + 1
|
|
||||||
used[row][col] = count
|
|
||||||
count = count + 1
|
|
||||||
# otherwise, move to the next used cell, and try again
|
|
||||||
else:
|
|
||||||
while True:
|
|
||||||
if col != width - 1:
|
|
||||||
col = col + 1
|
|
||||||
elif row != length - 1:
|
|
||||||
row, col = row + 1, 0
|
|
||||||
else:
|
|
||||||
row, col = 0, 0
|
|
||||||
if used[row][col] != 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Add a random exit
|
|
||||||
col = random.randint(0, width - 1)
|
|
||||||
row = length - 1
|
|
||||||
walls[row][col] = walls[row][col] + 1
|
|
||||||
|
|
||||||
# Print the maze
|
|
||||||
for col in range(width):
|
|
||||||
if col == enter_col:
|
|
||||||
print(". ", end="")
|
|
||||||
else:
|
|
||||||
print(".--", end="")
|
|
||||||
print(".")
|
|
||||||
for row in range(length):
|
|
||||||
print("I", end="")
|
|
||||||
for col in range(width):
|
|
||||||
if walls[row][col] < 2:
|
|
||||||
print(" I", end="")
|
|
||||||
else:
|
|
||||||
print(" ", end="")
|
|
||||||
print()
|
print()
|
||||||
for col in range(width):
|
print()
|
||||||
if walls[row][col] == 0 or walls[row][col] == 2:
|
print()
|
||||||
print(":--", end="")
|
|
||||||
|
|
||||||
|
def build_maze(width: int, length: int) -> Maze:
|
||||||
|
# Build two 2D arrays
|
||||||
|
#
|
||||||
|
# used:
|
||||||
|
# Initially set to zero, unprocessed cells
|
||||||
|
# Filled in with consecutive non-zero numbers as cells are processed
|
||||||
|
#
|
||||||
|
# walls:
|
||||||
|
# Initially set to zero, (all paths blocked)
|
||||||
|
# Remains 0 if there is no exit down or right
|
||||||
|
# Set to 1 if there is an exit down
|
||||||
|
# Set to 2 if there is an exit right
|
||||||
|
# Set to 3 if there are exits down and right
|
||||||
|
|
||||||
|
used = []
|
||||||
|
walls = []
|
||||||
|
for _ in range(length):
|
||||||
|
used.append([0] * width)
|
||||||
|
walls.append([0] * width)
|
||||||
|
|
||||||
|
# Use direction variables with nice names
|
||||||
|
GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN = [0, 1, 2, 3]
|
||||||
|
# Give Exit directions nice names
|
||||||
|
EXIT_DOWN = 1
|
||||||
|
EXIT_RIGHT = 2
|
||||||
|
|
||||||
|
# Pick a random entrance, mark as used
|
||||||
|
enter_col = random.randint(0, width - 1)
|
||||||
|
row, col = 0, enter_col
|
||||||
|
count = 1
|
||||||
|
used[row][col] = count
|
||||||
|
count = count + 1
|
||||||
|
|
||||||
|
while count != width * length + 1:
|
||||||
|
# remove possible directions that are blocked or
|
||||||
|
# hit cells that we have already processed
|
||||||
|
possible_dirs = [GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN]
|
||||||
|
if col == 0 or used[row][col - 1] != 0:
|
||||||
|
possible_dirs.remove(GO_LEFT)
|
||||||
|
if row == 0 or used[row - 1][col] != 0:
|
||||||
|
possible_dirs.remove(GO_UP)
|
||||||
|
if col == width - 1 or used[row][col + 1] != 0:
|
||||||
|
possible_dirs.remove(GO_RIGHT)
|
||||||
|
if row == length - 1 or used[row + 1][col] != 0:
|
||||||
|
possible_dirs.remove(GO_DOWN)
|
||||||
|
|
||||||
|
# If we can move in a direction, move and make opening
|
||||||
|
if len(possible_dirs) != 0:
|
||||||
|
direction = random.choice(possible_dirs)
|
||||||
|
if direction == GO_LEFT:
|
||||||
|
col = col - 1
|
||||||
|
walls[row][col] = EXIT_RIGHT
|
||||||
|
elif direction == GO_UP:
|
||||||
|
row = row - 1
|
||||||
|
walls[row][col] = EXIT_DOWN
|
||||||
|
elif direction == GO_RIGHT:
|
||||||
|
walls[row][col] = walls[row][col] + EXIT_RIGHT
|
||||||
|
col = col + 1
|
||||||
|
elif direction == GO_DOWN:
|
||||||
|
walls[row][col] = walls[row][col] + EXIT_DOWN
|
||||||
|
row = row + 1
|
||||||
|
used[row][col] = count
|
||||||
|
count = count + 1
|
||||||
|
# otherwise, move to the next used cell, and try again
|
||||||
else:
|
else:
|
||||||
print(": ", end="")
|
while True:
|
||||||
|
if col != width - 1:
|
||||||
|
col = col + 1
|
||||||
|
elif row != length - 1:
|
||||||
|
row, col = row + 1, 0
|
||||||
|
else:
|
||||||
|
row, col = 0, 0
|
||||||
|
if used[row][col] != 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Add a random exit
|
||||||
|
col = random.randint(0, width - 1)
|
||||||
|
row = length - 1
|
||||||
|
walls[row][col] = walls[row][col] + 1
|
||||||
|
return Maze(used, walls, enter_col, width, length)
|
||||||
|
|
||||||
|
|
||||||
|
def get_maze_dimensions() -> Tuple[int, int]:
|
||||||
|
while True:
|
||||||
|
width_str, length_str = input("What are your width and length?").split(",")
|
||||||
|
width = int(width_str)
|
||||||
|
length = int(length_str)
|
||||||
|
if width > 1 and length > 1:
|
||||||
|
break
|
||||||
|
print("Meaningless dimensions. Try again.")
|
||||||
|
return width, length
|
||||||
|
|
||||||
|
|
||||||
|
def print_maze(maze: Maze) -> None:
|
||||||
|
for col in range(maze.width):
|
||||||
|
if col == maze.enter_col:
|
||||||
|
print(". ", end="")
|
||||||
|
else:
|
||||||
|
print(".--", end="")
|
||||||
print(".")
|
print(".")
|
||||||
|
for row in range(maze.length):
|
||||||
|
print("I", end="")
|
||||||
|
for col in range(maze.width):
|
||||||
|
if maze.walls[row][col] < 2:
|
||||||
|
print(" I", end="")
|
||||||
|
else:
|
||||||
|
print(" ", end="")
|
||||||
|
print()
|
||||||
|
for col in range(maze.width):
|
||||||
|
if maze.walls[row][col] == 0 or maze.walls[row][col] == 2:
|
||||||
|
print(":--", end="")
|
||||||
|
else:
|
||||||
|
print(": ", end="")
|
||||||
|
print(".")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|||||||
@@ -42,20 +42,26 @@
|
|||||||
#
|
#
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
"""
|
"""
|
||||||
Node of the binary tree of questions.
|
Node of the binary tree of questions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, text, yes_node, no_node):
|
def __init__(
|
||||||
|
self, text: str, yes_node: Optional["Node"], no_node: Optional["Node"]
|
||||||
|
):
|
||||||
# the nodes that are leafs have as text the animal's name, otherwise
|
# the nodes that are leafs have as text the animal's name, otherwise
|
||||||
# a yes/no question
|
# a yes/no question
|
||||||
self.text = text
|
self.text = text
|
||||||
self.yes_node = yes_node
|
self.yes_node = yes_node
|
||||||
self.no_node = no_node
|
self.no_node = no_node
|
||||||
|
|
||||||
def update_node(self, new_question, answer_new_ques, new_animal):
|
def update_node(
|
||||||
|
self, new_question: str, answer_new_ques: str, new_animal: str
|
||||||
|
) -> None:
|
||||||
# update the leaf with a question
|
# update the leaf with a question
|
||||||
old_animal = self.text
|
old_animal = self.text
|
||||||
# we replace the animal with a new question
|
# we replace the animal with a new question
|
||||||
@@ -69,13 +75,13 @@ class Node:
|
|||||||
self.no_node = Node(new_animal, None, None)
|
self.no_node = Node(new_animal, None, None)
|
||||||
|
|
||||||
# the leafs have as children None
|
# the leafs have as children None
|
||||||
def is_leaf(self):
|
def is_leaf(self) -> bool:
|
||||||
return self.yes_node == None and self.no_node == None
|
return self.yes_node is None and self.no_node is None
|
||||||
|
|
||||||
|
|
||||||
def list_known_animals(root_node):
|
def list_known_animals(root_node: Optional[Node]) -> None:
|
||||||
# Traversing the tree by recursion until we reach the leafs
|
# Traversing the tree by recursion until we reach the leafs
|
||||||
if root_node == None:
|
if root_node is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if root_node.is_leaf():
|
if root_node.is_leaf():
|
||||||
@@ -89,91 +95,93 @@ def list_known_animals(root_node):
|
|||||||
list_known_animals(root_node.no_node)
|
list_known_animals(root_node.no_node)
|
||||||
|
|
||||||
|
|
||||||
def parse_input(message, check_list, root_node):
|
def parse_input(message: str, check_list: bool, root_node: Optional[Node]) -> str:
|
||||||
# only accepts yes or no inputs and recognizes list operation
|
"""only accepts yes or no inputs and recognizes list operation"""
|
||||||
correct_input = False
|
token = ""
|
||||||
while not correct_input:
|
while token not in ["y", "n"]:
|
||||||
try:
|
inp = input(message)
|
||||||
inp = input(message)
|
|
||||||
|
|
||||||
if check_list and inp.lower() == "list":
|
if check_list and inp.lower() == "list":
|
||||||
print("Animals I already know are:")
|
print("Animals I already know are:")
|
||||||
list_known_animals(root_node)
|
list_known_animals(root_node)
|
||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
|
if len(inp) > 0:
|
||||||
token = inp[0].lower()
|
token = inp[0].lower()
|
||||||
if token == "y" or token == "n":
|
else:
|
||||||
correct_input = True
|
token = ""
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
|
||||||
def avoid_void_input(message):
|
def avoid_void_input(message: str) -> str:
|
||||||
answer = ""
|
answer = ""
|
||||||
while answer == "":
|
while answer == "":
|
||||||
answer = input(message)
|
answer = input(message)
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
|
|
||||||
def initial_message():
|
def initial_message() -> None:
|
||||||
print(" " * 32 + "Animal")
|
print(" " * 32 + "Animal")
|
||||||
print(" " * 15 + "Creative Computing Morristown, New Jersey\n")
|
print(" " * 15 + "Creative Computing Morristown, New Jersey\n")
|
||||||
print("Play ´Guess the Animal´")
|
print("Play ´Guess the Animal´")
|
||||||
print("Think of an animal and the computer will try to guess it.\n")
|
print("Think of an animal and the computer will try to guess it.\n")
|
||||||
|
|
||||||
|
|
||||||
# Initial tree
|
def main() -> None:
|
||||||
yes_child = Node("Fish", None, None)
|
# Initial tree
|
||||||
no_child = Node("Bird", None, None)
|
yes_child = Node("Fish", None, None)
|
||||||
root = Node("Does it swim?", yes_child, no_child)
|
no_child = Node("Bird", None, None)
|
||||||
|
root = Node("Does it swim?", yes_child, no_child)
|
||||||
# Main loop of game
|
|
||||||
initial_message()
|
|
||||||
keep_playing = parse_input("Are you thinking of an animal? ", True, root) == "y"
|
|
||||||
while keep_playing:
|
|
||||||
keep_asking = True
|
|
||||||
# Start traversing the tree by the root
|
|
||||||
actual_node = root
|
|
||||||
|
|
||||||
while keep_asking:
|
|
||||||
|
|
||||||
if not actual_node.is_leaf():
|
|
||||||
# we have to keep asking i.e. traversing nodes
|
|
||||||
answer = parse_input(actual_node.text, False, None)
|
|
||||||
|
|
||||||
if answer == "y":
|
|
||||||
actual_node = actual_node.yes_node
|
|
||||||
else:
|
|
||||||
actual_node = actual_node.no_node
|
|
||||||
else:
|
|
||||||
# we have reached a possible answer
|
|
||||||
answer = parse_input(f"Is it a {actual_node.text}? ", False, None)
|
|
||||||
if answer == "n":
|
|
||||||
# add the new animal to the tree
|
|
||||||
new_animal = avoid_void_input(
|
|
||||||
"The animal you were thinking of was a ? "
|
|
||||||
)
|
|
||||||
new_question = avoid_void_input(
|
|
||||||
"Please type in a question that would distinguish a {} from a {}: ".format(
|
|
||||||
new_animal, actual_node.text
|
|
||||||
)
|
|
||||||
)
|
|
||||||
answer_new_question = parse_input(
|
|
||||||
f"for a {new_animal} the answer would be: ", False, None
|
|
||||||
)
|
|
||||||
|
|
||||||
actual_node.update_node(
|
|
||||||
new_question + "?", answer_new_question, new_animal
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("Why not try another animal?")
|
|
||||||
|
|
||||||
keep_asking = False
|
|
||||||
|
|
||||||
|
# Main loop of game
|
||||||
|
initial_message()
|
||||||
keep_playing = parse_input("Are you thinking of an animal? ", True, root) == "y"
|
keep_playing = parse_input("Are you thinking of an animal? ", True, root) == "y"
|
||||||
|
while keep_playing:
|
||||||
|
keep_asking = True
|
||||||
|
# Start traversing the tree by the root
|
||||||
|
actual_node: Node = root
|
||||||
|
|
||||||
|
while keep_asking:
|
||||||
|
|
||||||
|
if not actual_node.is_leaf():
|
||||||
|
|
||||||
|
# we have to keep asking i.e. traversing nodes
|
||||||
|
answer = parse_input(actual_node.text, False, None)
|
||||||
|
|
||||||
|
# As this is an inner node, both children are not None
|
||||||
|
if answer == "y":
|
||||||
|
assert actual_node.yes_node is not None
|
||||||
|
actual_node = actual_node.yes_node
|
||||||
|
else:
|
||||||
|
assert actual_node.no_node is not None
|
||||||
|
actual_node = actual_node.no_node
|
||||||
|
else:
|
||||||
|
# we have reached a possible answer
|
||||||
|
answer = parse_input(f"Is it a {actual_node.text}? ", False, None)
|
||||||
|
if answer == "n":
|
||||||
|
# add the new animal to the tree
|
||||||
|
new_animal = avoid_void_input(
|
||||||
|
"The animal you were thinking of was a ? "
|
||||||
|
)
|
||||||
|
new_question = avoid_void_input(
|
||||||
|
"Please type in a question that would distinguish a "
|
||||||
|
f"{new_animal} from a {actual_node.text}: "
|
||||||
|
)
|
||||||
|
answer_new_question = parse_input(
|
||||||
|
f"for a {new_animal} the answer would be: ", False, None
|
||||||
|
)
|
||||||
|
|
||||||
|
actual_node.update_node(
|
||||||
|
new_question + "?", answer_new_question, new_animal
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("Why not try another animal?")
|
||||||
|
|
||||||
|
keep_asking = False
|
||||||
|
|
||||||
|
keep_playing = parse_input("Are you thinking of an animal? ", True, root) == "y"
|
||||||
|
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
@@ -193,3 +201,6 @@ while keep_playing:
|
|||||||
# function (Lines 120 to 130, 135, 158, 160, 168, 173)
|
# function (Lines 120 to 130, 135, 158, 160, 168, 173)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user