Introduction
This handout explains the problem you are to solve, and the tasks you need to complete for the request. Please read it carefully.
Goals of this request
Use the Function Design Recipe to plan, implement, and test functions.
Write function bodies using variables, numeric types, strings, and conditional statements. (You can do this whole request with only the concepts from Weeks 1, 2, and 3 of the course.)
Learn to use Python 3, Wing 101, provided starter code, a checker module, and other tools.
Phrase Puzzler
In this request, you’ll be writing a Phrase Puzzler game. To see how the game is played, please watch the demo below.
The video demonstrates playing the one-player version of the game, but your code will eventually also have a two-player human vs. human version and also a human vs. computer version.
If you have trouble viewing the video above, you can click here to watch it on MS Stream (Links to an external site.).
Starter code
For this request, we are giving you some files, including Python starter code files. Please download the request 1 filesand extract/unzip the zip file.
There are three starter code Python files, two sample text input files, and a Python program that helps you check (not fully test!) your solutions for Python style violations:
puzzler_functions.py
This file contains constants for you to use in your code, a provided function (is_game_over), and the complete docstrings (but not the function bodies) for the first two functions you are to write. Note that we have provided extra docstring examples for these functions to help you, however you only need to write two for your own docstrings.
You can find the full table of functions to implement below. Your job is to complete this file.
puzzler.py
This is the main program. You will not modify this file (with one exception stated in the next section), and you will not submit it. Rather, you will run this file to play the Phrase Puzzler game. Please note that puzzler.py depends on functions you will write in puzzler_functions.py, so this program won’t run properly until you’ve implemented the functions.
puzzles_small.txt and puzzles.txt
Each of these files contains puzzle phrases used by puzzler.py to select a puzzle for a game and also to provide a pool of phrases that the computer player “knows”. You may want to use puzzles_small.txt when you are in the beginning of developing and debugging your solution, and puzzles.txt to play the game.
To change which of these files you are using, edit the string that the constant DATA_FILE refers to inpuzzler.py. This is the only change you should make topuzzler.py.
a1_checker.py
This is a checker program that you should use to check your code. See below for more information about a1_checker.py.
There are some other files and folders in the zip file. You do not need to do anything with them, other than leave them where they are.
Constants
Constants are special variables whose values should not change once assigned. A different naming convention (uppercase pothole) is used for constants, so that programmers know to not change their values. For example, in the starter code, the constant CONSONANT_POINTS is assigned the value 1 at the beginning of the module and the value of CONSONANT_POINTS should never change in your code. When writing your code, if you need to use the number of points awarded for a guessed consonant, you should use CONSONANT_POINTS. The same goes for the other constant values.
Using constants simplifies code modifications and improves readability and changeability. For example, if we later decide to use a different character to represent a hidden index in our puzzle, we would only have to make a change in one place (the HIDDEN request statement), rather than throughout the program. This also makes our code more readable – whether we use’^’or any other character to represent a hidden index, we write our code using the constant HIDDEN so it is clear to the reader what we mean.
More about the Phrase Puzzler program:
Two strings are used to represent information about a Phrase Puzzler puzzle:
puzzleis made up of alphabetic and non-alphabetic characters (e.g., spaces, punctuation, and digits). An example puzzle string is ‘e-mail inbox’.
view is the current view of the puzzle as seen by the players. In it, the alphabetic characters are either displayed (if they have been revealed) or hidden (using a special character (a caret’^’by default), if they have not yet been revealed). Non-alphabetic characters (spaces, punctuation, and digits) are always displayed. For example, at the beginning of the game, the view string for the puzzle above would be (with a caret to represent a hidden character):’^-^^^^ ^^^^^’.
As the game progresses and players guess letters to be revealed, the view is updated. Continuing with the example above, if the player guesses “m”, the view becomes’^-m^^^ ^^^^^’and then if “i” is guessed, it becomes’^-m^i^ i^^^^’.
There are three types of games that your program will play: human, human vs human, and human vs computer. We will use the constants HUMAN,HUMAN_HUMAN, and HUMAN_COMPUTER respectively, to represent the type of game being played.
When a player guesses a consonant, each occurrence of that consonant in the puzzle earns a certain number points for that player: the value of the constant CONSONANT_POINTS. If a player correctly guesses a consonant, they play again in the next turn. If the guess is incorrect, the turn goes to the next player (in a two-player game).
Players have to pay to guess a vowel. The cost does not depend on the number of occurrences of the vowel, and is always equal to the value of the constant VOWEL_PRICE. Thus, guessing a vowel decreases the player’s points. A player is not allowed to guess a vowel if they do not have sufficient points to pay for it. After paying to guess a vowel, the player plays again if the vowel is in the puzzle. If the guessed vowel is not in the puzzle, the turn goes to the next player (in a two-player game).
When a player solves the puzzle, CONSONANT_BONUS bonus points are added to their score for each occurrence of a consonant that is still HIDDEN.
All puzzles are always lower-case. That is, the puzzles will not contain any upper-case letters.
You should read the constants defined at the top of puzzler_functions.py carefully to understand the purpose of each defined constant. You must use these constants in your code and NOT the literal values. For example, you must use HIDDEN instead of’^’.
What to do
In the starter code file puzzler_functions.py, complete the following function definitions. Use the Function Design Recipe that you have been learning in this course. We have included the type contracts in the following table; please read through the table to understand how the functions will be used.
We will be evaluating your docstrings in addition to your code. Please include two examples in your docstrings. You will need to paraphrase the full descriptions of the functions to get an appropriate docstring description.
Using Constants
As we discuss in section Constants above, your code should make use of the provided constants. If the value of one of those constants were changed, and your program rerun, your functions should work with those new values.
For example, if CONSONANT_POINTS were changed, then your functions should work according to the new number of bonus points that should be earned for guessing a consonant. Using constants in your code means that this happens automatically.
Your docstring examples should reflect the given values of the constants in the provided starter code, and do not need to change.
Preconditions
You can assume that your functions will be called with arguments as described in the table above. For example, you can assume that is_human will only be passed one of the three constants representing the type of game being played.
If this hand out states that a parameter represents a particular value, then you can assume that will be the case and you do not need to state it as a precondition.
No Input or Output
Your puzzler_functions.py file should contain the starter code, plus the function definitions specified above. puzzler_functions.py must not include any calls to the print and input functions. Do not add any import statements. Also, do not include any function calls or other code outside of the function definitions.
How should you test whether your code works
First, run the checker and review ALL output you may need to scroll. You should also test each function individually by writing code to verify your functions in the Python shell. For example, after defining functionis_human, you might call it from the shell (e.g.,is_human(‘Player One’, ‘HC’)) to check whether it returns the right value (True). One call usually isn’t enough to thoroughly test the function for example, we should also testis_human(‘Player Two’, ‘HC’) where it must return False.
Running the checker program on Markus
In addition to running the checker program on your own computer, run the checker on MarkUs as well. You will be able to run the checker program on MarkUs once every 12 hours (note: we may have to revert to every 24 hours if MarkUs has any issues handling every 12 hours). This can help to identify issues such as uploading the incorrect file.
First, submit your work on MarkUs. Next, click on the “Automated Testing” tab and then click on “Run Tests”. Wait for a minute or so, then refresh the webpage. Once the tests have finished running, you’ll see results for the Style Checker and Type Checker components of the checker program (see both the Automated Testing tab and results files under the Submissions tab). Note that these are not actually marks – just the checker results. This is the same checker that we have provided to you in the starter code. If there are errors, edit your code, run the checker program again on your own machine to check that the problems are resolved, resubmit your request on MarkUs, and (if time permits) after the 24 hour period has elapsed, rerun the checker on MarkUs.