Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.72 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. # Very simple tetris implementation
  5. #
  6. # Control keys:
  7. # Down - Drop stone faster
  8. # Left/Right - Move stone
  9. # Up - Rotate Stone clockwise
  10. # Escape - Quit game
  11. # P - Pause game
  12. #
  13. # Have fun!
  14.  
  15. # Copyright (c) 2010 "Kevin Chabowski"<kevin@kch42.de>
  16. #
  17. # Permission is hereby granted, free of charge, to any person obtaining a copy
  18. # of this software and associated documentation files (the "Software"), to deal
  19. # in the Software without restriction, including without limitation the rights
  20. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  21. # copies of the Software, and to permit persons to whom the Software is
  22. # furnished to do so, subject to the following conditions:
  23. #
  24. # The above copyright notice and this permission notice shall be included in
  25. # all copies or substantial portions of the Software.
  26. #
  27. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  33. # THE SOFTWARE.
  34.  
  35. from random import randrange as rand
  36. import numpy as np
  37. import pygame, sys
  38. import copy
  39.  
  40. # The configuration
  41. config = {
  42. 'cell_size': 20,
  43. 'cols': 10,
  44. 'rows': 20,
  45. 'delay': 150,
  46. 'maxfps': 30
  47. }
  48.  
  49. colors = [
  50. (0, 0, 0),
  51. (255, 0, 0),
  52. (0, 150, 0),
  53. (0, 0, 255),
  54. (255, 120, 0),
  55. (255, 255, 0),
  56. (180, 0, 255),
  57. (0, 220, 220)
  58. ]
  59.  
  60. # Define the shapes of the single parts
  61. tetris_shapes = [
  62. [[1, 1, 1],
  63. [0, 1, 0]],
  64.  
  65. [[0, 2, 2],
  66. [2, 2, 0]],
  67.  
  68. [[3, 3, 0],
  69. [0, 3, 3]],
  70.  
  71. [[4, 0, 0],
  72. [4, 4, 4]],
  73.  
  74. [[0, 0, 5],
  75. [5, 5, 5]],
  76.  
  77. [[6, 6, 6, 6]],
  78.  
  79. [[7, 7],
  80. [7, 7]]
  81. ]
  82.  
  83. reward_scores = [
  84. 100,
  85. 300,
  86. 500,
  87. 800
  88. ]
  89.  
  90. def rotate_clockwise(shape):
  91. return np.rot90(shape,k=3)
  92.  
  93.  
  94. def check_collision(board, shape, offset):
  95. off_x, off_y = offset
  96. for cy, row in enumerate(shape):
  97. for cx, cell in enumerate(row):
  98. try:
  99. if cell and board[cy + off_y][cx + off_x]:
  100. return True
  101. except IndexError:
  102. return True
  103. return False
  104.  
  105.  
  106. def remove_row(board, row):
  107. del board[row]
  108. return [[0 for i in range(config['cols'])]] + board
  109.  
  110.  
  111. def join_matrixes(mat1, mat2, mat2_off):
  112. off_x, off_y = mat2_off
  113. for cy, row in enumerate(mat2):
  114. for cx, val in enumerate(row):
  115. mat1[cy + off_y - 1][cx + off_x] += val
  116. return mat1
  117.  
  118.  
  119. def new_board():
  120. board = [[0 for x in range(config['cols'])]
  121. for y in range(config['rows'])]
  122. board += [[1 for x in range(config['cols'])]]
  123. return board
  124.  
  125.  
  126. class TetrisApp(object):
  127. def __init__(self):
  128. pygame.init()
  129. pygame.key.set_repeat(250, 25)
  130. self.width = config['cell_size'] * config['cols'] + 200
  131. self.height = config['cell_size'] * config['rows']
  132.  
  133. self.stonebag = [i for i in range(len(tetris_shapes))] * 2
  134. self.current_stone = tetris_shapes[self.stonebag.pop(rand(len(self. stonebag)))]
  135. self.next_stone = tetris_shapes[self.stonebag.pop(rand(len(self. stonebag)))]
  136.  
  137. self.score = 0
  138. self.current_reward = 0
  139.  
  140. self.iteration = 0
  141.  
  142. self.screen = pygame.display.set_mode((self.width, self.height))
  143. pygame.event.set_blocked(pygame.MOUSEMOTION) # We do not need
  144. # mouse movement
  145. # events, so we
  146. # block them.
  147. self.init_game()
  148.  
  149. def new_stone(self):
  150. if not self.stonebag:
  151. self.stonebag = [i for i in range(len(tetris_shapes))] * 2
  152. self.current_stone = self.next_stone
  153. self.next_stone = tetris_shapes[self.stonebag.pop(rand(len(self.stonebag)))]
  154.  
  155. self.stone_x = int(config['cols'] / 2 - len(self.current_stone[0]) / 2)
  156. self.stone_y = 0
  157.  
  158. if check_collision(self.board,
  159. self.current_stone,
  160. (self.stone_x, self.stone_y)):
  161. self.gameover = True
  162.  
  163. def init_game(self):
  164. self.board = new_board()
  165. self.new_stone()
  166.  
  167. def center_msg(self, msg):
  168. for i, line in enumerate(msg.splitlines()):
  169. msg_image = pygame.font.Font(
  170. pygame.font.get_default_font(), 12).render(
  171. line, False, (255, 255, 255), (0, 0, 0))
  172.  
  173. msgim_center_x, msgim_center_y = msg_image.get_size()
  174. msgim_center_x //= 2
  175. msgim_center_y //= 2
  176.  
  177. self.screen.blit(msg_image, (
  178. self.width // 2 - msgim_center_x,
  179. self.height // 2 - msgim_center_y + i * 22))
  180.  
  181. def draw_matrix(self, matrix, offset):
  182. off_x, off_y = offset
  183. for y, row in enumerate(matrix):
  184. for x, val in enumerate(row):
  185. if val:
  186. pygame.draw.rect(
  187. self.screen,
  188. colors[val],
  189. pygame.Rect(
  190. (off_x + x) *
  191. (config['cell_size']),
  192. (off_y + y) *
  193. (config['cell_size']),
  194. (config['cell_size']),
  195. (config['cell_size'])), 0)
  196.  
  197. def move(self, delta_x):
  198. if not self.gameover and not self.paused:
  199. new_x = self.stone_x + delta_x
  200. if new_x < 0:
  201. new_x = 0
  202. if new_x > config['cols'] - len(self.current_stone[0]):
  203. new_x = config['cols'] - len(self.current_stone[0])
  204. if not check_collision(self.board,
  205. self.current_stone,
  206. (new_x, self.stone_y)):
  207. self.stone_x = new_x
  208.  
  209. def quit(self):
  210. self.center_msg("Exiting...")
  211. pygame.display.update()
  212. sys.exit()
  213.  
  214. def drop(self):
  215. if not self.gameover and not self.paused:
  216. self.stone_y += 1
  217. if check_collision(self.board,
  218. self.current_stone,
  219. (self.stone_x, self.stone_y)):
  220. self.board = join_matrixes(
  221. self.board,
  222. self.current_stone,
  223. (self.stone_x, self.stone_y))
  224. self.new_stone()
  225. combo = 0
  226. while True:
  227. for i, row in enumerate(self.board[:-1]):
  228. if 0 not in row:
  229. self.board = remove_row(
  230. self.board, i)
  231. combo += 1
  232. break
  233. else:
  234. break
  235. # give reward
  236. if combo != 0:
  237. self.score += reward_scores[combo - 1]
  238. self.current_reward = reward_scores[combo - 1]
  239.  
  240. def rotate_stone(self):
  241. if not self.gameover and not self.paused:
  242. new_stone = rotate_clockwise(self.current_stone)
  243. # if self.stone_x > config["cols"] - 3:
  244. for i in range(1, 4):
  245. if check_collision(self.board,
  246. new_stone,
  247. (self.stone_x, self.stone_y)) and not check_collision(self.board, new_stone, (
  248. self.stone_x - i, self.stone_y)):
  249. if self.stone_x - i >= 0:
  250. self.stone_x -= i
  251. self.current_stone = new_stone
  252. elif not check_collision(self.board,
  253. new_stone,
  254. (self.stone_x, self.stone_y)):
  255. self.current_stone = new_stone
  256.  
  257. def toggle_pause(self):
  258. self.paused = not self.paused
  259.  
  260. def start_game(self):
  261. if self.gameover:
  262. self.init_game()
  263. self.score = 0
  264. self.gameover = False
  265.  
  266. def get_state(self):
  267. state = []
  268. for row in self.board:
  269. for value in row:
  270. if value == 0:
  271. state += [0]
  272. else:
  273. state += [1]
  274.  
  275. for i, row in enumerate(self.current_stone):
  276. for j, column in enumerate(row):
  277. if column != 0:
  278. state[(self.stone_y + i) * config['cols'] + self.stone_x + j] = 0.5
  279. """
  280. print("## BOARD ##")
  281. for i, value in enumerate(state):
  282. if (i + 1) % config['cols'] == 0:
  283. print(value)
  284. else:
  285. print(value, end="")
  286. """
  287. return state
  288.  
  289. def run(self):
  290. key_actions = {
  291. 'ESCAPE': self.quit,
  292. 'LEFT': lambda: self.move(-1),
  293. 'RIGHT': lambda: self.move(+1),
  294. 'DOWN': self.drop,
  295. 'UP': self.rotate_stone,
  296. 'p': self.toggle_pause,
  297. 'SPACE': self.start_game
  298. }
  299.  
  300. self.gameover = False
  301. self.paused = False
  302.  
  303. pygame.time.set_timer(pygame.USEREVENT + 1, config['delay'])
  304. dont_burn_my_cpu = pygame.time.Clock()
  305. while 1:
  306. if self.iteration % 100 == 0:
  307. dont_burn_my_cpu.tick(config['maxfps'])
  308. self.screen.fill((0, 0, 0))
  309. if self.gameover:
  310. self.center_msg("Game Over!")
  311. else:
  312. if self.paused:
  313. self.center_msg("Paused")
  314. else:
  315. self.draw_matrix(self.board, (0, 0))
  316. self.draw_matrix(self.current_stone,
  317. (self.stone_x,
  318. self.stone_y))
  319. pygame.draw.rect(self.screen, (98,103,108), pygame.Rect(self.width-200, 0, 200, self.height), 0)
  320. myfont = pygame.font.SysFont('Comic Sans MS', 16)
  321. textsurface = myfont.render("Score: "+str(self.score), False, (240, 240, 240))
  322. self.screen.blit(textsurface, (self.width-190, 10))
  323.  
  324. textsurface = myfont.render("Iteration: "+str(self.iteration), False, (240, 240, 240))
  325. self.screen.blit(textsurface, (self.width-190, 40))
  326. pygame.display.update()
  327.  
  328.  
  329. for event in pygame.event.get():
  330. if event.type == pygame.USEREVENT + 1:
  331. self.drop()
  332. elif event.type == pygame.QUIT:
  333. self.quit()
  334. elif event.type == pygame.KEYDOWN:
  335. for key in key_actions:
  336. if event.key == eval("pygame.K_"
  337. + key):
  338. key_actions[key]()
  339. else:
  340. dont_burn_my_cpu.tick(300000000000)
  341.  
  342. s = self.get_state()
  343. a = rand(0, 4)
  344.  
  345. actions = ['LEFT', 'RIGHT', 'DOWN', 'UP']
  346. key_actions[actions[a]]()
  347.  
  348. r = self.current_reward
  349. self.current_reward = 0
  350.  
  351. if self.gameover:
  352. self.iteration += 1
  353. self.start_game()
  354.  
  355. #print(s,a,r,sep="\n")
  356.  
  357.  
  358. if __name__ == '__main__':
  359. App = TetrisApp()
  360. App.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement