patternpythonMinor
Tetris clone written in Python/Pygame
Viewed 0 times
writtenpythonpygametetrisclone
Problem
Tetromino class:
```
class Tetromino(object):
def __init__(self, board, matrix, type, color, x=0, y=None, updateinterval=FRAMERATE, queue=0):
self.matrix = matrix
self.type = type
self.board = board
self.color = color
self.updateinterval = updateinterval
self.time_until_update = self.updateinterval
self.draw_required = True
self.update_required = True
self.sped_up = False
self.x = x
self.y = y
self.queue = queue
self.level = 1
if y == None:
self.y = -(len(self.matrix))
## Hackety hack
def forBlock(self, func, boolean=False):
for y in xrange(len(self.matrix)):
for x in xrange(len(self.matrix[y])):
if self.matrix[y][x] and func(self.x + x, self.y + y, self.matrix) and boolean:
return True
def draw(self):
def drawBlock(x, y, _):
self.board.drawCube(x, y, self.color)
self.forBlock(drawBlock)
def insert(self):
def insert(x, y, _):
self.board.blocks[(x, y)] = self.color
if self.y self.board.height-1:
return "bottom"
if xp+x > self.board.width-1:
return "right"
if xp+x < 0:
return "left"
## Move diagonally, if possible
def moveDiagonal(self, direction):
self.y += direction
if self.checkBlockCollision():
self.y -= direction
self.insert()
if self.checkWallCollision(self.x, self.y) == "bottom":
self.y -= direction
self.insert()
## Move horizontally, if possible
def moveHorizontal(self, direction):
self.x += direction
if self.checkBlockCollision():
self.x -= direction
if self.checkWallCollision(self.x, self.y):
self.x -= direction
## Rotate if possible
def rotate(s
```
class Tetromino(object):
def __init__(self, board, matrix, type, color, x=0, y=None, updateinterval=FRAMERATE, queue=0):
self.matrix = matrix
self.type = type
self.board = board
self.color = color
self.updateinterval = updateinterval
self.time_until_update = self.updateinterval
self.draw_required = True
self.update_required = True
self.sped_up = False
self.x = x
self.y = y
self.queue = queue
self.level = 1
if y == None:
self.y = -(len(self.matrix))
## Hackety hack
def forBlock(self, func, boolean=False):
for y in xrange(len(self.matrix)):
for x in xrange(len(self.matrix[y])):
if self.matrix[y][x] and func(self.x + x, self.y + y, self.matrix) and boolean:
return True
def draw(self):
def drawBlock(x, y, _):
self.board.drawCube(x, y, self.color)
self.forBlock(drawBlock)
def insert(self):
def insert(x, y, _):
self.board.blocks[(x, y)] = self.color
if self.y self.board.height-1:
return "bottom"
if xp+x > self.board.width-1:
return "right"
if xp+x < 0:
return "left"
## Move diagonally, if possible
def moveDiagonal(self, direction):
self.y += direction
if self.checkBlockCollision():
self.y -= direction
self.insert()
if self.checkWallCollision(self.x, self.y) == "bottom":
self.y -= direction
self.insert()
## Move horizontally, if possible
def moveHorizontal(self, direction):
self.x += direction
if self.checkBlockCollision():
self.x -= direction
if self.checkWallCollision(self.x, self.y):
self.x -= direction
## Rotate if possible
def rotate(s
Solution
I have a few comments on your OOP design.
Your
Therefore, the
Then, we add a
Lastly we should have a
The
Your
Tetromino class is way too full of functionality, or in other words, bloated. On one hand, it stores the basic info of location, type etc, but at the same time it is responsible for events, drawing, and collision detection. That is a violation of the Single Responsibility Principle which states that each component should be responsible for 1 task. Therefore, the
Tetromino class should just have a list of the 4 coordinates, and a color. We then subclass Tetromino for all the types of tetrominoes: SquareTetromino, LineTetromino, and etc. which will have convenient initializers for generating the correct coordinates given a single coordinate (such as the upper left corner). Then, we add a
TetrominoController which handles moving the Tetrominos as needed and so has a list of the tetrominos and the dimensions of the board. This class does the bound checking.Lastly we should have a
TetrominoRenderer that interfaces with the TetrominoController to draw the board (the controller will notify the renderer when positions change and so on).The
Game class should interact with the TetrominoController to dictate updates, and it should initialize the renderer (but not do anything else, as the renderer should get notifications from the controller).Context
StackExchange Code Review Q#49812, answer score: 4
Revisions (0)
No revisions yet.