Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

Module 2: Spot it!

As with all assignments, make sure that you read, understand, and follow the course honor
code policy (https://canvas.rice.edu/courses/60066/assignments/syllabus) for assignments.

This assignment is due at 8PM on Friday, September 15, 2023. We will not always remind you of
assignment due dates. It is your responsibility to know them. Late assignments will be subject to
the course grading policies. Note, in particular, that the "available until date" of all homework
assignments will be 2 days after the assignment is due. No homework assignments may ever be
turned in after that time.

The goal of this homework is for you to get practice with more complex computational problems and
to become comfortable with more of the Python programming language. Again, we will follow the
process of:

1. Reading and understanding the problem description.


2. Determining the inputs and outputs.
3. Decomposing the problem into subproblems, as appropriate.
4. Designing a computational recipe (algorithm) to solve the subproblems/problem.
5. Implementing your solution.

Be sure to read the entire assignment before beginning. And, as always, be sure you have read and
be sure you follow both the COMP 140 Recipe Guide
(https://canvas.rice.edu/courses/60066/pages/comp-140-recipe-guide) and the COMP 140 Coding
Style Standards (https://canvas.rice.edu/courses/60066/pages/comp-140-coding-style-standards) .

1. The Problem
In this assignment, you will create a deck of cards for the game of "Spot it!". You will be able to use
this deck to play a single-person variant of the game.

In a valid deck of cards for the game, every card must have the same number of images and every
card must have one image, and only one image, in common with every other card in the deck.

As with the last module, hopefully, the problem is clear from the English language description.
However, the solution strategy for this problem is likely to be much less obvious.

2. A Solution Strategy
First, make sure you understand the problem we are trying to solve. Once you do, we need to
develop a solution strategy. We are going to use projective geometry to solve this problem.

Recall from lecture (in Module 2C) that projective geometry has the following four properties:

1. A point is a triple of numbers that are not all zero. (The use of parentheses is just to
distinguish between points and lines.)
2. A line is a triple of numbers, that are not all zero. (The use of brackets is just to
distinguish between points and lines.)
3. If , then and .
4. The point is on the line if and only if .

To actually use projective geometry to create a deck of cards for "Spot it!", we have to further restrict
our numbers to be in a finite field, . In order to construct a valid projective geometric plane,
must be a prime number so that we can add, subtract, multiply, and divide numbers. Remember in
a finite field, , all mathematical operations must be performed modulo .

Projective geometry also has an elegant symmetry in which there is a duality between points and
lines. This means that you can interchange points and lines in any true theorem or statement about
a projective geometric plane. See, for example, the duality of properties (1) and (2) above. Further,
note that properties (3) and (4) remain valid if you interchange the points and lines.

3. Breaking Down the Problem


The ultimate objective is to create a projective plane in and convert that to a deck of cards. It is
unreasonable to try to do this in one step.

The four mathematical conditions for projective geometry give us a clue as to the underlying
operations we will need:

1. We need to be able to generate all points in a projective plane.


2. We need to be able to generate all lines in a projective plane. (Note that due to the duality of
projective geometry, this is exactly the same as generating all points, so we can just use the
same function to generate either points or lines!)
3. We need to be able to check if two points/lines are the same.
4. We need to be able to check if a point is on a line.

There are primarily two types of data in this problem: points and lines. We need to choose how to
represent these types. As points and lines cannot be modified, it makes sense to represent them
both using tuples with three elements. As they are the dual of each other, representing them both in
the same way makes sense.

Given these representations, write the following functions. You should start your implementation
with the following template (https://py3.codeskulptor.org/#comp140_module2_template.py) . As
you develop your code, be sure to test it. You should test your own code yourself, and we have
provided an automated testing framework (https://py3.owltest.org/owltest/?
urlTests=comp140.module2_tests.py&urlPylintConfig=comp140.pylint_config.py&imports=%7Bcomp14
0:comp140_module2%7D) for further testing.

A. Incidence
Write a function, named incident , to test if a point lies on a line. The function should take a point, a
line, and a modulus and return True or False .
B. Equivalence

Write a function, named equivalent , to test if two points (lines) are equivalent. The function should
take two points and a modulus and return True or False .

Mathematically, this can be expressed as follows:

This is the simplest way of expressing this function, as it directly follows the definition of equivalence
in projective geometry. However, it is actually deceptively difficult to implement it this way because
some of the coordinates of both points can be 0. That makes it difficult to divide the elements of the
two points (using multiplicative inverses) and see if the results are all the same ( ).

Instead, we can use the cross product. The cross product can be interpreted as the line that
connects two points. The cross product is defined as follows:

This yields the line . If the result is all zero, then there is no line, so they must be the same
point! To help understand this, first do the following:

i. Pick two points that you know are distinct in , yet equivalent in a finite projective field and
compute the cross product. Confirm that it is . Show all of your work in your written
submission.

ii. Pick two points that you know are not the same and compute the cross product. Confirm that
both points lie on that line using condition (4) above. Show all of your work in your written
submission.

Given the definition of the cross product, the equivalent function can be expressed mathematically
as follows:

iii. Write the function equivalent . The function should take two points and a modulus and return
True or False .

C. Generating all points


i. Recipe

Generating all of the points in a projective plane is a multi-step process. Clearly describe a recipe
(https://canvas.rice.edu/courses/60066/pages/comp-140-recipe-guide) for computing all of the unique
points in the projective plane given a prime modulus.

You should describe this recipe in clear, concise English and math notation. Do not use any
Python! You can use bulleted (or enumerated) lists for clarity, if you desire.
If you need to break down the recipe into multiple functions, clearly describe the recipe for each
one. Don't forget that you've already been asked to write two functions that might be useful, as
well! If you need to use incident or equivalent , you can just use them; you do not need to further
describe the recipe for either.

ii. Code

Implement your recipe in Python in a function named generate_all_points . This function should
take a modulus as input and return a list of points. Each point should be a tuple with 3 elements.
You may write and use any helper functions that are appropriate. Your implementation should follow
the recipe you gave in part (i).

4. Solving the Problem


At this point, you have a working implementation of a projective geometric plane. You can, and
should, confirm this with the automated testing framework. If you do not, you should go back to the
previous problem and continue until you successfully pass the tests. Solving the actual problem
now requires mapping the points in the projective geometric plane into a deck of "Spot it!" cards.

The key insight here is that each card in the deck is simply a line in the projective geometric plane
and each image on the card is a point on that line. We do not want to label images on the "Spot it!"
cards with their points. Instead, we just want to use consecutive integers starting at 0. It
does not matter which point is assigned to which integer, so you can just use the index of the point
in the list generated by generate_all_points .

A. Recipe

Clearly describe the recipe for converting points in a projective geometric plane into cards for a
"Spot it!" game. You will need both the points and the prime modulus. Keep in mind the functions
you wrote in part 3. You can make use of those functions here (and do not need to describe how
they work, as you have already done so)!

B. Code

Write a function create_


create_cards . This function should take a list of points (as created by
generate_all_points ), a list of lines, and a modulus. It should output a list of cards. Each card
should be a list of numbers representing the images that will be on that card. Your implementation
should follow the recipe you gave in part (A).

Once you have completed (and tested) this function, you can uncomment the call to spotit.start

at the bottom of the file and you will be able to play your "Spot it!" game! To play, click the matching
image on the player's card (on the right). See how quickly you can get through all the cards.

5. Discussion
If you use a prime modulus of 5, you will generate a valid deck of 31 "Spot it!" cards, each with 6
images on them. If you use a prime modulus of 7, you will generate a valid deck of 57 "Spot it!"
cards, each with 8 images on them.
Suppose you wanted to create a valid deck of 40 "Spot it!" cards. Is this possible? If not, why not?
If so, how would you go about doing so?

Answer this question by expressing your ideas in a few sentences of English. You do not need to
prove anything mathematically or show any Python.

6. Submission
This assignment should be submitted in two parts. All of the code should be submitted as a single
CodeSkulptor URL through CanvasTest. All of the written questions should be submitted as a single
PDF file through Gradescope with written answers for all of the parts that require that.

That is, you will submit the code to the "Spot it! (Python)" assignment in Canvas, and you will submit
the writeup to the "Spot it! (Writeup)" assignment in Gradescope. You access Gradescope via the
"Gradescope" link on the navigation bar in the Canvas site. Be sure to submit
to both assignments! It is your responsibility to remember to do so.

You may submit as many times as you like. However, only your last Python submission and your
last Writeup submission will count towards your assignment grade and be used to determine if your
assignment is late. Requests to instead grade previous submissions will be denied.

You might also like