|
| 1 | +import pygame |
| 2 | +import random |
| 3 | +pygame.init() |
| 4 | + |
| 5 | +blocks = [ |
| 6 | + [[1,4,7],[3,4,5]], #straight |
| 7 | + [[1,3,4,5,7]], #cross |
| 8 | + [[0,1,4,5],[1,3,4,6]], # two on two ones |
| 9 | + [[1,2,3,4],[0,3,4,7]], |
| 10 | + [[0,1,3,6],[0,1,2,5],[2,5,7,8],[3,6,7,8]], |
| 11 | + [[1,2,5,8],[5,6,7,8],[0,3,6,7],[0,1,2,3]], |
| 12 | + [[4,6,7,8],[0,3,4,6],[0,1,2,4],[2,4,5,8]] |
| 13 | +] |
| 14 | + |
| 15 | +colours = [ |
| 16 | + (122,78,0), |
| 17 | + (0,255,0), |
| 18 | + (100,60,200), |
| 19 | + (100,50,100), |
| 20 | + (50,100,200), |
| 21 | + (255,0,0), |
| 22 | + (0,0,255) |
| 23 | +] |
| 24 | + |
| 25 | +class Block: |
| 26 | + def __init__(self,x,y): |
| 27 | + self.x = x |
| 28 | + self.y = y |
| 29 | + self.type = random.randint(0,len(blocks) - 1) |
| 30 | + self.rotation = 0 |
| 31 | + self.colour = colours[random.randint(0,len(colours) -1)] |
| 32 | + |
| 33 | + def shape(self): |
| 34 | + return blocks[self.type][self.rotation] |
| 35 | + |
| 36 | +def draw_block(screen, block, grid_size, x_gap, y_gap): |
| 37 | + for y in range(3): |
| 38 | + for x in range(3): |
| 39 | + if y * 3 + x in block.shape(): |
| 40 | + pygame.draw.rect(screen,block.colour, |
| 41 | + [(x + block.x) * grid_size + x_gap + 1, |
| 42 | + (y + block.y) * grid_size + y_gap + 1,grid_size - 2,grid_size - 2]) |
| 43 | + |
| 44 | +def collides(block,rows,cols,game_board,ny): |
| 45 | + collision = False |
| 46 | + for y in range(3): |
| 47 | + for x in range(3): |
| 48 | + if y * 3 + x in block.shape(): |
| 49 | + if y + block.y + ny > rows - 1 or y + block.y + ny < 0: |
| 50 | + collision = True |
| 51 | + break |
| 52 | + if x + block.x > cols - 1 or x + block.x < 0: |
| 53 | + collision = True |
| 54 | + break |
| 55 | + if game_board[x + block.x][y + block.y + ny] != (0,0,0): |
| 56 | + collision = True |
| 57 | + break |
| 58 | + return collision |
| 59 | + |
| 60 | +def rotate(block,rows,cols,game_board): |
| 61 | + last_rotate = block.rotation |
| 62 | + block.rotation = (block.rotation + 1)%len(blocks[block.type]) |
| 63 | + can_rotate = True |
| 64 | + for y in range(3): |
| 65 | + for x in range(3): |
| 66 | + if y * 3 + x in block.shape(): |
| 67 | + if collides(block,rows,cols,game_board,ny=0): |
| 68 | + can_rotate = False |
| 69 | + if not can_rotate: |
| 70 | + block.rotation = last_rotate |
| 71 | + |
| 72 | + |
| 73 | +def drawGrid(screen,rows,cols,x_gap,y_gap,grid_size,game_board): |
| 74 | + for y in range(rows): |
| 75 | + for x in range(cols): |
| 76 | + pygame.draw.rect(screen,(100,100,100),[x * grid_size + x_gap,y * grid_size + y_gap,grid_size,grid_size],1) |
| 77 | + pygame.draw.rect(screen,game_board[x][y],[x * grid_size + x_gap + 1,y * grid_size + y_gap + 1,grid_size - 2,grid_size - 2]) |
| 78 | + |
| 79 | +def dropBlock(block,rows,cols,game_board): |
| 80 | + can_drop = True |
| 81 | + for y in range(3): |
| 82 | + for x in range(3): |
| 83 | + if y * 3 + x in block.shape(): |
| 84 | + if collides(block,rows,cols,game_board,ny=1): |
| 85 | + can_drop = False |
| 86 | + if can_drop: |
| 87 | + block.y += 1 |
| 88 | + else: |
| 89 | + for y in range(3): |
| 90 | + for x in range(3): |
| 91 | + if y * 3 + x in block.shape(): |
| 92 | + game_board[x + block.x][y + block.y] = block.colour |
| 93 | + return can_drop |
| 94 | + |
| 95 | + |
| 96 | +def sideMove(block,cols,dx): |
| 97 | + can_move = True |
| 98 | + for y in range(3): |
| 99 | + for x in range(3): |
| 100 | + if y * 3 + x in block.shape(): |
| 101 | + if block.x + x >= cols - 1 and dx == 1: |
| 102 | + can_move = False |
| 103 | + elif block.x + x < 1 and dx == -1: |
| 104 | + can_move = False |
| 105 | + if can_move: |
| 106 | + block.x += dx |
| 107 | + |
| 108 | +def findLines(rows,cols,game_board): |
| 109 | + lines = 0 |
| 110 | + for y in range(rows): |
| 111 | + empty = 0 |
| 112 | + for x in range(cols): |
| 113 | + if game_board[x][y] == (0,0,0): |
| 114 | + empty += 1 |
| 115 | + if empty == 0: |
| 116 | + lines += 1 |
| 117 | + for y2 in range(y,1,-1): |
| 118 | + for x2 in range(cols): |
| 119 | + game_board[x2][y2] = game_board[x2][y2 - 1] |
| 120 | + return lines |
| 121 | + |
| 122 | +def main(): |
| 123 | + screen = pygame.display.set_mode((300,600)) |
| 124 | + pygame.display.set_caption('Tetris') |
| 125 | + grid_size = 30 |
| 126 | + cols = screen.get_width() // grid_size |
| 127 | + rows = screen.get_height() // grid_size |
| 128 | + x_gap = (screen.get_width() - cols * grid_size) // 2 |
| 129 | + y_gap = (screen.get_height() - rows * grid_size) // 2 |
| 130 | + block = Block((cols - 1) // 2,0) |
| 131 | + game_over = False |
| 132 | + clock = pygame.time.Clock() |
| 133 | + fps = 8 |
| 134 | + |
| 135 | + #game board setting black color |
| 136 | + game_board = [] |
| 137 | + for i in range(cols): |
| 138 | + new_col = [] |
| 139 | + for j in range(rows): |
| 140 | + new_col.append((0,0,0)) |
| 141 | + game_board.append(new_col) |
| 142 | + |
| 143 | + score = 0 |
| 144 | + font = pygame.font.SysFont('Arial', 25, True) |
| 145 | + font_quit = pygame.font.SysFont('Arial', 50, True) |
| 146 | + finished_text = font_quit.render('Game Over', True, (255,255,255)) |
| 147 | + text_pos = [(screen.get_width() - finished_text.get_width())// 2, (screen.get_height() - finished_text.get_height()) // 2] |
| 148 | + game_finished = False |
| 149 | + while not game_over: |
| 150 | + clock.tick(fps) |
| 151 | + for event in pygame.event.get(): |
| 152 | + if event.type == pygame.QUIT: |
| 153 | + game_over = True |
| 154 | + if event.type == pygame.KEYDOWN: |
| 155 | + if event.key == pygame.K_UP: |
| 156 | + rotate(block,rows,cols,game_board) |
| 157 | + if event.type == pygame.KEYDOWN: |
| 158 | + if block is not None: |
| 159 | + if event.key == pygame.K_LEFT: |
| 160 | + sideMove(block,cols,-1) |
| 161 | + if event.key == pygame.K_RIGHT: |
| 162 | + sideMove(block,cols,1) |
| 163 | + |
| 164 | + screen.fill((0,0,0)) |
| 165 | + drawGrid(screen,rows,cols,x_gap,y_gap,grid_size,game_board) |
| 166 | + |
| 167 | + if block is not None: |
| 168 | + draw_block(screen, block, grid_size, x_gap, y_gap) |
| 169 | + if not dropBlock(block,rows,cols,game_board) and not game_finished: |
| 170 | + score += findLines(rows,cols,game_board) |
| 171 | + block = Block(random.randint(5,cols-5),0) |
| 172 | + if collides(block,rows,cols,game_board,ny=0): |
| 173 | + game_finished = True |
| 174 | + |
| 175 | + text = font.render("Score: " + str(score), True, (255,255,255)) |
| 176 | + screen.blit(text, [0,0]) |
| 177 | + if game_finished == True: |
| 178 | + screen.blit(finished_text,text_pos) |
| 179 | + pygame.display.update() |
| 180 | + |
| 181 | + pygame.quit() |
| 182 | + |
| 183 | +if __name__ == '__main__': |
| 184 | + main() |
0 commit comments