Ejemplo n.º 1
0
    def __init__(self, parent, nrows, ncols, blocksize):
        super(DrawabaleTetrisBoard, self).__init__(parent)

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize
        self.showgrid = True
        self.gridwidth = 2
        self.gridcolor = QColor(204, 204, 204)

        # the "sink" is the white border around the actual
        # tetris grid
        #
        self.sinkwidth = 4
        self.sinkcolor = 'white'
        self.block_border_color = 'black'
        self.bgcolor = QColor(234, 234, 244)

        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.width = self.sinkwidth * 2 + ncols * blocksize + (
            ncols + 1) * self.gridwidth
        self.height = self.sinkwidth * 2 + nrows * blocksize + (
            nrows + 1) * self.gridwidth

        self.board = TetrisBoard(nrows, ncols)
Ejemplo n.º 2
0
    def set_figure(self, figure):
        self.figure = figure
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(figure)
        self.board.move_figure_down()
        self.board.move_figure_down()

        self.update()
Ejemplo n.º 3
0
    def __init__(self, parent, nrows, ncols, blocksize):
        super(DrawabaleTetrisBoard, self).__init__(parent)

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize
        self.showgrid = True
        self.gridwidth = 2
        self.gridcolor = QColor(204, 204, 204)

        # the "sink" is the white border around the actual
        # tetris grid
        #
        self.sinkwidth = 4
        self.sinkcolor = "white"
        self.block_border_color = "black"
        self.bgcolor = QColor(234, 234, 244)

        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.width = self.sinkwidth * 2 + ncols * blocksize + (ncols + 1) * self.gridwidth
        self.height = self.sinkwidth * 2 + nrows * blocksize + (nrows + 1) * self.gridwidth

        self.board = TetrisBoard(nrows, ncols)
Ejemplo n.º 4
0
    def set_figure(self, figure):
        self.figure = figure
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(figure)
        self.board.move_figure_down()
        self.board.move_figure_down()

        self.update()
Ejemplo n.º 5
0
class TetrisPreviewWidget(DrawabaleTetrisBoard):
    """ A preview window for figures. Only shows a single figure, trying to
        center it vertically.
        Note: the success of this method depends on the actual figures that
        participate in the game. It works well for the default 7 Tetris
        figures.
    """
    def __init__(self, parent, nrows, ncols, blocksize):
        super(TetrisPreviewWidget, self).__init__(parent, nrows, ncols, blocksize)

        self.showgrid = False
        self.figure = None

    def set_figure(self, figure):
        self.figure = figure
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(figure)
        self.board.move_figure_down()
        self.board.move_figure_down()

        self.update()
Ejemplo n.º 6
0
class TetrisPreviewWidget(DrawabaleTetrisBoard):
    """ A preview window for figures. Only shows a single figure, trying to
        center it vertically.
        Note: the success of this method depends on the actual figures that
        participate in the game. It works well for the default 7 Tetris
        figures.
    """
    def __init__(self, parent, nrows, ncols, blocksize):
        super(TetrisPreviewWidget, self).__init__(parent, nrows, ncols,
                                                  blocksize)

        self.showgrid = False
        self.figure = None

    def set_figure(self, figure):
        self.figure = figure
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(figure)
        self.board.move_figure_down()
        self.board.move_figure_down()

        self.update()
Ejemplo n.º 7
0
class DrawabaleTetrisBoard(QWidget):
    """ A base class for tetris board widgets that can draw
        themselves.
    """
    def __init__(self, parent, nrows, ncols, blocksize):
        super(DrawabaleTetrisBoard, self).__init__(parent)

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize
        self.showgrid = True
        self.gridwidth = 2
        self.gridcolor = QColor(204, 204, 204)

        # the "sink" is the white border around the actual
        # tetris grid
        #
        self.sinkwidth = 4
        self.sinkcolor = 'white'
        self.block_border_color = 'black'
        self.bgcolor = QColor(234, 234, 244)

        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.width = self.sinkwidth * 2 + ncols * blocksize + (
            ncols + 1) * self.gridwidth
        self.height = self.sinkwidth * 2 + nrows * blocksize + (
            nrows + 1) * self.gridwidth

        self.board = TetrisBoard(nrows, ncols)

    def minimumSizeHint(self):
        return QSize(self.width, self.height)

    def sizeHint(self):
        return self.minimumSizeHint()

    def paintEvent(self, event=None):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillRect(0, 0, self.width, self.height,
                         QBrush(self.bgcolor, Qt.SolidPattern))

        if self.showgrid: self._draw_grid(painter)
        self._draw_sink(painter)

        self._draw_all_blocks(painter)

    def _draw_sink(self, painter):
        sink_pen = QPen(QColor(self.sinkcolor))
        sink_pen.setWidth(self.sinkwidth)
        painter.setPen(sink_pen)

        halfsink = self.sinkwidth / 2
        painter.drawLine(halfsink, 0, halfsink, self.height)
        painter.drawLine(self.width - halfsink, 0, self.width - halfsink,
                         self.height)
        painter.drawLine(0, halfsink, self.width, halfsink)
        painter.drawLine(0, self.height - halfsink, self.width,
                         self.height - halfsink)

    def _draw_grid(self, painter):
        grid_pen = QPen(QColor(self.gridcolor))
        grid_pen.setWidth(self.gridwidth)
        painter.setPen(grid_pen)

        # combined size of a block with a single grid line
        blockgrid_size = self.blocksize + self.gridwidth

        # horizontal
        for row in range(self.nrows + 1):
            painter.drawLine(self.sinkwidth,
                             self.sinkwidth + row * blockgrid_size + 1,
                             self.width - 1 - self.sinkwidth,
                             self.sinkwidth + row * blockgrid_size + 1)

        # vertical
        for col in range(self.ncols + 1):
            painter.drawLine(self.sinkwidth + col * blockgrid_size + 1,
                             self.sinkwidth,
                             self.sinkwidth + col * blockgrid_size + 1,
                             self.height - 1 - self.sinkwidth)

    def _draw_all_blocks(self, painter):
        board = self.board.board_with_active_figure()

        for row in range(self.nrows):
            for col in range(self.ncols):
                color = board[row][col]

                if color != 0:
                    self._draw_block(painter, row, col, color)

    def _draw_block(self, painter, row, col, color):
        block_pen = QPen(QColor(self.block_border_color))
        block_pen.setWidth(self.gridwidth)
        painter.setPen(block_pen)

        blockgrid_size = self.blocksize + self.gridwidth
        block_rect = QRect(self.sinkwidth + col * blockgrid_size + 1,
                           self.sinkwidth + row * blockgrid_size + 1,
                           blockgrid_size, blockgrid_size)

        painter.fillRect(block_rect, QBrush(color, Qt.SolidPattern))
        painter.drawRect(block_rect)
Ejemplo n.º 8
0
 def restart(self, startfigure):
     self.board = TetrisBoard(self.nrows, self.ncols)
     self.board.spawn_figure(startfigure)
     self.update()
Ejemplo n.º 9
0
class MainTetrisWidget(DrawabaleTetrisBoard):
    """ The main tetris window type, with an active figure that can be moved
        around, dropped, etc. and a bunch of inactive blocks.
        Supports all the expected tetris operations, like removing completed
        rows and generating new figures.
    """
    def __init__(self, parent, nrows, ncols, blocksize, startfigure):
        super(MainTetrisWidget, self).__init__(parent, nrows, ncols, blocksize)

        self.board.spawn_figure(startfigure)

        # Keeps track of the amount of rows the active figure
        # fell in the last "drop" command. This is used to
        # update the score.
        #
        self.last_drop_height = 0

    def restart(self, startfigure):
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(startfigure)
        self.update()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Up:
            self.board.rotate_figure()
        elif event.key() == Qt.Key_Down:
            self.board.move_figure_down()
        elif event.key() == Qt.Key_Left:
            self.board.move_figure_left()
        elif event.key() == Qt.Key_Right:
            self.board.move_figure_right()
        elif event.key() == Qt.Key_Space:
            for i in range(self.nrows):
                if not self.board.move_figure_down():
                    self.last_drop_height = i
                    break
        else:
            return

        self.update()

    Result = namedtuple('Result', 'state completed_rows drop_height')

    def timer_tick(self, nextfigure):
        """ One timer tick for the tetris game.
            
            Advances the game by one step and returns a result as 
            a namedtuple: 
            
                result.state:   
                    The game state.
                        running -   The current figure was moved 
                                    down by one cell successfully.
                        newfigure - The current figure could no 
                                    longer be moved down, so a new 
                                    figure was created.
                        gameover -  The current figure could no 
                                    longer be moved down, and a 
                                    new figure could not be
                                    created.
                                    
                result.completed_rows:
                    A list of row numbers that were completed with 
                    the current figure reaching bottom. It is 
                    applicable in the "newfigure" state
                
                result.drop_height: 
                    The amount of lines the figure was dropped in 
                    the last drop.
        """
        state = 'running'
        completed_rows = []
        drop_height = 0

        if self.board.move_figure_down():
            state = 'running'
        else:
            completed_rows = self.board.finish_fall()

            if self.board.spawn_figure(nextfigure):
                state = 'newfigure'
            else:
                state = 'gameover'

        drop_height = self.last_drop_height
        self.last_drop_height = 0

        self.update()
        return self.Result(state, completed_rows, drop_height)
Ejemplo n.º 10
0
class DrawabaleTetrisBoard(QWidget):
    """ A base class for tetris board widgets that can draw
        themselves.
    """

    def __init__(self, parent, nrows, ncols, blocksize):
        super(DrawabaleTetrisBoard, self).__init__(parent)

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize

        self.nrows = nrows
        self.ncols = ncols
        self.blocksize = blocksize
        self.showgrid = True
        self.gridwidth = 2
        self.gridcolor = QColor(204, 204, 204)

        # the "sink" is the white border around the actual
        # tetris grid
        #
        self.sinkwidth = 4
        self.sinkcolor = "white"
        self.block_border_color = "black"
        self.bgcolor = QColor(234, 234, 244)

        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.width = self.sinkwidth * 2 + ncols * blocksize + (ncols + 1) * self.gridwidth
        self.height = self.sinkwidth * 2 + nrows * blocksize + (nrows + 1) * self.gridwidth

        self.board = TetrisBoard(nrows, ncols)

    def minimumSizeHint(self):
        return QSize(self.width, self.height)

    def sizeHint(self):
        return self.minimumSizeHint()

    def paintEvent(self, event=None):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillRect(0, 0, self.width, self.height, QBrush(self.bgcolor, Qt.SolidPattern))

        if self.showgrid:
            self._draw_grid(painter)
        self._draw_sink(painter)

        self._draw_all_blocks(painter)

    def _draw_sink(self, painter):
        sink_pen = QPen(QColor(self.sinkcolor))
        sink_pen.setWidth(self.sinkwidth)
        painter.setPen(sink_pen)

        halfsink = self.sinkwidth / 2
        painter.drawLine(halfsink, 0, halfsink, self.height)
        painter.drawLine(self.width - halfsink, 0, self.width - halfsink, self.height)
        painter.drawLine(0, halfsink, self.width, halfsink)
        painter.drawLine(0, self.height - halfsink, self.width, self.height - halfsink)

    def _draw_grid(self, painter):
        grid_pen = QPen(QColor(self.gridcolor))
        grid_pen.setWidth(self.gridwidth)
        painter.setPen(grid_pen)

        # combined size of a block with a single grid line
        blockgrid_size = self.blocksize + self.gridwidth

        # horizontal
        for row in range(self.nrows + 1):
            painter.drawLine(
                self.sinkwidth,
                self.sinkwidth + row * blockgrid_size + 1,
                self.width - 1 - self.sinkwidth,
                self.sinkwidth + row * blockgrid_size + 1,
            )

        # vertical
        for col in range(self.ncols + 1):
            painter.drawLine(
                self.sinkwidth + col * blockgrid_size + 1,
                self.sinkwidth,
                self.sinkwidth + col * blockgrid_size + 1,
                self.height - 1 - self.sinkwidth,
            )

    def _draw_all_blocks(self, painter):
        board = self.board.board_with_active_figure()

        for row in range(self.nrows):
            for col in range(self.ncols):
                color = board[row][col]

                if color != 0:
                    self._draw_block(painter, row, col, color)

    def _draw_block(self, painter, row, col, color):
        block_pen = QPen(QColor(self.block_border_color))
        block_pen.setWidth(self.gridwidth)
        painter.setPen(block_pen)

        blockgrid_size = self.blocksize + self.gridwidth
        block_rect = QRect(
            self.sinkwidth + col * blockgrid_size + 1,
            self.sinkwidth + row * blockgrid_size + 1,
            blockgrid_size,
            blockgrid_size,
        )

        painter.fillRect(block_rect, QBrush(color, Qt.SolidPattern))
        painter.drawRect(block_rect)
Ejemplo n.º 11
0
 def restart(self, startfigure):
     self.board = TetrisBoard(self.nrows, self.ncols)
     self.board.spawn_figure(startfigure)
     self.update()
Ejemplo n.º 12
0
class MainTetrisWidget(DrawabaleTetrisBoard):
    """ The main tetris window type, with an active figure that can be moved
        around, dropped, etc. and a bunch of inactive blocks.
        Supports all the expected tetris operations, like removing completed
        rows and generating new figures.
    """

    def __init__(self, parent, nrows, ncols, blocksize, startfigure):
        super(MainTetrisWidget, self).__init__(parent, nrows, ncols, blocksize)

        self.board.spawn_figure(startfigure)

        # Keeps track of the amount of rows the active figure
        # fell in the last "drop" command. This is used to
        # update the score.
        #
        self.last_drop_height = 0

    def restart(self, startfigure):
        self.board = TetrisBoard(self.nrows, self.ncols)
        self.board.spawn_figure(startfigure)
        self.update()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Up:
            self.board.rotate_figure()
        elif event.key() == Qt.Key_Down:
            self.board.move_figure_down()
        elif event.key() == Qt.Key_Left:
            self.board.move_figure_left()
        elif event.key() == Qt.Key_Right:
            self.board.move_figure_right()
        elif event.key() == Qt.Key_Space:
            for i in range(self.nrows):
                if not self.board.move_figure_down():
                    self.last_drop_height = i
                    break
        else:
            return

        self.update()

    Result = namedtuple("Result", "state completed_rows drop_height")

    def timer_tick(self, nextfigure):
        """ One timer tick for the tetris game.
            
            Advances the game by one step and returns a result as 
            a namedtuple: 
            
                result.state:   
                    The game state.
                        running -   The current figure was moved 
                                    down by one cell successfully.
                        newfigure - The current figure could no 
                                    longer be moved down, so a new 
                                    figure was created.
                        gameover -  The current figure could no 
                                    longer be moved down, and a 
                                    new figure could not be
                                    created.
                                    
                result.completed_rows:
                    A list of row numbers that were completed with 
                    the current figure reaching bottom. It is 
                    applicable in the "newfigure" state
                
                result.drop_height: 
                    The amount of lines the figure was dropped in 
                    the last drop.
        """
        state = "running"
        completed_rows = []
        drop_height = 0

        if self.board.move_figure_down():
            state = "running"
        else:
            completed_rows = self.board.finish_fall()

            if self.board.spawn_figure(nextfigure):
                state = "newfigure"
            else:
                state = "gameover"

        drop_height = self.last_drop_height
        self.last_drop_height = 0

        self.update()
        return self.Result(state, completed_rows, drop_height)