fork download
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import curses
  5. import locale
  6. import random
  7. import time
  8. import copy
  9.  
  10. width, height, offx, offy = 20, 24, 18, 0
  11. colors = ('CYAN', 'BLUE', 'WHITE', # foreground, background, wall
  12. 'RED', 'GREEN', 'RED', 'GREEN', 'MAGENTA', 'YELLOW', 'CYAN', 'BLACK') # block
  13. blocklist = (
  14. ((1, 1), ('** ', ' **')), ((1, 1), (' **', '** ')),
  15. ((1, 2), (' *', '***')), ((0, 2), ('***', ' *')),
  16. ((0, 2), ('****')), ((1, 1), (' * ', '***')), ((1, 1), ('**', '**')))
  17. blocks = []
  18. scrmap = [[0 for i in xrange(width)] for j in xrange(height)]
  19.  
  20. def makecoords(bl):
  21. r = []
  22. for k, (o, b) in enumerate(bl):
  23. if not isinstance(b, tuple): b = (b, )
  24. p = []
  25. for j, s in enumerate(b):
  26. for i, c in enumerate(s):
  27. if c == '*': p.append([j - o[0], i - o[1]])
  28. r.append(p)
  29. return r
  30.  
  31. def showblock(y, x, b, n):
  32. for p in b: scrmap[y + p[0]][x + p[1]] = 2 + n
  33. return y, x
  34.  
  35. def hideblock(y, x, b):
  36. showblock(y, x, b, -2)
  37.  
  38. def checkspace(y, x, b):
  39. for p in b:
  40. ny, nx = y + p[0], x + p[1]
  41. if ny < 0 or ny >= height - 1 or nx <= 0 or nx >= width - 1: return False
  42. if scrmap[ny][nx]: return False
  43. return True
  44.  
  45. def rotateblock(y, x, b, n, r):
  46. if n == len(blocks) - 1: return
  47. hideblock(y, x, b)
  48. for i in xrange(len(b)): b[i] = [r * b[i][1], -r * b[i][0]]
  49. if not checkspace(y, x, b):
  50. for i in xrange(len(b)): b[i] = [-r * b[i][1], r * b[i][0]]
  51. showblock(y, x, b, n)
  52.  
  53. def moveblock(y, x, b, n, dy, dx):
  54. hideblock(y, x, b)
  55. ny, nx = y + dy, x + dx
  56. if not checkspace(ny, nx, b): return showblock(y, x, b, n)
  57. return showblock(ny, nx, b, n)
  58.  
  59. def deleteblocks():
  60. for j in xrange(height - 1):
  61. for i in xrange(1, width - 1):
  62. if not scrmap[j][i]: break
  63. else:
  64. for y in xrange(j, 0, -1):
  65. for x in xrange(1, width - 1):
  66. scrmap[y][x] = scrmap[y - 1][x]
  67.  
  68. def display(v):
  69. for j in xrange(height):
  70. for i in xrange(width):
  71. v.addstr(j, i * 2, ' ', curses.color_pair(scrmap[j][i] + 1))
  72. t = time.time()
  73. v.addstr(0, 8,
  74. '%s.%03d' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)),
  75. int(t * 1000) % 1000),
  76. curses.color_pair(1))
  77. v.refresh(0, 0, offy, offx, offy + height, offx + width * 2)
  78.  
  79. def main(stdscr):
  80. locale.setlocale(locale.LC_ALL, '')
  81. enc = locale.getpreferredencoding()
  82. w = curses.initscr()
  83. curses.curs_set(0)
  84. curses.noecho()
  85. w.keypad(1)
  86. curses.cbreak()
  87. curses.start_color()
  88. for i, c in enumerate(colors):
  89. if i: curses.init_pair(i, getattr(curses, 'COLOR_%s' % colors[0]) + 8,
  90. getattr(curses, 'COLOR_%s' % c) + (0 if i == 1 else 8))
  91. v = curses.newpad(height + 1, (width + 1) * 2) # double buffering
  92. v.keypad(1)
  93. blocks = makecoords(blocklist)
  94. for j in xrange(height):
  95. if j < height - 1:
  96. scrmap[j][0] = scrmap[j][width - 1] = 1
  97. else:
  98. for i in xrange(width): scrmap[j][i] = 1
  99. random.seed()
  100. speed, tp, stat, y, x, n, b = 0.5, 0, 0, 3, 10, -1, []
  101. while True:
  102. curses.flushinp() # clear key buffer
  103. if stat == 0:
  104. stat = 1
  105. y, x = 3, 10
  106. n = random.randint(0, len(blocks) - 1)
  107. b = copy.deepcopy(blocks[n])
  108. if not checkspace(y, x, b):
  109. stat = -1
  110. for j in xrange(height - 1):
  111. for i in xrange(1, width - 1):
  112. if scrmap[j][i]: scrmap[j][i] = 9
  113. showblock(y, x, b, n)
  114. tp = time.time()
  115. elif stat == 1:
  116. if time.time() - tp >= speed:
  117. ny, nx = moveblock(y, x, b, n, 1, 0)
  118. if ny != y: y, x = ny, nx
  119. else: stat = 2
  120. tp = time.time()
  121. elif stat == 2:
  122. if time.time() - tp >= speed:
  123. ny, nx = moveblock(y, x, b, n, 1, 0)
  124. if ny != y:
  125. stat = 1
  126. y, x = ny, nx
  127. else:
  128. stat = 0
  129. deleteblocks()
  130. tp = time.time()
  131. else: break
  132. display(v)
  133. v.timeout(50)
  134. c = v.getch()
  135. if c == -1: pass
  136. elif c == ord('q'): break
  137. elif c == ord('z'): rotateblock(y, x, b, n, -1) # counter clockwise
  138. elif c == ord('x'): rotateblock(y, x, b, n, 1) # clockwise
  139. elif c == curses.KEY_UP: rotateblock(y, x, b, n, 1) # clockwise
  140. elif c == curses.KEY_LEFT: y, x = moveblock(y, x, b, n, 0, -1)
  141. elif c == curses.KEY_RIGHT: y, x = moveblock(y, x, b, n, 0, 1)
  142. elif c == curses.KEY_DOWN: y, x = moveblock(y, x, b, n, 1, 0)
  143. elif c == ord(' '): y, x = moveblock(y, x, b, n, 3, 0)
  144. else: pass
  145. v.keypad(0)
  146. curses.nocbreak()
  147. w.keypad(0)
  148. curses.echo()
  149. curses.curs_set(1)
  150. curses.endwin()
  151.  
  152. if __name__ == '__main__':
  153. curses.wrapper(main)
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty