refactoring, bug fix, optimization
parent
80964680ea
commit
9d02cb51b5
67
board.py
67
board.py
|
@ -125,6 +125,12 @@ class Board:
|
|||
|
||||
return self.game_over
|
||||
|
||||
def rotate_block(self):
|
||||
rotated_shape = list(map(list, zip(*self.current_block.shape[::-1])))
|
||||
|
||||
if self._can_move(self.current_block_pos, rotated_shape):
|
||||
self.current_block.shape = rotated_shape
|
||||
|
||||
def move_block(self, direction):
|
||||
"""Try to move block"""
|
||||
|
||||
|
@ -138,7 +144,7 @@ class Board:
|
|||
else:
|
||||
raise ValueError("wrong directions")
|
||||
|
||||
if self._can_move(new_pos):
|
||||
if self._can_move(new_pos, self.current_block.shape):
|
||||
self.current_block_pos = new_pos
|
||||
elif direction == "down":
|
||||
self._land_block()
|
||||
|
@ -149,7 +155,7 @@ class Board:
|
|||
"""Move to very very bottom"""
|
||||
|
||||
i = 1
|
||||
while self._can_move((self.current_block_pos[0] + 1, self.current_block_pos[1])):
|
||||
while self._can_move((self.current_block_pos[0] + 1, self.current_block_pos[1]), self.current_block.shape):
|
||||
i += 1
|
||||
self.move_block("down")
|
||||
|
||||
|
@ -172,10 +178,11 @@ class Board:
|
|||
self.current_block = self.next_block
|
||||
self.next_block = self._get_new_block()
|
||||
|
||||
col_pos = math.floor((self.width - self.current_block.size[1]) / 2)
|
||||
size = Block.get_size(self.current_block.shape)
|
||||
col_pos = math.floor((self.width - size[1]) / 2)
|
||||
self.current_block_pos = [0, col_pos]
|
||||
|
||||
if self._check_overlapping(self.current_block_pos):
|
||||
if self._check_overlapping(self.current_block_pos, self.current_block.shape):
|
||||
self.game_over = True
|
||||
self._save_best_score()
|
||||
else:
|
||||
|
@ -184,8 +191,9 @@ class Board:
|
|||
def _land_block(self):
|
||||
"""Put block to the board and generate a new one"""
|
||||
|
||||
for row in range(self.current_block.size[0]):
|
||||
for col in range(self.current_block.size[1]):
|
||||
size = Block.get_size(self.current_block.shape)
|
||||
for row in range(size[0]):
|
||||
for col in range(size[1]):
|
||||
if self.current_block.shape[row][col] == 1:
|
||||
self.board[self.current_block_pos[0] + row][self.current_block_pos[1] + col] = 1
|
||||
|
||||
|
@ -202,24 +210,26 @@ class Board:
|
|||
if self.lines % 10 == 0:
|
||||
self.level += 1
|
||||
|
||||
def _check_overlapping(self, pos):
|
||||
def _check_overlapping(self, pos, shape):
|
||||
"""If current block overlaps any other on the board"""
|
||||
|
||||
for row in range(self.current_block.size[0]):
|
||||
for col in range(self.current_block.size[1]):
|
||||
if self.current_block.shape[row][col] == 1:
|
||||
size = Block.get_size(shape)
|
||||
for row in range(size[0]):
|
||||
for col in range(size[1]):
|
||||
if shape[row][col] == 1:
|
||||
if self.board[pos[0] + row][pos[1] + col] == 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _can_move(self, pos):
|
||||
def _can_move(self, pos, shape):
|
||||
"""Check if move is possible"""
|
||||
|
||||
if pos[1] < 0 or pos[1] + self.current_block.size[1] > self.width \
|
||||
or pos[0] + self.current_block.size[0] > self.height:
|
||||
size = Block.get_size(shape)
|
||||
if pos[1] < 0 or pos[1] + size[1] > self.width \
|
||||
or pos[0] + size[0] > self.height:
|
||||
return False
|
||||
|
||||
return not self._check_overlapping(pos)
|
||||
return not self._check_overlapping(pos, shape)
|
||||
|
||||
def _save_best_score(self):
|
||||
"""Save best score to file"""
|
||||
|
@ -241,7 +251,13 @@ class Board:
|
|||
def _get_new_block():
|
||||
"""Get random block"""
|
||||
|
||||
return Block(random.randint(0, len(block_shapes) - 1))
|
||||
block = Block(random.randint(0, len(block_shapes) - 1))
|
||||
|
||||
# flip it randomly
|
||||
if random.getrandbits(1):
|
||||
block.flip()
|
||||
|
||||
return block
|
||||
|
||||
|
||||
class Block:
|
||||
|
@ -250,15 +266,20 @@ class Block:
|
|||
def __init__(self, block_type):
|
||||
self.shape = block_shapes[block_type]
|
||||
self.color = block_type + 1
|
||||
self.size = self._get_size()
|
||||
|
||||
def rotate(self):
|
||||
"""Every time rotate clockwise 90"""
|
||||
def flip(self):
|
||||
self.shape = list(map(list, self.shape[::-1]))
|
||||
|
||||
self.shape = list(map(list, zip(*self.shape[::-1])))
|
||||
self.size = self._get_size()
|
||||
def _get_rotated(self):
|
||||
return list(map(list, zip(*self.shape[::-1])))
|
||||
|
||||
def _get_size(self):
|
||||
"""Get size of block"""
|
||||
def size(self):
|
||||
"""Get size of the block"""
|
||||
|
||||
return [len(self.shape), len(self.shape[0])]
|
||||
return self.get_size(self.shape)
|
||||
|
||||
@staticmethod
|
||||
def get_size(shape):
|
||||
"""Get size of a shape"""
|
||||
|
||||
return [len(shape), len(shape[0])]
|
||||
|
|
26
tetris.py
26
tetris.py
|
@ -78,8 +78,8 @@ def draw_game_window(window):
|
|||
window.addstr(a + 1, 2 * b + 1, " .", curses.color_pair(99))
|
||||
|
||||
# draw current block
|
||||
for a in range(game_board.current_block.size[0]):
|
||||
for b in range(game_board.current_block.size[1]):
|
||||
for a in range(game_board.current_block.size()[0]):
|
||||
for b in range(game_board.current_block.size()[1]):
|
||||
if game_board.current_block.shape[a][b] == 1:
|
||||
x = 2 * game_board.current_block_pos[1] + 2 * b + 1
|
||||
y = game_board.current_block_pos[0] + a + 1
|
||||
|
@ -111,16 +111,16 @@ def draw_status_window(window):
|
|||
window.addstr(row, 2, "".rjust(STATUS_WINDOW_WIDTH - 3, " "))
|
||||
|
||||
window.border()
|
||||
|
||||
window.addstr(1, 2, f"Score: {game_board.score}")
|
||||
import random
|
||||
window.addstr(1, 2, f"Score: {game_board.score} {random.randint(1,10)}")
|
||||
window.addstr(2, 2, f"Lines: {game_board.lines}")
|
||||
window.addstr(3, 2, f"Level: {game_board.level}")
|
||||
window.addstr(4, 2, f"Best Score:{game_board.best_score}")
|
||||
|
||||
start_col = int(STATUS_WINDOW_WIDTH / 2 - game_board.next_block.size[1])
|
||||
start_col = int(STATUS_WINDOW_WIDTH / 2 - game_board.next_block.size()[1])
|
||||
|
||||
for row in range(game_board.next_block.size[0]):
|
||||
for col in range(game_board.next_block.size[1]):
|
||||
for row in range(game_board.next_block.size()[0]):
|
||||
for col in range(game_board.next_block.size()[1]):
|
||||
if game_board.next_block.shape[row][col] == 1:
|
||||
window.addstr(6 + row, start_col + 2 * col, " ", curses.color_pair(game_board.next_block.color))
|
||||
|
||||
|
@ -170,12 +170,13 @@ def draw_footer():
|
|||
|
||||
window.refresh()
|
||||
|
||||
|
||||
pause = False
|
||||
|
||||
game_board = board.Board(BOARD_HEIGHT, BOARD_WIDTH)
|
||||
game_board.start()
|
||||
|
||||
old_score = game_board.score
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
scr = curses.initscr()
|
||||
|
@ -195,11 +196,11 @@ if __name__ == "__main__":
|
|||
status_window = init_status_window()
|
||||
|
||||
draw_game_window(game_window)
|
||||
draw_status_window(status_window)
|
||||
|
||||
start = time.time()
|
||||
|
||||
quit_game = False
|
||||
|
||||
while not quit_game:
|
||||
key_event = game_window.getch()
|
||||
|
||||
|
@ -213,7 +214,7 @@ if __name__ == "__main__":
|
|||
start = time.time()
|
||||
|
||||
if key_event == curses.KEY_UP:
|
||||
game_board.current_block.rotate()
|
||||
game_board.rotate_block()
|
||||
elif key_event == curses.KEY_DOWN:
|
||||
game_board.move_block("down")
|
||||
elif key_event == curses.KEY_LEFT:
|
||||
|
@ -233,6 +234,9 @@ if __name__ == "__main__":
|
|||
game_window.nodelay(True)
|
||||
|
||||
draw_game_window(game_window)
|
||||
draw_status_window(status_window)
|
||||
|
||||
if old_score != game_board.score:
|
||||
draw_status_window(status_window)
|
||||
old_score = game_board.score
|
||||
finally:
|
||||
curses.endwin()
|
||||
|
|
Loading…
Reference in New Issue