def block_erase(self, block): new_grid = self.gd.grid for i in range(4): row = block.curr_pos[i][0] col = block.curr_pos[i][1] if block.get_type() == bt.GHOST: if new_grid[row][col].get_type() != bt.BLOCK: new_grid[row][col] = Square(c.GREY, bt.EMPTY) else: new_grid[row][col] = Square(c.GREY, bt.EMPTY) return new_grid
def move(self, direction): # Erase the block's current position, fill in new position to left/right new_grid = self.gd.get_grid() self.block_erase(self.gd.curr_block) for i in range(4): row = self.gd.curr_block.curr_pos[i][0] col = self.gd.curr_block.curr_pos[i][1] if direction == "left": self.gd.curr_block.curr_pos[i] = (row, col - 1) new_grid[row][col - 1] = Square(self.gd.curr_block.get_color(), bt.BLOCK) else: # direction == "right" self.gd.curr_block.curr_pos[i] = (row, col + 1) new_grid[row][col + 1] = Square(self.gd.curr_block.get_color(), bt.BLOCK)
def draw_mini_grid(self, gd, block, xpos, ypos): mini_grid = [[Square(c.GREY, "EMPTY") for column in range(4)] for row in range(4)] if block != None: block_shape = block.shape for i in range(len(block_shape)): row = block_shape[i][0] col = block_shape[i][1] mini_grid[row][col] = Square(block.get_color(), "BLOCK") for row in range(4): for col in range(4): color = mini_grid[row][col].get_color() rect = pg.Rect(c.SQUARE * col + xpos + c.SQUARE_MARGIN, c.SQUARE * row + ypos + c.SQUARE_MARGIN, c.SQUARE_SIZE, c.SQUARE_SIZE) pg.draw.rect(self.screen, color, rect)
def soft_drop(self): new_grid = self.gd.grid self.block_erase(self.gd.curr_block) for i in range(4): row = self.gd.curr_block.curr_pos[i][0] col = self.gd.curr_block.curr_pos[i][1] self.gd.curr_block.curr_pos[i] = (row + 1, col) new_grid[row + 1][col] = Square(self.gd.curr_block.get_color(), bt.BLOCK)
def block_overlap(self): temp_grid = self.gd.get_grid() for pos in self.gd.curr_block.start_pos: if (temp_grid[pos[0]][pos[1]].get_type() == bt.BLOCK): print("Game Over!") return True temp_grid[pos[0]][pos[1]] = Square(self.gd.curr_block.get_color(), bt.BLOCK) return False
def hard_drop(self, block): # input: # block -> Block Class new_grid = self.gd.grid while not self.block_collision_v(block): self.block_erase(block) for i in range(4): row = block.curr_pos[i][0] col = block.curr_pos[i][1] block.curr_pos[i] = (row + 1, col) for i in range(4): row = block.curr_pos[i][0] col = block.curr_pos[i][1] new_grid[row][col] = Square(block.get_color(), block.get_type())
def ghost_block_generate(self): curr_block = self.gd.curr_block if self.gd.ghost_block: self.block_erase(self.gd.ghost_block) self.gd.ghost_block = Block(curr_block.template, bt.GHOST).clone() self.gd.ghost_block.set_color(c.WHITE) self.gd.ghost_block.set_pos(deepcopy(curr_block.get_pos())) self.hard_drop(self.gd.ghost_block) if self.gd.ghost_block.get_pos() == curr_block.get_pos(): for i in range(4): row = curr_block.curr_pos[i][0] col = curr_block.curr_pos[i][1] self.gd.grid[row][col] = Square(curr_block.get_color(), bt.BLOCK)
def grid_generate(self): # Create a grid with color other than black. grid = [[Square(c.GREY, "EMPTY") for column in range(c.COLUMN_COUNT)] for row in range(c.ROW_COUNT)] self.set_grid(grid)
def rotate(self, direction): # input: # direction -> str # O-block doesn't need to rotate if self.gd.curr_block.rotation_states == None: return self.gd.grid # I-block, S-block, Z-block, L-block, J-block, T-block rotates 4 ways else: new_grid = self.gd.get_grid() curr_state = self.gd.curr_block.get_curr_state() next_state = curr_state diff = [] if direction == "clockwise": if curr_state == 3: next_state = 0 else: next_state += 1 else: # direction == "counter clockwise" if curr_state == 0: next_state = 3 else: next_state -= 1 curr_points = self.gd.curr_block.get_rotation_states()[curr_state] next_points = self.gd.curr_block.get_rotation_states()[next_state] # Find the difference to transition from current to next state if direction == "clockwise": diff = self.find_diff(direction, curr_points, next_points) else: # direction == "counter clockwise" diff = self.find_diff(direction, next_points, curr_points) # Check collision before committing rotation leftmost = min(self.gd.curr_block.curr_pos, key=lambda x: x[1])[1] rightmost = max(self.gd.curr_block.curr_pos, key=lambda x: x[1])[1] # Wall kick if: # I-block, current state is 1 or 3, and near either wall # Current state is 1 and against left wall # Current state is 3 and against right wall if self.gd.curr_block.template == 'I': if ((curr_state == 1 or curr_state == 3) and leftmost <= 1 and not self.block_collision_h("right")): self.wall_kick_i("left", diff, curr_state) elif ((curr_state == 1 or curr_state == 3) and rightmost >= 8 and not self.block_collision_h("left")): self.wall_kick_i("right", diff, curr_state) else: if (curr_state == 1 and leftmost == 0 and not self.block_collision_h("right")): self.wall_kick("left", diff) elif (curr_state == 3 and rightmost == 9 and not self.block_collision_h("left")): self.wall_kick("right", diff) if not self.block_collision_r(diff): # Rotation self.block_erase(self.gd.curr_block) for i in range(4): row = self.gd.curr_block.curr_pos[i][0] col = self.gd.curr_block.curr_pos[i][1] next_row = row + diff[i][0] next_col = col + diff[i][1] self.gd.curr_block.curr_pos[i] = (next_row, next_col) new_grid[next_row][next_col] = Square( self.gd.curr_block.get_color(), bt.BLOCK) self.gd.curr_block.set_curr_state(next_state)
def remove_line(self, row_index): # input: # row_index -> int del self.gd.grid[row_index] self.gd.grid.insert(0, [Square(c.GREY, bt.EMPTY)] * c.COLUMN_COUNT)