diff --git a/01 Acey Ducey/python/aceyducey.py b/01 Acey Ducey/python/aceyducey.py new file mode 100644 index 000000000..c995b836a --- /dev/null +++ b/01 Acey Ducey/python/aceyducey.py @@ -0,0 +1,196 @@ +######################################################## +# +# Acey Ducey +# +# From: BASIC Computer Games (1978) +# Edited by David Ahl +# +# "This is a simulation of the Acey Ducey card game. +# In the game, the dealer (the computer) deals two +# cards face up. You have an option to bet or not to +# bet depending on whether or not you feel the next +# card dealt will have a value between the first two. +# +# "Your initial money is set to $100. The game keeps +# going on until you lose all your money or interrupt +# the program. +# +# "The original BASIC program author was Bill Palmby +# of Prairie View, Illinois." +# +# Python port by Jeff Jetton, 2019 +# +######################################################## + + +import random + +# "You may alter [the following statement] if you want +# to start with more or less than $100." +DEFAULT_BANKROLL = 100 + +# functions +def deal_card_num(): + return random.randint(0, 12) + +def get_card_name(n): + cardNames = (" 2", " 3", " 4", " 5", " 6", \ + " 7", " 8", " 9", " 10", "Jack", \ + "Queen", "King", "Ace") + return(cardNames[n]) + +def display_bankroll(b): + if bankroll > 0: + print("You now have %s dollars\n"%b) + + + +# Display initial title and instructions +print("\n Acey Ducey Card Game") +print("Creative Computing Morristown, New Jersey") +print("\n\n") +print("Acey-Ducey is played in the following manner") +print("The dealer (computer) deals two cards face up") +print("You have an option to bet or not bet depending") +print("on whether or not you feel the card will have") +print("a value between the first two.") +print("If you do not want to bet, input a 0") + + +# Loop for series of multiple games +keep_playing = True +while keep_playing: + + # Initialize bankroll at start of each game + bankroll = DEFAULT_BANKROLL + display_bankroll(bankroll) + + # Loop for a single round. Repeat until out of money. + while bankroll > 0: + + # Deal out dealer cards + print("Here are your next two cards") + dealer1 = deal_card_num() + # If the cards match, we redeal 2nd card until they don't + dealer2 = dealer1 + while dealer1 == dealer2: + dealer2 = deal_card_num() + # Organize the cards in order if they're not already + if (dealer1 >= dealer2): + (dealer1, dealer2) = (dealer2, dealer1) # Ya gotta love Python! + # Show dealer cards to the player + # (use card name rather than internal number) + print(get_card_name(dealer1)) + print(get_card_name(dealer2) + "\n") + + # Get and handle player bet choice + bet_is_valid = False + while not bet_is_valid: + curr_bet = input("What is your bet? ") + try: + curr_bet = int(curr_bet) + except: + # Bad input? Just loop back up and ask again... + pass + else: + if curr_bet == 0: + bet_is_valid = True + print("Chicken!!\n") + elif curr_bet > bankroll: + print("Sorry, my friend but you bet too much") + print("You have only %s dollars to bet\n" % bankroll) + else: + # Deal player card + bet_is_valid = True + player = deal_card_num() + print(get_card_name(player)) + + # Did we win? + if player > dealer1 and player < dealer2: + print("You win!!!") + bankroll += curr_bet + else: + print("Sorry, you lose") + bankroll -= curr_bet + + # Update player on new bankroll level + display_bankroll(bankroll) + + # End of loop for a single round + + print("\n\nSorry, friend but you blew your wad") + player_response = input("Try again (yes or no) ") + if player_response.lower() == "yes": + print() + else: + keep_playing = False + +# End of multiple game loop + +print("OK Hope you had fun\n") + + +######################################################## +# +# Porting notes: +# +# The original BASIC version had a variable named N +# that was initialized to 100 and then never used. +# Maybe it did something in feature that was edited +# out of the final version used in the book? +# +# The original program simply generated random numbers +# for each card. It did not simulate a true card deck, +# where the dealing of a card eliminates it from the +# deck and reduces the chances of the same value +# being drawn. This "infinite deck" logic (or "deal, +# with replacement after") has NOT been changed. +# +# In the interests of historical fidelity, the bug +# in the original BASIC listing that let you input a +# negative bet value has been faithfully reproduced. +# This lets the player lose money when they win and +# earn money when they lose! :-) +# +# +# Ideas for Modifications +# +# Give the user the ability to quit the game, perhaps +# by typing "quit" instead of making a bet. Provide a +# final assement based on how much of the original +# bankroll they have left. +# +# Or have the game run for a set number of rounds or +# until a certain bankroll goal is attained. +# +# Implement an "ante"--a set amount the player has to +# bet each time rather than having the option to lay +# out entirely. +# +# See "porting notes" above about negative bet values. +# How would you fix this? +# +# When the player "chickens out", show them what the +# next card would've been and point out whether they +# made a good or bad decision. +# +# In what situations are the odds of winning high +# enough to justify making a bet? Create a cheat mode +# where the program identifies these situations and +# lets the player know. +# +# Change the card dealing to simulate deals from a +# single deck (or a user-selectable number of decks). +# +# Implement a two-player mode where players take turns +# betting (or both bet on the same dealer cards and +# get their own player card dealt). +# +######################################################## + + + + + + + diff --git a/05 Bagels/python/bagels.py b/05 Bagels/python/bagels.py new file mode 100644 index 000000000..b56a75d02 --- /dev/null +++ b/05 Bagels/python/bagels.py @@ -0,0 +1,201 @@ +###################################################################### +# +# Bagels +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "In this game, the computer picks a 3-digit secret number using +# the digits 0 to 9 and you attempt to guess what it is. You are +# allowed up to twenty guesses. No digit is repeated. After +# each guess the computer will give you clues about your guess +# as follows: +# +# PICO One digit is correct, but in the wrong place +# FERMI One digit is in the correct place +# BAGELS No digit is correct +# +# "You will learn to draw inferences from the clues and, with +# practice, you'll learn to improve your score. There are several +# good strategies for playing Bagels. After you have found a good +# strategy, see if you can improve it. Or try a different strategy +# altogether and see if it is any better. While the program allows +# up to twenty guesses, if you use a good strategy it should not +# take more than eight guesses to get any number. +# +# "The original authors of this program are D. Resek and P. Rowe of +# the Lawrence Hall of Science, Berkeley, California." +# +# +# Python port by Jeff Jetton, 2019 +# +###################################################################### + + +import random + +MAX_GUESSES = 20 + + + +def print_rules(): + print("\nI am thinking of a three-digit number. Try to guess") + print("my number and I will give you clues as follows:") + print(" PICO - One digit correct but in the wrong position") + print(" FERMI - One digit correct and in the right position") + print(" BAGELS - No digits correct") + + + +def pick_number(): + # Note that this returns a list of individual digits + # as separate strings, not a single integer or string + numbers = [i for i in range(10)] + random.shuffle(numbers) + num = numbers[0:3] + num = [str(i) for i in num] + return num + + + +def get_valid_guess(): + valid = False + while not valid: + guess = input(f"Guess # {guesses} ? ") + guess = guess.strip() + # Guess must be three characters + if len(guess) == 3: + # And they should be numbers + if guess.isnumeric(): + # And the numbers must be unique + if len(set(guess)) == 3: + valid = True + else: + print("Oh, I forgot to tell you that " + + "the number I have in mind") + print("has no two digits the same.") + else: + print("What?") + else: + print("Try guessing a three-digit number.") + + return guess + + + +def build_result_string(num, guess): + + result = "" + + # Correct digits in wrong place + for i in range(2): + if num[i] == guess[i+1]: + result += "PICO " + if num[i+1] == guess[i]: + result += "PICO " + if num[0] == guess[2]: + result += "PICO " + if num[2] == guess[0]: + result += "PICO " + + # Correct digits in right place + for i in range(3): + if num[i] == guess[i]: + result += "FERMI " + + # Nothing right? + if result == "": + result = "BAGELS" + + return result + + + + +###################################################################### + + +# Intro text +print("\n Bagels") +print("Creative Computing Morristown, New Jersey") +print("\n\n") + +# Anything other than N* will show the rules +response = input("Would you like the rules (Yes or No)? ") +if len(response) > 0: + if response.upper()[0] != 'N': + print_rules() +else: + print_rules() + +games_won = 0 +still_running = True +while still_running: + + # New round + num = pick_number() + num_str = ''.join(num) + guesses = 1 + + print("\nO.K. I have a number in mind.") + guessing = True + while guessing: + + guess = get_valid_guess() + + if guess == num_str: + print("You got it!!!\n") + games_won += 1 + guessing = False + else: + print(build_result_string(num, guess)) + guesses += 1 + if guesses > MAX_GUESSES: + print("Oh well") + print(f"That's {MAX_GUESSES} guesses. " + + "My number was " + num_str) + guessing = False + + + valid_response = False + while not valid_response: + response = input("Play again (Yes or No)? ") + if len(response) > 0: + valid_response = True + if response.upper()[0] != "Y": + still_running = False + + +if games_won > 0: + print(f"\nA {games_won} point Bagels buff!!") + +print("Hope you had fun. Bye.\n") + + + +###################################################################### +# +# Porting Notes +# +# The original program did an unusually good job of validating the +# player's input (compared to many of the other programs in the +# book). Those checks and responses have been exactly reproduced. +# +# +# Ideas for Modifications +# +# It should probably mention that there's a maximum of MAX_NUM +# guesses in the instructions somewhere, shouldn't it? +# +# Could this program be written to use anywhere from, say 2 to 6 +# digits in the number to guess? How would this change the routine +# that creates the "result" string? +# +###################################################################### + + + + + + + diff --git a/20 Buzzword/python/buzzword.py b/20 Buzzword/python/buzzword.py new file mode 100644 index 000000000..4de33d297 --- /dev/null +++ b/20 Buzzword/python/buzzword.py @@ -0,0 +1,113 @@ +###################################################################### +# +# Buzzword Generator +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "This program is an invaluable aid for preparing speeches and +# briefings about education technology. This buzzword generator +# provides sets of three highly-acceptable words to work into your +# material. Your audience will never know that the phrases don't +# really mean much of anything because they sound so great! Full +# instructions for running are given in the program. +# +# "This version of Buzzword was written by David Ahl." +# +# +# Python port by Jeff Jetton, 2019 +# +###################################################################### + + +import random + + +WORDS = [ ["Ability", "Basal", "Behavioral", "Child-centered", + "Differentiated", "Discovery", "Flexible", "Heterogeneous", + "Homogenous", "Manipulative", "Modular", "Tavistock", + "Individualized"], + + ["learning", "evaluative", "objective", "cognitive", + "enrichment", "scheduling", "humanistic", "integrated", + "non-graded", "training", "vertical age", "motivational", + "creative"] , + + ["grouping", "modification", "accountability", "process", + "core curriculum", "algorithm", "performance", + "reinforcement", "open classroom", "resource", "structure", + "facility","environment"] ] + + +# Display intro text +print("\n Buzzword Generator") +print("Creative Computing Morristown, New Jersey") +print("\n\n") +print("This program prints highly acceptable phrases in") +print("'educator-speak' that you can work into reports") +print("and speeches. Whenever a question mark is printed,") +print("type a 'Y' for another phrase or 'N' to quit.") +print("\n\nHere's the first phrase:") + +still_running = True +while still_running: + phrase = "" + for section in WORDS: + if len(phrase) > 0: + phrase += " " + phrase += section[random.randint(0, len(section)-1)] + + print(phrase) + print("") + + response = input("? ") + try: + if response.upper()[0] != 'Y': + still_running = False + except: + still_running = False + + +print("Come back when you need help with another report!\n") + + + +###################################################################### +# +# Porting Notes +# +# The original program stored all 39 words in one array, then +# built the buzzword phrases by randomly sampling from each of the +# three regions of the array (1-13, 14-26, and 27-39). +# +# Here, we're storing the words for each section in separate +# tuples. That makes it easy to just loop through the sections +# to stitch the phrase together, and it easily accomodates adding +# (or removing) elements from any section. They don't all need to +# be the same length. +# +# The author of this program (and founder of Creative Computing +# magazine) first started working at DEC--Digital Equipment +# Corporation--as a consultant helping the company market its +# computers as educational products. He later was editor of a DEC +# newsletter named "EDU" that focused on using computers in an +# educational setting. No surprise, then, that the buzzwords in +# this program were targeted towards educators! +# +# +# Ideas for Modifications +# +# Try adding more/different words. Better yet, add a third +# dimnension to our WORDS tuple to add new sets of words that +# might pertain to different fields. What would business buzzwords +# be? Engineering buzzwords? Art/music buzzwords? Let the user +# choose a field and pick the buzzwords accordingly. +# +###################################################################### + + + + + + + diff --git a/33 Dice/python/dice.py b/33 Dice/python/dice.py new file mode 100644 index 000000000..94cdab6bd --- /dev/null +++ b/33 Dice/python/dice.py @@ -0,0 +1,123 @@ +######################################################## +# +# Dice +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "Not exactly a game, this program simulates rolling +# a pair of dice a large number of times and prints out +# the frequency distribution. You simply input the +# number of rolls. It is interesting to see how many +# rolls are necessary to approach the theoretical +# distribution: +# +# 2 1/36 2.7777...% +# 3 2/36 5.5555...% +# 4 3/36 8.3333...% +# etc. +# +# "Daniel Freidus wrote this program while in the +# seventh grade at Harrison Jr-Sr High School, +# Harrison, New York." +# +# Python port by Jeff Jetton, 2019 +# +######################################################## + + +import random + + +# We'll track counts of roll outcomes in a 13-element list. +# The first two indices (0 & 1) are ignored, leaving just +# the indices that match the roll values (2 through 12). +freq = [0] * 13 + + +# Display intro text +print("\n Dice") +print("Creative Computing Morristown, New Jersey") +print("\n\n") +# "Danny Freidus" +print("This program simulates the rolling of a") +print("pair of dice.") +print("You enter the number of times you want the computer to") +print("'roll' the dice. Watch out, very large numbers take") +print("a long time. In particular, numbers over 5000.") + +still_playing = True +while still_playing: + print("") + n = int(input("How many rolls? ")) + + # Roll the dice n times + for i in range(n): + die1 = random.randint(1, 6) + die2 = random.randint(1, 6) + roll_total = die1 + die2 + freq[roll_total] += 1 + + # Display final results + print("\nTotal Spots Number of Times") + for i in range(2, 13): + print(" %-14d%d" % (i, freq[i])) + + # Keep playing? + print("") + response = input("Try again? ") + if len(response) > 0 and response.upper()[0] == 'Y': + # Clear out the frequency list + freq = [0]*13 + else: + # Exit the game loop + still_playing = False + + + + +######################################################## +# +# Porting Notes +# +# A fairly straightforward port. The only change is +# in the handling of the user's "try again" response. +# The original program only continued if the user +# entered "YES", whereas this version will continue +# if any word starting with "Y" or "y" is given. +# +# The instruction text--which, like all these ports, +# was taken verbatim from the original listing--is +# charmingly quaint in its dire warning against +# setting the number of rolls too high. At the time +# of this writing, on a fairly slow computer, a +# 5000-roll run typically clocks in at well under +# 1/10 of a second! +# +# +# Ideas for Modifications +# +# Have the results include a third column showing +# the percent of rolls each count represents. Or +# (better yet) print a low-fi bar graph using +# rows of asterisks to represent relative values, +# with each asterisk representing one percent, +# for example. +# +# Add a column showing the theoretically expected +# percentage, for comparison. +# +# Keep track of how much time the series of rolls +# takes and add that info to the final report. +# +# What if three (or four, or five...) dice were +# rolled each time? +# +######################################################## + + + + + + + diff --git a/58 Love/python/love.py b/58 Love/python/love.py new file mode 100644 index 000000000..81c9ae2ff --- /dev/null +++ b/58 Love/python/love.py @@ -0,0 +1,155 @@ +###################################################################### +# +# LOVE +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "This program is designed to reproduce Robert Indiana's great art +# work 'Love' with a message of your choice up to 60 characters long. +# +# "The [DATA variable is] an alternating count of the number +# of characters and blanks which form the design. These data give +# the correct proportions for a standard 10 character per inch +# Teletype or line printer. +# +# "The LOVE program was created by David Ahl." +# +# +# Python port by Jeff Jetton, 2019 +# +###################################################################### + + +# Image data. Each top-level element is a row. Each row element +# contains alternating character and blank run lengths. +DATA = [ [60, ], + [1, 12, 26, 9, 12], + [3, 8, 24, 17, 8], + [4, 6, 23, 21, 6], + [4, 6, 22, 12, 5, 6, 5], + [4, 6, 21, 11, 8, 6, 4], + [4, 6, 21, 10, 10, 5, 4], + [4, 6, 21, 9, 11, 5, 4], + [4, 6, 21, 8, 11, 6, 4], + [4, 6, 21, 7, 11, 7, 4], + [4, 6, 21, 6, 11, 8, 4], + [4, 6, 19, 1, 1, 5, 11, 9, 4], + [4, 6, 19, 1, 1, 5, 10, 10, 4], + [4, 6, 18, 2, 1, 6, 8, 11, 4], + [4, 6, 17, 3, 1, 7, 5, 13, 4], + [4, 6, 15, 5, 2, 23, 5], + [1, 29, 5, 17, 8], + [1, 29, 9, 9, 12], + + [1, 13, 5, 40, 1], + [1, 13, 5, 40, 1], + [4, 6, 13, 3, 10, 6, 12, 5, 1], + [5, 6, 11, 3, 11, 6, 14, 3, 1], + [5, 6, 11, 3, 11, 6, 15, 2, 1], + [6, 6, 9, 3, 12, 6, 16, 1, 1], + [6, 6, 9, 3, 12, 6, 7, 1, 10], + [7, 6, 7, 3, 13, 6, 6, 2, 10], + [7, 6, 7, 3, 13, 14, 10], + [8, 6, 5, 3, 14, 6, 6, 2, 10], + [8, 6, 5, 3, 14, 6, 7, 1, 10], + [9, 6, 3, 3, 15, 6, 16, 1, 1], + [9, 6, 3, 3, 15, 6, 15, 2, 1], + [10, 6, 1, 3, 16, 6, 14, 3, 1], + [10, 10, 16, 6, 12, 5, 1], + [11, 8, 13, 27, 1], + [11, 8, 13, 27, 1], + [60, ] ] + + +# Assume that the total length of the first element +# is the line length used by every row +ROW_LEN = sum(DATA[0]) + +# Display intro text +print("\n Love") +print("Creative Computing Morristown, New Jersey") +print("\n\n") +print("A tribute to the great American artist, Robert Indiana.") +print("His great work will be reproduced with a message of") +print("your choice up to 60 characters. If you can't think of") +print("a message, simple type the word 'love'\n") # (sic) + +# Get message from user +message = input("Your message, please? ") +if message == "": + message = "LOVE" + +# Repeat the message until we get at least one line's worth +while(len(message) < ROW_LEN): + message += message + +# Display image +print("\n" * 9) +for row in DATA: + print_message = True + position = 0 + line_text = '' + for length in row: + if print_message: + text = message[position:(position + length)] + print_message = False + else: + text = " " * length + print_message = True + line_text += text + position += length + print(line_text) + +print("") + + + +###################################################################### +# +# Porting Notes +# +# Not too different from the original, logic-wise. The image was +# originally encoded as a series of BASIC "DATA" lines. Here, +# we've converted it to a more Pythonic nested list structure. +# Other changes include reducing some of the vertical spacing +# (since we'll probably be showing this on a screen rather than +# the sort of tractor-feed printer the program was written for) +# and having the message default to LOVE when no input is given. +# +# This program uses a simple version of run-length encoding to +# compress a 60 x 36 image (2,160 characters) into just 252 DATA +# values. That's about an 8.5-to-1 data compression ratio, +# which is pretty good! +# +# +# Ideas for Modifications +# +# Process the user's message input to remove spaces and change +# to uppercase. +# +# Encode other images in a similar fashion and let the user choose +# which one they'd like to use to display their message. +# +# To help with the above step, create a program that reads in a +# text file of any sort of similar character/space art and produces +# the Python code to initialize the correct nested list of values. +# +# For example, if the input file were: +# +# ***** +# * ** +# ** * +# +# Your program would output: +# +# ((5, ), (1, 1, 2), (2, 1, 1)) +# +###################################################################### + + + + + + + diff --git a/78 Sine Wave/python/sinewave.py b/78 Sine Wave/python/sinewave.py new file mode 100644 index 000000000..d1d0024d8 --- /dev/null +++ b/78 Sine Wave/python/sinewave.py @@ -0,0 +1,115 @@ +######################################################## +# +# Sine Wave +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "Did you ever go to a computer show and see a bunch of +# CRT terminals just sitting there waiting forlornly +# for someone to give a demo on them. It was one of +# those moments when I was at DEC that I decided there +# should be a little bit of background activity. And +# why not plot with words instead of the usual X's? +# Thus SINE WAVE was born and lives on in dozens of +# different versions. At least those CRTs don't look +# so lifeless anymore." +# +# Original BASIC version by David Ahl +# +# Python port by Jeff Jetton, 2019 +# +######################################################## + +import math, time + +# Constants +STRINGS = ('Creative', 'Computing') # Text to display +MAX_LINES = 160 +STEP_SIZE = 0.25 # Number of radians to increase at each + # line. Controls speed of horizontal + # printing movement. +CENTER = 26 # Controls left edge of "middle" string +DELAY = 0.05 # Amount of seconds to wait between lines + + +# Display "intro" text +print("\n Sine Wave") +print(" Creative Computing Morristown, New Jersey") +print("\n\n\n\n") +# "REMarkable program by David Ahl" + + +string_index = 0 +radians = 0 +width = CENTER - 1 + +# "Start long loop" +for line_num in range(MAX_LINES): + + # Get string to display on this line + curr_string = STRINGS[string_index] + + # Calculate how far over to print the text + sine = math.sin(radians) + padding = int(CENTER + width * sine) + print(curr_string.rjust(padding + len(curr_string))) + + # Increase radians and increment our tuple index + radians += STEP_SIZE + string_index += 1 + if string_index >= len(STRINGS): + string_index = 0 + + # Make sure the text doesn't fly by too fast... + time.sleep(DELAY) + + + +######################################################## +# +# Porting Notes +# +# The original BASIC version hardcoded two words in +# the body of the code and then used a sentinel flag +# (flipping between 0 and 1) with IF statements to +# determine the word to display next. +# +# Here, the words have been moved to a Python tuple, +# which is iterated over without any assumptions about +# how long it is. The STRINGS tuple can therefore be +# modified to have to program print out any sequence +# of any number of lines of text. +# +# Since a modern computer running Python will print +# to the screen much more quickly than a '70s-era +# computer running BASIC would, a delay component +# has been introduced in this version to make the +# output more historically accurate. +# +# +# Ideas for Modifications +# +# Ask the user for desired number of lines (perhaps +# with an "infinite" option) and/or step size. +# +# Let the user input the text strings to display, +# rather than having it pre-defined in a constant. +# Calculate an appropriate CENTER based on length of +# longest string. +# +# Try changing STINGS so that it only includes a +# single string, just like this: +# +# STRINGS = ('Howdy!') +# +# What happens? Why? How would you fix it? +# +######################################################## + + + + + + + diff --git a/82 Stars/python/stars.py b/82 Stars/python/stars.py new file mode 100644 index 000000000..7b4cbfa14 --- /dev/null +++ b/82 Stars/python/stars.py @@ -0,0 +1,141 @@ +###################################################################### +# +# Stars +# +# From: BASIC Computer Games (1978) +# Edited by David H. Ahl +# +# "In this game, the computer selects a random number from 1 to 100 +# (or any value you set [for MAX_NUM]). You try to guess the number +# and the computer gives you clues to tell you how close you're +# getting. One star (*) means you're far away from the number; seven +# stars (*******) means you're really close. You get 7 guesses. +# +# "On the surface this game is very similar to GUESS; however, the +# guessing strategy is quite different. See if you can come up with +# one or more approaches to finding the mystery number. +# +# "Bob Albrecht of People's Computer Company created this game." +# +# +# Python port by Jeff Jetton, 2019 +# +###################################################################### + + +import random + +# Some contants +MAX_NUM = 100 +MAX_GUESSES = 7 + + +def print_instructions(): + # "*** Instructions on how to play" + print("I am thinking of a whole number from 1 to %d" % MAX_NUM) + print("Try to guess my number. After you guess, I") + print("will type one or more stars (*). The more") + print("stars I type, the closer you are to my number.") + print("one star (*) means far away, seven stars (*******)") + print("means really close! You get %d guesses." % MAX_GUESSES) + + +def print_stars(secret_number, guess): + diff = abs(guess - secret_number) + stars = "" + for i in range(8): + if diff < 2**i: + stars += "*" + print(stars) + + +def get_guess(): + valid_response = False + while not valid_response: + guess = input("Your guess? ") + if guess.isdigit(): + valid_response = True + guess = int(guess) + return(guess) + + + +# Display intro text +print("\n Stars") +print("Creative Computing Morristown, New Jersey") +print("\n\n") +# "*** Stars - People's Computer Center, MenloPark, CA" + +response = input("Do you want instructions? ") +if response.upper()[0] == "Y": + print_instructions() + +still_playing = True +while still_playing: + + # "*** Computer thinks of a number" + secret_number = random.randint(1, MAX_NUM) + print("\n\nOK, I am thinking of a number, start guessing.") + + # Init/start guess loop + guess_number = 0 + player_has_won = False + while (guess_number < MAX_GUESSES) and not player_has_won: + + print("") + guess = get_guess() + guess_number += 1 + + if guess == secret_number: + # "*** We have a winner" + player_has_won = True + print("*************************" + + "*************************!!!") + print("You got it in %d guesses!!!" % guess_number) + + else: + print_stars(secret_number, guess) + + # End of guess loop + + # "*** Did not guess in [MAX_GUESS] guesses" + if not player_has_won: + print("\nSorry, that's %d guesses, number was %d" % + (guess_number, secret_number)) + + # Keep playing? + response = input("\nPlay again? ") + if response.upper()[0] != "Y": + still_playing = False + + + +###################################################################### +# +# Porting Notes +# +# The original program never exited--it just kept playing rounds +# over and over. This version asks to continue each time. +# +# +# Ideas for Modifications +# +# Let the player know how many guesses they have remaining after +# each incorrect guess. +# +# Ask the player to select a skill level at the start of the game, +# which will affect the values of MAX_NUM and MAX_GUESSES. +# For example: +# +# Easy = 8 guesses, 1 to 50 +# Medium = 7 guesses, 1 to 100 +# Hard = 6 guesses, 1 to 200 +# +###################################################################### + + + + + + +