A test project is an assignment that you complete on your own, without the help of others. It is like a take-home exam. You may use the textbook, your notes, your previous assignments, the notes and examples on the course web page and the Python library documentation (linked from the course web page), but use of any other source, such as Google, is not permitted. You may not discuss these assignment with anyone except the course instructor, and ASIs and tutors. However, all of those parties may only give you limited answers (as you would expect during an exam).
To be clear, you may not work with, discuss, or in any way collaborate with anyone else.
You are encouraged to reuse code from your assignments or our class examples. Partial credit will be awarded, so if you can’t solve the whole problem, get as far as you can. If you are stuck, contact me. While I cannot help you solve the test project itself, I may be able to suggest general problem-solving strategies, help with conceptual difficulties about Python, and or direct you to relevant examples from class.
For this test project you will be implementing a text-based version of the game “Memory” (aka concentration), where the user has to find matching pairs of cards. See the Wikipedia page on the game for more information.
When the game starts, all of the cards are face down. In our version there are 16 cards, each indicated by a numbered square. The cards are laid out in four rows of four cards each:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
“Underneath” each of these numbers is a letter. The user does not see these, but the program will keep track of them. For example, the board above may have the following letters underneath:
G D B F H B C D A A E E F H G C
The game proceeds by having the user pick two squares to look under by entering the numbers of the squares separated by a space.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Guess two squares:
For example, to view squares 1 and 2 the user would type
1 2; to view 7 and
15 the user would type
7 15. The two cards that the user specified are then
shown. For example, if the user entered
7 15 they would see:
1 2 3 4 5 6 C 8 9 10 11 12 13 14 G 16
If the user’s selected cards do NOT match, like 7 (C) and 15 (G), then the cards are displayed for 2 seconds and then turned back over leaving just the numbers. The user is then prompted for another choice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Guess two squares:
If the user selects two that do match, for example 2 and 8 (both D) then those two are flipped over and they stay flipped over for the rest of the game. The user is then immediately prompted to enter an additional pair.
1 D 3 4 5 6 7 D 9 10 11 12 13 14 15 16 Guess two squares:
If the user enters invalid numbers (outside the range 1-16, or cards that have already been turned over), the program notifies the user of the invalid input and prompts them again:
Guess two squares: 1 33 Invalid number(s). Guess two squares:
The game ends once the user finds all matching pairs. When the game ends, the text “You win!” is displayed along with the finished board, the number of moves, and the amount of time it took the player to solve the game. For example:
You win! G D B F H B C D A A E E F H G C It took you 15 guesses and 99 seconds.
To run a demo of the memory game:
On OSX, start Terminal from within Thonny via the “Tools -> Open System Shell” menu option. Windows users can download and use the Putty SSH program. Note that you want the “putty.exe” binary (further down on the page), not the package installer. Here are some additional instructions for using Putty.
Connect to basin via using the following command, replacing
with your Middlebury username. Answer yes to any question and then enter
your Middlebury password (as a security measure nothing will show on the
screen while you type your password).
ssh <middlebury username>@basin.cs.middlebury.edu
e.g. for me it is
Once connected, in the Terminal window type:
This should execute the example program in the terminal window. If you ever want to exit or quit early, you can type Ctrl + c.
play_gamethat does not take any parameters.
If you follow the above requirements (and also get full credit for style and documentation), you will earn 48 of 50 points. For the remaining two points, your program should easily generalize to other board sizes, solely by changing your two constants that specify the number of rows and columns. This means you will need to use loops for initializing and printing the board. Any even number of squares should be supported, up to 50 squares (25 pairs of letters), with no more than 10 rows or 10 columns. For instance, if 5 rows and 8 columns are specified, the game should use 20 pairs of letters (‘A’ through ‘T’).
As always, I strongly suggest an incremental approach to developing your program. Before you start programming, develop a design (like you did for lab 8) that describes what functions you will need, the parameters each function should take and how each function will work. You won’t turn this in, but it will save you a lot of time if you think through the design of the program first. As you start to code, work incrementally - pick one function and get it working before moving on. Read through this entire section before you start the program since I provide many implementation suggestions.
As you’re thinking about how you will write your program, think about what information you need to store and update as the game progresses and how you are going to represent this information. For example, for the word game (Lab 6) we had a number of pieces of information:
What information do we need to keep track of for this game? And how will it be stored? As a string, a list, a set, a dictionary, etc.? You should choose data structures that are convenient and efficient. You will be graded based on your choices; for example, using a string to represent the entire board will be neither convenient nor efficient, and so would not earn full credit.
Your program will necessarily have a loop to repeat the steps of each “turn. In each “turn”:
This is a rough skeleton of each “turn”. I suggest making a more detailed listing of the game play in each turn during the planning phase.
There are many ways of implementing this program. Here is one approach:
shufflethat takes a list as an argument and randomly shuffles the elements in place. For example, try shuffling the list
['A', 'A', 'B', 'B'].
To print multiple strings on the same line, use the optional keyword parameter
end to specify what should be printed after each item (by default
end is the
newline character). See
help(print). For example:
>>> for i in range(3): ... print(i) ... 0 1 2 >>> for i in range(3): ... print(i, end=" ") ... 0 1 2 >>> >>> >>> for i in range(3): ... print(i, end="") ... 012>>>
Note that in both of the latter cases, changing
end parameter means no
newlines are printed at all. An alternate approach is to build up a string, and
then print that string:
>>> s = '' >>> for i in range(3): ... s += str(i) ... >>> print(s) 012
Python strings have a
ljust method that can be used to generate
left-justified text padded out to a fixed width.
Before submitting your code, double check to make sure you have satisfied all of the requirements and your program runs properly in a newly started Python shell (running in the terminal is a good way ensure that is indeed the case).
Make sure that your program is properly documented:
and uses good coding style:
Submit your program via Gradescope. Your program program file must be named tp2_memory.py. You can submit multiple times, with only the most recent submission (before the due date) graded. Note that the tests performed by Gradescope are limited. Passing all of the visible tests does not guarantee that your submission correctly satisfies all of the requirements of the assignment.
Gradescope will import your file for testing so that make sure that, as specified, no code executes on import. That is when imported your program should not start the game.
|Board displays correctly||6|
|Board is randomly initialized||4|
|Loops until game completed||4|
|Properly handles match||7|
|Properly handles non-match||7|
|Handles invalid user input||6|
|Starts properly, counts guesses and records time elapsed||4|
|Generalizes to other sizes||2|
|Code design and style||10|