game.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import collections
  2. import numpy as np
  3. import tetrominos
  4. FIELD_WIDTH = 10
  5. FIELD_HEIGHT = 20
  6. COMMAND_NONE = 0
  7. COMMAND_LEFT = 1
  8. COMMAND_RIGHT = 2
  9. COMMAND_ROTATE = 3
  10. def tetromino_to_field_at(tetromino, row, col):
  11. col_offset = col + tetromino.col_offset
  12. row_offset = row + tetromino.row_offset
  13. if col_offset < 0 or row_offset < 0:
  14. return None
  15. if col_offset + tetromino.data.shape[1] > FIELD_WIDTH:
  16. return None
  17. if row_offset + tetromino.data.shape[0] > FIELD_HEIGHT:
  18. return None
  19. array = tetromino.data
  20. left_zeros = np.zeros(shape=(array.shape[0], col_offset),
  21. dtype=np.int32, order="C")
  22. right_zeros = np.zeros(shape=(array.shape[0],
  23. FIELD_WIDTH-col_offset-array.shape[1]),
  24. dtype=np.int32, order="C")
  25. array = np.concatenate((left_zeros, array, right_zeros), axis=1)
  26. top_zeros = np.zeros(shape=(row_offset,FIELD_WIDTH),
  27. dtype=np.int32, order="C")
  28. bottom_zeros = np.zeros(shape=(FIELD_HEIGHT - row_offset - array.shape[0],
  29. FIELD_WIDTH),
  30. dtype=np.int32, order="C")
  31. array = np.concatenate((top_zeros, array, bottom_zeros), axis=0)
  32. return array
  33. GameState = collections.namedtuple('GameState',
  34. ['grid', 'current_piece', 'next_piece',
  35. 'rotation', 'row', 'col'])
  36. def initial_game_state(current_piece, next_piece):
  37. return GameState(grid=np.zeros(shape=(FIELD_HEIGHT,FIELD_WIDTH),
  38. dtype=np.int32, order="C"),
  39. current_piece=current_piece,
  40. next_piece=next_piece,
  41. rotation=0, row=0, col=0)
  42. def is_game_state_valid(game_state):
  43. tetromino_array = tetromino_to_field_at(
  44. tetrominos.SHAPES[game_state.current_piece][game_state.rotation],
  45. game_state.row, game_state.col)
  46. if tetromino_array is None:
  47. return False
  48. total_field = np.add(game_state.grid, tetromino_array)
  49. if np.any(np.vectorize(lambda x: x > 1)(total_field)):
  50. return False
  51. return True
  52. def game_state_field(game_state):
  53. tetromino_array = tetromino_to_field_at(
  54. tetrominos.SHAPES[game_state.current_piece][game_state.rotation],
  55. game_state.row, game_state.col)
  56. total_field = np.add(game_state.grid, tetromino_array)
  57. total_field = np.add(total_field, tetromino_array)
  58. return total_field
  59. def advance_game_state_shift(game_state, col_offset):
  60. next_game_state = GameState(grid=game_state.grid,
  61. current_piece=game_state.current_piece,
  62. next_piece=game_state.next_piece,
  63. rotation=game_state.rotation,
  64. row=game_state.row,
  65. col=game_state.col + col_offset)
  66. if is_game_state_valid(next_game_state):
  67. return next_game_state
  68. return None
  69. def advance_game_state_rotate(game_state):
  70. next_game_state = GameState(grid=game_state.grid,
  71. current_piece=game_state.current_piece,
  72. next_piece=game_state.next_piece,
  73. rotation=(game_state.rotation + 1) % 4,
  74. row=game_state.row,
  75. col=game_state.col)
  76. if is_game_state_valid(next_game_state):
  77. return next_game_state
  78. return None
  79. def advance_game_state_down(game_state):
  80. next_game_state = GameState(grid=game_state.grid,
  81. current_piece=game_state.current_piece,
  82. next_piece=game_state.next_piece,
  83. rotation=game_state.rotation,
  84. row=game_state.row + 1,
  85. col=game_state.col)
  86. if is_game_state_valid(next_game_state):
  87. return next_game_state
  88. return None
  89. def advance_game_state_piece(game_state, next_piece):
  90. tetromino_array = tetromino_to_field_at(
  91. tetrominos.SHAPES[game_state.current_piece][game_state.rotation],
  92. game_state.row, game_state.col)
  93. next_grid = np.add(game_state.grid, tetromino_array)
  94. next_game_state = GameState(grid=next_grid,
  95. current_piece=game_state.next_piece,
  96. next_piece=next_piece,
  97. rotation=0, row=0, col=0)
  98. return next_game_state
  99. def advance_game_state(game_state, command):
  100. command_game_state = None
  101. if command == COMMAND_LEFT:
  102. command_game_state = advance_game_state_shift(game_state, -1)
  103. elif command == COMMAND_RIGHT:
  104. command_game_state = advance_game_state_shift(game_state, 1)
  105. elif command == COMMAND_ROTATE:
  106. command_game_state = advance_game_state_rotate(game_state)
  107. if command_game_state is None:
  108. command_game_state = game_state
  109. next_game_state = advance_game_state_down(command_game_state)
  110. if next_game_state is None:
  111. next_game_state = advance_game_state_piece(command_game_state, 0)
  112. return next_game_state