def draw_score(self, score): stddraw.setPenColor(self.boundary_color) # using boundary_color # set the pen radius stddraw.setPenRadius(self.box_thickness) # coordinates of the bottom left corner of the game grid pos_x, pos_y = self.grid_width - 0.5, -0.5 stddraw.rectangle(pos_x, pos_y, 3.5, self.grid_height) stddraw.setPenColor(Color(167, 160, 151)) stddraw.filledRectangle(pos_x + 0.03, pos_y + 0.09, 3.4, self.grid_height - 0.2) # set the text text_color = Color(0, 0, 0) stddraw.setFontFamily("Arial") stddraw.setFontSize(30) stddraw.setPenColor(text_color) text_to_display = "SCORE" text_to_display2 = "NEXT" stddraw.text(12 + 1.2, 5, text_to_display2) stddraw.text(self.grid_width + 1.2, 15, text_to_display) stddraw.text(self.grid_width + 1.2, 14, str(score)) # get the tetromino's type to create next tetromino to show in the next section tet_type = self.current_tetromino.get_type() if tet_type == 'I': width = 4 height = 11 elif tet_type == 'O': width = 2 height = 12 else: width = 3 height = 11 next_tetromino = Tetromino(tet_type, height, width) next_tetromino.draw_next_tet(self.current_tetromino) stddraw.setPenRadius() # reset the pen radius to its default value
def compute_moves_available(self, grid, tetromino): heights = self.compute_heightmap(grid) possible_moves = [] # consider each rotation for rotation in tetromino.unique_rotations_list: # to compute each possible drop placement, first find the largest value # in the heightmap that contains the tetromino at each section of columns current_tmino = Tetromino(tetromino.id, rotation) for i in range(current_tmino.min_x, current_tmino.max_x + 1): current_tmino.x_pos = i # find greatest height greatest_height = 0 for j in range(i, i + current_tmino.size): # check for out of bounds if j >= 0 and j < len(grid): if heights[j] > greatest_height: greatest_height = heights[j] # we are guaranteed that the tetromino will not have collided with # anything before this greatest height value, all that is needed # to do now is to find the correct point of contact for j in range( max( len(grid[0]) - greatest_height - current_tmino.size, current_tmino.min_y), current_tmino.max_y + 1): current_tmino.y_pos = j if is_colliding(grid, current_tmino): current_tmino.y_pos = j - 1 break if not is_colliding(grid, current_tmino): # tetromino is now at a possible placement possible_moves.append( (rotation, current_tmino.x_pos, current_tmino.y_pos)) return possible_moves
def main_loop(self, dt): # drop tetromino (do move_down while self.drop_tetromino and not overlap) while True: self.current_tetromino.move_down(dt) overlap = self.grid.overlap(self.current_tetromino.get_coords()) if not self.drop_tetromino or overlap: self.drop_tetromino = False break # tetromino overlaps a block or passed the bottom if overlap: while overlap and not self.grid.is_out_of_bounds( self.current_tetromino.get_coords(), self.columns): self.current_tetromino.move_up() overlap = self.grid.overlap( self.current_tetromino.get_coords()) self.grid.update(self.current_tetromino.get_coords(), self.current_tetromino.get_color_index()) # increase difficulty level every time 10 lines are cleared if self.grid.get_lines() // 10 + 1 != self.difficulty_level: self.difficulty_level += 1 self.tetromino_move_time *= Player.difficulty_modifier # swap next and current tetromino and create a new tetromino self.current_tetromino = self.next_tetromino self.current_tetromino.set_coords( self.grid.get_center_coord(self.columns)) self.current_tetromino.set_speed(self.tetromino_move_time) self.next_tetromino = Tetromino(self.randomizer.get_number(), self.block_size, self.next_tetromino_coord, self.tetromino_move_time) self._create_strings()
def __init__(self, *args, **kwargs): self.tetrion = Tetrion() self.win = pyglet.window.Window.__init__(self, *args, **kwargs) self.batch = pyglet.graphics.Batch() self.playfield = pyglet.shapes.Rectangle(200, 200, 220, 484, color=(64, 64, 64), batch=self.batch) self.tetromino = Tetromino.create_tetromino() self.next_tetromino = Tetromino.create_tetromino() pyglet.clock.schedule_interval(self.update, 1 / 120) pyglet.clock.schedule_interval(self.auto_lower_tt, 1 / 1) self.sprites = self.get_sprites() self.debug1 = pyglet.text.Label(font_name="Tahoma", font_size=12, x=620, y=700, batch=self.batch) self.debug2 = pyglet.text.Label(font_name="Tahoma", font_size=12, x=620, y=660, batch=self.batch)
def test_can_move_right(self): g = grid.Grid(22, 10) tetromino = Tetromino('Z') for i in range(18, 22): g.cells[i][9] = 3 g.cells[18][8] = 2 g.cells[19][8] = 0 g.cells[20][8] = 3 g.cells[21][8] = 1 tetromino.row = 18 tetromino.column = 5 self.assertTrue(g.can_move(tetromino, 1))
def test_can_move_left(self): g = grid.Grid(22, 10) tetromino = Tetromino('Z') for i in range(18, 22): g.cells[i][0] = 3 g.cells[18][1] = 2 g.cells[19][1] = 0 g.cells[20][1] = 3 g.cells[21][1] = 1 tetromino.row = 19 tetromino.column = 2 self.assertTrue(g.can_move(tetromino, -1))
def __init__(self, grid, block_size, viewport_min_coord, player_number): self.columns = (player_number * 10, (player_number + 1) * 10) # coordinates super().__init__(grid, block_size, viewport_min_coord, self.columns) # create next random tetromino self.next_tetromino_coord = (viewport_min_coord[0] + Player.next_tetromino_coord[0], viewport_min_coord[1] + Player.next_tetromino_coord[1] + 3 * player_number * block_size) self.next_tetromino = Tetromino(self.randomizer.get_number(), block_size, self.next_tetromino_coord, self.tetromino_move_time)
def test_can_move_down(self): g = grid.Grid(22, 10) tetromino = Tetromino('I') tetromino.rotate() tetromino.row = 18 self.assertFalse(g.can_move(tetromino, 0)) tetromino.row = 20 self.assertFalse(g.can_move(tetromino, 0)) tetromino.row = 17 self.assertTrue(g.can_move(tetromino, 0)) tetromino.rotate() self.assertTrue(g.can_move(tetromino, 0)) tetromino.row = 20 self.assertFalse(g.can_move(tetromino, 0))
def new_block(self): if not self.__tetrominos_upcoming: pprint("no blocks") self.__tetrominos_upcoming = list(range(Tetromino.block_count())) random.shuffle(self.__tetrominos_upcoming) self.tetromino = Tetromino.get(self.__tetrominos_upcoming.pop(0), self.__starting_position) self.tetromino_next = Tetromino.get(self.__tetrominos_upcoming.pop(0), self.__next_position) else: pprint("have blocks") self.tetromino = self.__tetromino_next self.tetromino.move_to(self.__starting_position) self.tetromino_next = Tetromino.get(self.__tetrominos_upcoming.pop(0), self.__next_position) pprint(self.tetromino_next.name) self.tetromino_next.draw(self.__screen)
def set_legal_actions(self): state = GameState(self) tet = state.cur_tetromino _tet = tet.type grid, _pos = tet.spawn_tet() if not state.test_array(tet): self.legal_actions = [] return self.legal_actions = self.get_legal_actions_by_tet(tet) if self.hold_tet == '': next_tet = Tetromino(next_pieces[0]) else: next_tet = Tetromino(self.hold_tet) self.legal_actions += self.get_legal_actions_by_tet(next_tet) return
def get_drop(Tetromino, board): possible_rots = [ Tetromino, Tetromino.copy().rotate_right(), Tetromino.copy().rotate_right().rotate_right(), Tetromino.copy().rotate_left(), ] #Create a list of all possible drops with a given Tetromino and board, #For each drop in the list provide a copy of the field, the number of gaps, #The board height, the rotation of the Tetromino, and the column/row of the #Tetromino. drops = [] for rot, tet in enumerate(possible_rots): for col in range(10): try: b = board.copy() row = b.drop(tet, col) drops.append({ 'board': b, 'b_height': b.board_height(), 'b_gaps': b.gaps(), 't_row': row, 't_col': col, 't_rot': rot }) except AssertionError: continue min_row = float('inf') min_gaps = float('inf') min_height = float('inf') for drop in drops: min_gaps = min(min_gaps, drop['b_gaps']) drops = list(filter(lambda drop: drop['b_gaps'] == min_gaps, drops)) for drop in drops: min_height = min(min_height, drop['b_height']) drops = list(filter(lambda drop: drop['b_height'] == min_height, drops)) for drop in drops: min_row = min(min_row, drop['t_row']) drops = list(filter(lambda drop: drop['t_row'] == min_row, drops)) return drops[0]
def on_press(key): if(key == keyboard.Key.space): tetro_color = controls.capture_tetromino() input_tetro = Tetromino(color=tetro_color) playgrid.fast_drop(input_tetro) playgrid.print_self() return False
def get_tetromino(self): """Return a pseudo-random tetromino.""" tetromino = random.randint(1, 8) if tetromino == self.previous_tetromino or tetromino == 8: tetromino = random.randint(1, 7) self.previous_tetromino = tetromino return Tetromino(tetromino, 5, 2, 0, TETROMINOES[tetromino - 1])
def evaluate(self, tetromino, grid, state): """Return the optimality of a given state.""" features = [0] * 4 copy = Grid(grid.width, grid.height - 2) copy.grid = [grid.grid[i][:] for i in range(grid.height)] copy.place_tetromino( Tetromino(tetromino.type, state.x, state.y, state.orientation, tetromino.shapes)) lines = copy.lines copy.update() features[0] = copy.lines - lines previous = 0 for x in range(copy.width): current = 0 for y in range(copy.height): if copy.grid[y][x] != 0 and current == 0: current = copy.height - y features[1] += current elif copy.grid[y][x] == 0 and current > 0: features[3] += 1 if x > 0: features[2] += abs(current - previous) previous = current optimality = 0 for feature, weight in zip(features, self.weights): optimality += feature * weight return optimality
def __init__(self, grid, block_size, viewport_min_coord, columns=None): """ :param grid: Grid object :param block_size: integer :param viewport_min_coord: (x, y) :param columns: (start, end) start <= column_index < end """ self.randomizer = BagRandomizer(7) self.block_size = block_size self.difficulty_level = 1 self.drop_tetromino = False # fonts self.game_font = pg.font.Font(os.path.join('fonts', font_file), 38) self.message_font = pg.font.Font(os.path.join('fonts', font_file), 50) # coordinates self.score_coord = (viewport_min_coord[0] + Player.score_coord[0], viewport_min_coord[1] + Player.score_coord[1]) self.level_coord = (viewport_min_coord[0] + Player.score_coord[0], viewport_min_coord[1] + Player.score_coord[1]) self.lines_coord = (viewport_min_coord[0] + Player.lines_coord[0], viewport_min_coord[1] + Player.lines_coord[1]) self.level_coord = (viewport_min_coord[0] + Player.level_coord[0], viewport_min_coord[1] + Player.level_coord[1]) self.next_tetromino_coord = (viewport_min_coord[0] + Player.next_tetromino_coord[0], viewport_min_coord[1] + Player.next_tetromino_coord[1]) # next (text surface) coordinates self.next_coord = (self.next_tetromino_coord[0] - 10, self.next_tetromino_coord[1] - 3 * block_size) self.columns = columns self.grid = grid self.tetromino_move_time = Player.initial_move_time # current random tetromino self.current_tetromino = Tetromino( self.randomizer.get_number(), block_size, self.grid.get_center_coord(self.columns), self.tetromino_move_time) # create next random tetromino self.next_tetromino = Tetromino(self.randomizer.get_number(), block_size, self.next_tetromino_coord, self.tetromino_move_time) self.next_surface = write(self.game_font, "NEXT", Player.text_color) self._create_strings()
def create_tetromino(grid_height, grid_width): # type (shape) of the tetromino is determined randomly tetromino_types = ['I', 'O', 'Z'] random_index = random.randint(0, len(tetromino_types) - 1) random_type = tetromino_types[random_index] # create and return the tetromino tetromino = Tetromino(random_type, grid_height, grid_width) return tetromino
def lower_tt(self): if (self.check_next_tetromino()): if (self.tetromino.pos_y > 19): self.end_game() return False self.tetromino = self.next_tetromino self.next_tetromino = Tetromino.create_tetromino() return False self.tetromino.go_down() return True
def create_tetromino(grid_height, grid_width): # type (shape) of the tetromino is determined randomly # test with O's #tetromino_types = ['S'] tetromino_types = ["S", "T", "J", 'L', 'O', 'Z', 'I'] random_index = random.randint(0, len(tetromino_types) - 1) random_type = tetromino_types[random_index] # create and return the tetromino tetromino = Tetromino(random_type, grid_height, grid_width) return tetromino
class CoopPlayer(Player): def __init__(self, grid, block_size, viewport_min_coord, player_number): self.columns = (player_number * 10, (player_number + 1) * 10) # coordinates super().__init__(grid, block_size, viewport_min_coord, self.columns) # create next random tetromino self.next_tetromino_coord = (viewport_min_coord[0] + Player.next_tetromino_coord[0], viewport_min_coord[1] + Player.next_tetromino_coord[1] + 3 * player_number * block_size) self.next_tetromino = Tetromino(self.randomizer.get_number(), block_size, self.next_tetromino_coord, self.tetromino_move_time) def get_difficulty_level(self): return self.difficulty_level def increase_difficulty_level(self): self.difficulty_level += 1 self.tetromino_move_time *= Player.difficulty_modifier def show_grid(self, screen, normal_blocks): # blit text surfaces screen.blit(self.score_surface, self.lines_coord) screen.blit(self.level_surface, self.level_coord) screen.blit(self.next_surface, self.next_coord) self.grid.show(screen, normal_blocks) def show(self, screen, normal_blocks, assist_blocks, glow_blocks): # blit blocks if not self.grid.is_game_over(): assist_coords = self.grid.get_assist_coords( self.current_tetromino.get_coords()) for coord in assist_coords: screen.blit( assist_blocks[self.current_tetromino.get_color_index()], coord) self.current_tetromino.show(screen, normal_blocks, glow_blocks) self.next_tetromino.show(screen, normal_blocks, glow_blocks)
def compute_move(self, inst): best_move = (float('-inf'), None) grid = self.to_boolean_grid(inst.grid) # compute moves available with the current tetromino first_moves = self.compute_moves_available(grid, inst.current_tmino) # for every move with the current tetromino, # compute moves available with the next tetromino for move1 in first_moves: # determine a score for each move tmino1 = Tetromino(inst.current_tmino.id, move1[0], move1[1], move1[2]) self.add_to_grid(grid, tmino1) score = self.compute_score(grid) if score > best_move[0]: best_move = (score, Tetromino(inst.current_tmino.id, move1[0], move1[1], move1[2])) self.remove_from_grid(grid, tmino1) # the code below is an experimental scoring function # it returns the average of the scores of the next tetromino placement # note that this however runs exponentially slower then the code above """# compute possible moves for the next tetromino tmino1 = Tetromino(inst.current_tmino.id, move1[0], move1[1], move1[2]) self.add_to_grid(grid, tmino1) sum_score = 0 second_moves = self.compute_moves_available(grid, inst.next_tmino) for move2 in second_moves: tmino2 = Tetromino(inst.next_tmino.id, move2[0], move2[1], move2[2]) self.add_to_grid(grid, tmino2) sum_score += self.compute_score(grid) self.remove_from_grid(grid, tmino2) self.remove_from_grid(grid, tmino1) avg_score = float('-inf') if len(second_moves) == 0 else sum_score / len(second_moves) if avg_score >= best_move[0]: best_move = (avg_score, Tetromino(inst.current_tmino.id, move1[0], move1[1], move1[2]))""" return best_move[1]
def evaluate(seq): import sys f = Field() from optimizer import Optimizer answer = [] for i in range(len(seq)): t = Tetromino.create(seq[i]) try: opt = Optimizer.get_optimal_drop(f, t) t.rotate(opt['tetromino_rotation']) f.drop(t, opt['tetromino_column']) except: opt = {"tetromino_rotation": 0, "tetromino_column": 0} action = int( str(opt['tetromino_rotation']) + str(opt['tetromino_column'])) answer.append(action) # print(f, t, i, action) return answer
def take_action(self, action): self.blit_previews() if action.tet_type != self.cur_tetromino.type: if self.hold_tet != '': self.next_pieces.insert(0, self.hold_tet) self.hold_tet = self.cur_tetromino.type if (display_flag): screen.blit(prev_tet_table[tetrominoes.index(self.hold_tet)], (0, 0)) self.new_piece() self.cur_tetromino = Tetromino(action.tet_type) # for op, kick in action.moving: # start = time() # blit_tet(self.cur_tetromino.grid, 'black', self.cur_tetromino.pos) # self.cur_tetromino.take_op(op, kick) # blit_tet(self.cur_tetromino.grid, self.cur_tetromino.type, self.cur_tetromino.pos) # pygame.display.flip() # sleep(max(0.0, 0.025 - (time() - start))) self.cur_tetromino.grid = action.grid self.cur_tetromino.rotation = action.rotation self.cur_tetromino.pos = action.pos self.cur_tetromino.ghost_pos = self.find_ghost_pos() if self.place_piece() == 0: self.update_score(death_penalty) print("All overflow!") return False # blit_tet(self.cur_tetromino.grid, self.cur_tetromino.type, self.cur_tetromino.ghost_pos) # if self.clear_lines(self.cur_tetromino.ghost_pos, tspin): # self.reblit_field() self.new_piece() self.rand_add_garbage() self.set_legal_actions() if len(self.legal_actions) == 0: self.update_score(death_penalty) print("No legal actions!") return False return True
def get_states(self, tetromino, grid): """Return all possible states.""" states = [] visited = {(tetromino.x, tetromino.y, tetromino.orientation)} queue = [State(tetromino.x, tetromino.y, tetromino.orientation, None)] while len(queue) > 0: state = queue.pop(0) copy = Tetromino(tetromino.type, state.x, state.y, state.orientation, tetromino.shapes) copy.move(0, 1) if not grid.can_place(copy): states.append(state) actions = self.get_actions() for action in actions: copy = Tetromino(tetromino.type, state.x, state.y, state.orientation, tetromino.shapes) action(copy) if grid.can_place(copy) and (copy.x, copy.y, copy.orientation) not in visited: visited.add((copy.x, copy.y, copy.orientation)) queue.append(State(copy.x, copy.y, copy.orientation, state)) return states
#!/usr/bin/python from field import Field from optimizer import Optimizer from tetromino import Tetromino import pyautogui import time if __name__ == '__main__': field = Field() tetromino = None key = input() while True: if key in Tetromino.TYPES: tetromino = Tetromino.create(key) opt = Optimizer.get_optimal_drop(field, tetromino) rotation = opt['tetromino_rotation'] column = opt['tetromino_column'] tetromino.rotate(rotation) field.drop(tetromino, column) keys = Optimizer.get_keystrokes( rotation, column, { 'rotate_right': 'x', 'rotate_left': 'z', 'move_left': 'left', 'move_right': 'right', 'drop': ' ' }) print(field) else:
keys.append(keymap['move_left']) # Now we can move it back to the correct column. Since pyautogui's # typewrite is instantaneous, we don't have to worry about the delay # from moving it all the way to the left. for i in range(column): keys.append(keymap['move_right']) keys.append(keymap['drop']) return keys if __name__ == '__main__': mouse = detect_mouse() print("Mouse coordinates: {}".format(mouse)) field = Field() print("First tetromino:") current_tetromino = Tetromino.create(input()) next_tetromino = None time.sleep(2) while True: next_tetromino = TETROMINO[get_pixel(mouse)]() opt = Optimizer.get_optimal_drop(field, current_tetromino) rotation = opt['tetromino_rotation'] column = opt['tetromino_column'] current_tetromino.rotate(rotation) field.drop(current_tetromino, column) keys = Optimizer.get_keystrokes( rotation, column, { 'rotate_right': 'x', 'rotate_left': 'z', 'move_left': 'left', 'move_right': 'right',
def mainloop(self): player = Tetromino(self.screen, random.choice(tetrominoes), self.columns // 2 - 2, 0, self.draw_block, self.block_to_grid, self.is_free) done = False self.game_over = False self.score = 0 while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True self.quitting = True if event.type == EV_ADVANCEGAME: if not player.move(0, 1): player.freeze() n = self.remove_rows() self.score += n * n * 100 player = Tetromino(self.screen, random.choice(tetrominoes), self.columns // 2 - 2, 0, self.draw_block, self.block_to_grid, self.is_free) valid = player.valid(player.row, player.column) if not valid: self.game_over = True done = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.move(-1, 0) if event.key == pygame.K_RIGHT: player.move(1, 0) if event.key == pygame.K_DOWN: player.move(0, 1) if event.key == pygame.K_UP: player.rotate() self.draw_screen() player.show() pygame.display.flip() clock.tick(FPS)
class Player: # game parameters text_color = (255, 255, 255) columns = 10 rows = 20 initial_move_time = 1 # time in seconds # difficulty -> move_time *= difficulty_modifier for every level difficulty_modifier = 0.85 # text coordinates score_coord = (20, 50) lines_coord = (20, 100) level_coord = (20, 150) # next tetromino coordinates next_tetromino_coord = (64, 470) def __init__(self, grid, block_size, viewport_min_coord, columns=None): """ :param grid: Grid object :param block_size: integer :param viewport_min_coord: (x, y) :param columns: (start, end) start <= column_index < end """ self.randomizer = BagRandomizer(7) self.block_size = block_size self.difficulty_level = 1 self.drop_tetromino = False # fonts self.game_font = pg.font.Font(os.path.join('fonts', font_file), 38) self.message_font = pg.font.Font(os.path.join('fonts', font_file), 50) # coordinates self.score_coord = (viewport_min_coord[0] + Player.score_coord[0], viewport_min_coord[1] + Player.score_coord[1]) self.level_coord = (viewport_min_coord[0] + Player.score_coord[0], viewport_min_coord[1] + Player.score_coord[1]) self.lines_coord = (viewport_min_coord[0] + Player.lines_coord[0], viewport_min_coord[1] + Player.lines_coord[1]) self.level_coord = (viewport_min_coord[0] + Player.level_coord[0], viewport_min_coord[1] + Player.level_coord[1]) self.next_tetromino_coord = (viewport_min_coord[0] + Player.next_tetromino_coord[0], viewport_min_coord[1] + Player.next_tetromino_coord[1]) # next (text surface) coordinates self.next_coord = (self.next_tetromino_coord[0] - 10, self.next_tetromino_coord[1] - 3 * block_size) self.columns = columns self.grid = grid self.tetromino_move_time = Player.initial_move_time # current random tetromino self.current_tetromino = Tetromino( self.randomizer.get_number(), block_size, self.grid.get_center_coord(self.columns), self.tetromino_move_time) # create next random tetromino self.next_tetromino = Tetromino(self.randomizer.get_number(), block_size, self.next_tetromino_coord, self.tetromino_move_time) self.next_surface = write(self.game_font, "NEXT", Player.text_color) self._create_strings() def check_input(self, event, keys): """ :param event: pygame event :param keys: (left, right, rotate_cw, rotate_ccw, drop, speed up) """ keys_pressed = pg.key.get_pressed() if event.type == pg.KEYDOWN: if keys_pressed[keys[0]]: self.current_tetromino.move_left() # if tetromino overlaps or it is out of bounds undo move left if self.grid.is_out_of_bounds(self.current_tetromino.get_coords(), self.columns) \ or self.grid.overlap(self.current_tetromino.get_coords()): self.current_tetromino.move_right() elif keys_pressed[keys[1]]: self.current_tetromino.move_right() # if tetromino overlaps or it is out of bounds undo move right if self.grid.is_out_of_bounds(self.current_tetromino.get_coords(), self.columns) \ or self.grid.overlap(self.current_tetromino.get_coords()): self.current_tetromino.move_left() if keys_pressed[keys[2]]: self.current_tetromino.rotate_cw() # if tetromino overlaps or it is out of bounds undo rotate clockwise if self.grid.is_out_of_bounds(self.current_tetromino.get_coords(), self.columns) \ or self.grid.overlap(self.current_tetromino.get_coords()): self.current_tetromino.rotate_ccw() elif keys_pressed[keys[3]]: self.current_tetromino.rotate_ccw() # if tetromino overlaps or it is out of bounds undo rotate counterclockwise if self.grid.is_out_of_bounds(self.current_tetromino.get_coords(), self.columns) \ or self.grid.overlap(self.current_tetromino.get_coords()): self.current_tetromino.rotate_cw() if keys_pressed[keys[4]]: # drop the tetromino instantly if not sounds.mute: sounds.drop_sound.play() self.drop_tetromino = True elif keys_pressed[keys[5]]: # increase tetromino speed self.current_tetromino.speed_up() elif event.type == pg.KEYUP: # reset tetromino speed if keys_pressed[keys[5]]: self.current_tetromino.reset_speed() def main_loop(self, dt): # drop tetromino (do move_down while self.drop_tetromino and not overlap) while True: self.current_tetromino.move_down(dt) overlap = self.grid.overlap(self.current_tetromino.get_coords()) if not self.drop_tetromino or overlap: self.drop_tetromino = False break # tetromino overlaps a block or passed the bottom if overlap: while overlap and not self.grid.is_out_of_bounds( self.current_tetromino.get_coords(), self.columns): self.current_tetromino.move_up() overlap = self.grid.overlap( self.current_tetromino.get_coords()) self.grid.update(self.current_tetromino.get_coords(), self.current_tetromino.get_color_index()) # increase difficulty level every time 10 lines are cleared if self.grid.get_lines() // 10 + 1 != self.difficulty_level: self.difficulty_level += 1 self.tetromino_move_time *= Player.difficulty_modifier # swap next and current tetromino and create a new tetromino self.current_tetromino = self.next_tetromino self.current_tetromino.set_coords( self.grid.get_center_coord(self.columns)) self.current_tetromino.set_speed(self.tetromino_move_time) self.next_tetromino = Tetromino(self.randomizer.get_number(), self.block_size, self.next_tetromino_coord, self.tetromino_move_time) self._create_strings() def show(self, screen, normal_blocks, assist_blocks, glow_blocks): # blit text surfaces screen.blit(self.lines_surface, self.lines_coord) screen.blit(self.score_surface, self.score_coord) screen.blit(self.level_surface, self.level_coord) screen.blit(self.next_surface, self.next_coord) # blit blocks self.grid.show(screen, normal_blocks) if not self.grid.is_game_over(): assist_coords = self.grid.get_assist_coords( self.current_tetromino.get_coords()) for coord in assist_coords: screen.blit( assist_blocks[self.current_tetromino.get_color_index()], coord) self.current_tetromino.show(screen, normal_blocks, glow_blocks) self.next_tetromino.show(screen, normal_blocks, glow_blocks) def display_message(self, screen, text, color=text_color): self.grid.display_message(screen, self.message_font, color, text) def insert_lines(self, lines_number): self.grid.insert_blocks(lines_number) def get_lines_cleared(self): return self.grid.get_lines_cleared() def is_game_over(self): return self.grid.is_game_over() def _create_strings(self): score_string = "SCORE: " + str(self.grid.get_score()) self.score_surface = write(self.game_font, score_string, Player.text_color) lines_string = "LINES: " + str(self.grid.get_lines()) self.lines_surface = write(self.game_font, lines_string, Player.text_color) level_string = "LEVEL: " + str(self.difficulty_level) self.level_surface = write(self.game_font, level_string, Player.text_color)
def new_tetromino(self): self.tetromino = Tetromino(3, 0)
def random_piece(self): return Tetromino.random( y=0, x=randrange(0, self.number_of_cols - 2) )
from board import Board from heuristics import Heuristicizer from tetromino import Tetromino import queue import random import time tetrominos = { 1: Tetromino.OTet(), 2: Tetromino.ITet(), 3: Tetromino.JTet(), 4: Tetromino.LTet(), 5: Tetromino.STet(), 6: Tetromino.ZTet(), 7: Tetromino.TTet(), } tets = [1, 2, 3, 4, 5, 6, 7] random.shuffle(tets) q = queue.Queue(maxsize=20) if __name__ == '__main__': board = Board() while board.board_height() < board.HEIGHT: for tet in tets: q.put(tet) while not q.empty(): t = tetrominos[q.get()] h = Heuristicizer.get_drop(t, board) turns = h['t_rot']
def __init__(self, grid_camera=None): Tetromino.__init__(self, colour=ZPIECE_COLOUR, tile_positions=[(0, 0), (1, 0), (1, 1), (2, 1)], grid_camera=grid_camera) return