Learn to code with step-by-step lessons. A place for students to work through programming fundamentals and build skills.
← Step 2 · Tutorial 1.1 · Step 4 →
Make the current piece move left, right, and down with the keyboard. When a move would put the piece outside the grid or on top of an existing block, don’t allow it (rollback). When moving down causes a collision, lock the piece: add its blocks to the board and spawn a new piece. Use a try → check → rollback pattern: change position, check collision, and if there’s a collision undo the change (and for down, lock and spawn).
By the end of this step you should have:
check_collision() on Piece: returns True if any cell of the piece is out of bounds or overlaps a block in game.board.move(direction) on Piece: updates origin for “left”/”right”/”down”, calls check_collision(); if collision, restore the old origin. If the collision was on “down”, also call update_board() (add this piece’s blocks to game.board) and new_piece() (replace the current piece with a new one).This pattern is used everywhere in Tetris:
origin[1] += 1 for down).origin). If the move was down and we collided, that means the piece has landed - so lock it and spawn a new piece.check_collision() on Piece: build a list of (col, row) for each cell of the piece (using origin and offsets[self.offset_num]). Check: is any cell’s row ≥ game_area[1]? Column < 0 or ≥ game_area[0]? Is any cell’s (col, row) already in the board’s block locations? Return True if any of these happen.move(direction): save the current origin, then add (-1,0), (1,0), or (0,1) depending on direction. Call check_collision(). If True, set origin back to the saved value. If the collision was on down, call update_board() and new_piece().update_board(): for each offset in the current rotation, append to game.board a dict like {"location": (origin[0]+dx, origin[1]+dy), "image": ...}.new_piece(): remove the current piece from game.pieces and append a new Piece(game, ...). (You can pick a random type or cycle through a list.)pieces[0].move("left"), move("right"), and move("down").Run your game and play. Press A/D (or your keys) to move, and S or wait for the timer to drop. When the piece lands, it should lock and a new piece should appear. This is the first moment your project feels like a real game - you’re controlling something on the screen. Compare with the solution when ready.
Then go to Step 4 - Rotating pieces.