Tutorial 1.1 - Step 5

Learn to code with step-by-step lessons. A place for students to work through programming fundamentals and build skills.

Step 5 - Preventing rotation into walls and other pieces

← Step 4 · Tutorial 1.1 · Step 6 →


The problem

Right now, when you press rotate the piece always switches to the next offset list. So the piece can rotate into the wall or into locked blocks and look like it’s overlapping. That’s wrong: rotation should only be allowed if the new position is valid.


Goal

Use the same try → check → rollback pattern as for movement:

  1. Try the rotation: change offset_num to the next state.
  2. Check if that state causes a collision (use your existing check_collision()).
  3. If there’s a collision, rollback: restore the previous offset_num.

So rotation is only applied when the rotated shape doesn’t go out of bounds and doesn’t overlap the board.


Your task

  1. In rotate(), before changing offset_num, save the current value (e.g. old_offset = self.offset_num or use copy.copy).
  2. Apply the rotation: self.offset_num = (self.offset_num + 1) % len(self.offsets).
  3. Call check_collision(). If it returns True, set self.offset_num back to the saved value.
  4. No need to change key handling - still call rotate(1) on the rotate key.

Hints

Hint 1 - Why does the same check work for rotation? check_collision() already looks at the piece’s current origin and offsets[self.offset_num]. So after you change offset_num, calling check_collision() checks the *new* shape. If it overlaps the wall or the board, we rollback.
Hint 2 - Rollback only the offset We don’t move the piece’s position - only the rotation. So we only need to save and restore offset_num, not origin.
Hint 3 - Edge case: O piece The O piece often has only one offset list, so len(self.offsets) == 1 and rotation never changes the shape. That’s fine - the rollback logic still works; we just never see a different rotation.

Check your work

Rotating near a wall or near locked blocks should only change the shape when the new shape fits. If it would overlap, the piece should stay in the previous rotation. Compare with the solution when ready.

→ See the solution for Step 5

Then go to Step 6 - Clearing full rows.