Skip to content

Part 2: The Pytromino

Brief

In Pyturis, pytrominoes are the name for the pieces that fall from the top of the board. Each pytromino is represented as a single shape made of four blocks. In addition to absolute coordinates that represent where the pytromino is on the board, each block in the pytromino has a relative coordinate, to indicate its position within the pytromino.

The relative coordinates are calculated according to where the block is relative to the center of rotation for that pytromino.

Pytroillu

We’ll use a combination of the relative and absolute coordinates of pytrominoes. The pytromino is always moving around on the board, but once we know the absolute coordinates of the center of rotation block, they can be used to calculate the absolute coordinates of all other blocks in that pytromino using the relative coordinates.

Attributes

The Pytromino class is located in the models.py file. As with the Board class, there is already a constructor method provided, which contains a few useful attributes:

  • [Tuple] self.center_rot represents the coordinates of the center of rotation block of a pytromino and defaults to (0, 0)
  • [List] self.blocks_pos lists the set of coordinates (x, y) of the blocks in a pytromino relative to the center

TODOs

You’ll need to fill out four methods in models.py. We recommended (but do not require) that you use list comprehensions in your solution (when possible).

  • Q6: rotate_block_90_cw(pytromino, pos): Given pytromino, a Pytromino object, and pos, a tuple of x, y coordinates representing the center of rotation, return the updated coordinates as a tuple when pytromino is rotated 90 degrees clockwise.
  • Q7: filter_blocks_pos(pytromino, fn): Given pytromino, a Pytromino object, and the predicate function fn, which takes in a tuple coordinate and returns a boolean, filter the list of block positions of the pytromino on fn, and return the result as a new list of coordinates.
  • Q8: shift_down_fn(pos, steps): Given a position pos as a tuple, return a new position that's shifted down by steps. Hint: return a new position instead of directly modifying the original position!
  • Q9: shift_left_fn(pos, steps): Given a position pos as a tuple, return a new position that's shifted left by steps.

Validate & Apply

You’ll also need to fill out validated_apply_non_rot. However, you’ll need to have completed ALL other methods first. A validated apply means applying some transformation function (in our case, fn) to some input only if the output of that transformation function passes some validator check. If the output doesn’t pass the check, the input is left untransformed.

  • Q10: validated_apply_non_rot(self, fn, validator): returns a new Pytromino object, whose coordinates will be updated correspondingly if the transformation fn is successful on all items in self.blocks_pos. If the operation is not successful, the coordinates of the returned object remain unchanged. This function is called when the transformation is not rotational.

    In English, we have a Pytromino (consisting of four squares on the screen) and a fn() that wants to move it somewhere. The validator is going to check whether, as a result of that move, all the squares of the Pytromino are still on the screen (i.e., pass the validator). If all are, then great, return a Pytromino that is the result of the fn() move (remember BOTH the center of the Pytromino and all its squares need to be moved). Otherwise, don’t make the move and return a Pytromino without the fn() move applied.

arguments:

  • [Pytromino object] pytromino: the Pytronimo object to operate on
  • [Function] fn : takes in a coordinate and returns a transformed coordinate
  • [Function] validator : validates an input coordinate; returns True if valid, False otherwise

For this function, you should use validator to check each coordinate resulting from calling fn on every item in self.blocks_pos.

Local Tests

To check how your implementation is doing, You can run the local tests in the project directory with the following command. The code below tests all your work in models.py. To test each infividual question, replace the Pytromino in the command below with Q6 through Q10.

If there is no output in the terminal, that means your tests are PASSING!

For Windows:

py grader.py Pytromino

For Mac:

python3 grader.py Pytromino

Running the GUI

Once you’ve finished all parts, you’re done! Nice work! You can now play the game of Pyturis you’ve coded, by running the following command inside the project directory:

For Windows:

py __main__.py

For Mac:

python3 __main__.py