competitive_tetris.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #!/usr/bin/python3
  2. """
  3. Competitive tetris server
  4. """
  5. import random
  6. import pygame
  7. import shapes
  8. pygame.font.init()
  9. # GLOBALS VARS
  10. S_WIDTH = 800
  11. S_HEIGHT = 700
  12. PLAY_WIDTH = 300 # meaning 300 // 10 = 30 width per block
  13. PLAY_HEIGHT = 600 # meaning 600 // 20 = 30 height per block
  14. BLOCK_SIZE = 30
  15. TOP_LEFT_X = (S_WIDTH - PLAY_WIDTH) // 2
  16. TOP_LEFT_Y = S_HEIGHT - PLAY_HEIGHT
  17. # SHAPE FORMATS
  18. # index 0 - 6 represent shape
  19. class Piece:
  20. def __init__(self, x, y, shape):
  21. self.x = x
  22. self.y = y
  23. self.shape = shape
  24. self.color = shapes.SHAPE_COLORS[shapes.SHAPES.index(shape)]
  25. self.rotation = 0
  26. def create_grid(locked_pos={}):
  27. grid = [[(0,0,0) for _ in range(10)] for _ in range(20)]
  28. for i in range(len(grid)):
  29. for j in range(len(grid[i])):
  30. if (j, i) in locked_pos:
  31. c = locked_pos[(j,i)]
  32. grid[i][j] = c
  33. return grid
  34. def convert_shape_format(shape):
  35. positions = []
  36. format = shape.shape[shape.rotation % len(shape.shape)]
  37. for i, line in enumerate(format):
  38. row = list(line)
  39. for j, column in enumerate(row):
  40. if column == '0':
  41. positions.append((shape.x + j, shape.y + i))
  42. return positions
  43. def valid_space(shape, grid):
  44. accepted_pos = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)]
  45. accepted_pos = [j for sub in accepted_pos for j in sub]
  46. formatted = convert_shape_format(shape)
  47. for pos in formatted:
  48. if pos not in accepted_pos:
  49. if pos[1] > -1:
  50. return False
  51. return True
  52. def check_lost(positions):
  53. for pos in positions:
  54. x, y = pos
  55. if y < 1:
  56. return True
  57. return False
  58. def get_shape():
  59. return Piece(0, 0, random.choice(shapes.SHAPES))
  60. def draw_text_middle(surface, text, size, color):
  61. font = pygame.font.SysFont("comicsans", size, bold=True)
  62. label = font.render(text, 1, color)
  63. surface.blit(label, (TOP_LEFT_X + PLAY_WIDTH /2 - (label.get_width()/2), TOP_LEFT_Y + PLAY_HEIGHT/2 - label.get_height()/2))
  64. def draw_grid(surface, grid):
  65. sx = TOP_LEFT_X
  66. sy = TOP_LEFT_Y
  67. for i in range(len(grid)):
  68. pygame.draw.line(surface, (128,128,128), (sx, sy + i*BLOCK_SIZE), (sx+PLAY_WIDTH, sy+ i*BLOCK_SIZE))
  69. for j in range(len(grid[i])):
  70. pygame.draw.line(surface, (128, 128, 128), (sx + j*BLOCK_SIZE, sy),(sx + j*BLOCK_SIZE, sy + PLAY_HEIGHT))
  71. def clear_rows(grid, locked):
  72. inc = 0
  73. for i in range(len(grid)-1, -1, -1):
  74. row = grid[i]
  75. if (0,0,0) not in row:
  76. inc += 1
  77. ind = i
  78. for j in range(len(row)):
  79. try:
  80. del locked[(j,i)]
  81. except:
  82. continue
  83. if inc > 0:
  84. for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
  85. x, y = key
  86. if y < ind:
  87. newKey = (x, y + inc)
  88. locked[newKey] = locked.pop(key)
  89. return inc
  90. def draw_next_shape(shape, surface):
  91. font = pygame.font.SysFont('comicsans', 30)
  92. label = font.render('Next Shape', 1, (255,255,255))
  93. sx = TOP_LEFT_X + PLAY_WIDTH + 0
  94. sy = TOP_LEFT_Y + PLAY_HEIGHT/2 - 100
  95. format = shape.shape[shape.rotation % len(shape.shape)]
  96. for i, line in enumerate(format):
  97. row = list(line)
  98. for j, column in enumerate(row):
  99. if column == '0':
  100. pygame.draw.rect(surface, shape.color, (sx + j*BLOCK_SIZE, sy + i*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
  101. surface.blit(label, (sx + 10, sy - 30))
  102. def update_score(nscore):
  103. score = max_score()
  104. with open('scores.txt', 'w') as f:
  105. if int(score) > nscore:
  106. f.write(str(score))
  107. else:
  108. f.write(str(nscore))
  109. def max_score():
  110. with open('scores.txt', 'r') as f:
  111. lines = f.readlines()
  112. score = lines[0].strip()
  113. return score
  114. def draw_window(surface, grid, score=0, last_score = 0):
  115. surface.fill((0, 0, 0))
  116. pygame.font.init()
  117. font = pygame.font.SysFont('comicsans', 60)
  118. label = font.render('Tetris', 1, (255, 255, 255))
  119. surface.blit(label, (TOP_LEFT_X + PLAY_WIDTH / 2 - (label.get_width() / 2), 30))
  120. # current score
  121. font = pygame.font.SysFont('comicsans', 30)
  122. label = font.render('Score: ' + str(score), 1, (255,255,255))
  123. sx = TOP_LEFT_X + PLAY_WIDTH + 50
  124. sy = TOP_LEFT_Y + PLAY_HEIGHT/2 - 100
  125. surface.blit(label, (sx + 20, sy + 160))
  126. # last score
  127. label = font.render('High Score: ' + last_score, 1, (255,255,255))
  128. sx = TOP_LEFT_X - 200
  129. sy = TOP_LEFT_Y + 200
  130. surface.blit(label, (sx + 20, sy + 160))
  131. for i in range(len(grid)):
  132. for j in range(len(grid[i])):
  133. pygame.draw.rect(surface, grid[i][j], (TOP_LEFT_X + j*BLOCK_SIZE, TOP_LEFT_Y + i*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
  134. pygame.draw.rect(surface, (255, 0, 0), (TOP_LEFT_X, TOP_LEFT_Y, PLAY_WIDTH, PLAY_HEIGHT), 5)
  135. draw_grid(surface, grid)
  136. #pygame.display.update()
  137. def main(win): # *
  138. last_score = max_score()
  139. locked_positions = {}
  140. grid = create_grid(locked_positions)
  141. change_piece = False
  142. run = True
  143. current_piece = get_shape()
  144. current_piece.y = -4
  145. current_piece.x = 0
  146. next_piece = get_shape()
  147. clock = pygame.time.Clock()
  148. fall_time = 0
  149. fall_speed = 0.27
  150. level_time = 0
  151. score = 0
  152. while run:
  153. grid = create_grid(locked_positions)
  154. fall_time += clock.get_rawtime()
  155. level_time += clock.get_rawtime()
  156. clock.tick()
  157. if level_time/1000 > 5:
  158. level_time = 0
  159. if level_time > 0.12:
  160. level_time -= 0.005
  161. if fall_time/1000 > fall_speed:
  162. fall_time = 0
  163. current_piece.y += 1
  164. if not(valid_space(current_piece, grid)) and current_piece.y > 0:
  165. current_piece.y -= 1
  166. change_piece = True
  167. for event in pygame.event.get():
  168. if event.type == pygame.QUIT:
  169. run = False
  170. pygame.display.quit()
  171. if event.type == pygame.KEYDOWN:
  172. if event.key == pygame.K_LEFT:
  173. current_piece.x -= 1
  174. if not(valid_space(current_piece, grid)):
  175. current_piece.x += 1
  176. if event.key == pygame.K_RIGHT:
  177. current_piece.x += 1
  178. if not(valid_space(current_piece, grid)):
  179. current_piece.x -= 1
  180. if event.key == pygame.K_DOWN:
  181. current_piece.y += 1
  182. if not(valid_space(current_piece, grid)):
  183. current_piece.y -= 1
  184. if event.key == pygame.K_UP:
  185. current_piece.rotation += 1
  186. if not(valid_space(current_piece, grid)):
  187. current_piece.rotation -= 1
  188. shape_pos = convert_shape_format(current_piece)
  189. for i in range(len(shape_pos)):
  190. x, y = shape_pos[i]
  191. if y > -1:
  192. grid[y][x] = current_piece.color
  193. if change_piece:
  194. for pos in shape_pos:
  195. p = (pos[0], pos[1])
  196. locked_positions[p] = current_piece.color
  197. current_piece = next_piece
  198. current_piece.x = 0
  199. current_piece.y = -4
  200. next_piece = get_shape()
  201. change_piece = False
  202. score += clear_rows(grid, locked_positions) * 10
  203. draw_window(win, grid, score, last_score)
  204. draw_next_shape(next_piece, win)
  205. pygame.display.update()
  206. if check_lost(locked_positions):
  207. draw_text_middle(win, "YOU LOST!", 80, (255,255,255))
  208. pygame.display.update()
  209. pygame.time.delay(1500)
  210. run = False
  211. update_score(score)
  212. def main_menu(win): # *
  213. run = True
  214. while run:
  215. win.fill((0,0,0))
  216. draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
  217. pygame.display.update()
  218. for event in pygame.event.get():
  219. if event.type == pygame.QUIT:
  220. run = False
  221. if event.type == pygame.KEYDOWN:
  222. main(win)
  223. pygame.display.quit()
  224. win = pygame.display.set_mode((S_WIDTH, S_HEIGHT))
  225. pygame.display.set_caption('Tetris')
  226. main_menu(win)