refactoring, bug fix, optimization

master
Artem 2017-07-01 22:40:10 +01:00
parent 80964680ea
commit 9d02cb51b5
2 changed files with 59 additions and 34 deletions

View File

@ -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])]

View File

@ -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()