def testmove(self): ''' Création de 2 pions. Teste le mouvement correct des 2 pions. ''' tab = np.zeros((2,2)) tab[0][0] = 1 tab[0][1] = 2 Pion1 = Piece(0,0,1,1,1) Pion2 = Piece(0,1,1,0,2) Pion1.move(tab) Pion2.move(tab) self.assertEqual(tab[0][0], 0) self.assertEqual(tab[0][1], 0) self.assertEqual(tab[1][1], 1) self.assertEqual(tab[1][0], 2)
def answer(state_map, state_piece, x, dx, rad): map_tmp = copy.deepcopy(const.map) for i in range(len(state_map)): if state_map[i] != 0: map_tmp[state_map[i]][i] = 1 p_tmp = Piece(state_piece, x) p_tmp.updateMap(map_tmp) gain = 0 if dx>0: for i in range(dx): p_tmp.move('right') else: for i in range(-dx): p_tmp.move('left') for i in range(rad): p_tmp.rotate('ccw') p_tmp.drop() for i in range(len(p_tmp.shape[0])): for j in range(len(p_tmp.shape[0][i])): if p_tmp.shape[0][i][j]: map_tmp[p_tmp.y+i][p_tmp.x+j] = p_tmp.shape[1] erasable = [] for i in range(len(map_tmp)-1): flag_full = True for j in range(1,len(map_tmp[i])-1): if map_tmp[i][j] == 0 or map_tmp[i][j] == 8: flag_full = False if flag_full: erasable.append(i) if len(erasable) == 0: gain = 0 else: gain = scores[min(len(erasable)-1, 3)] for i in erasable: for j in range(i-2): map_tmp[i-j] = copy.deepcopy(map[i-j-1]) for i in range(len(map_tmp)): for j in range(len(map_tmp[i])): if map_tmp[i][j]!=0: map_tmp[i][j] = 1 return [map_tmp, gain]
class Manager: def __init__(self): self.display = Display() self._spawn_piece() def _spawn_piece(self): ''' Produce a new piece ''' self.display.update_board() self.current_piece = Piece() try: self.display.add_piece(self.current_piece) self.display.draw() except OverlapError: print('Game Over') exit() def game_loop(self): ''' Execute for each user input ''' move = raw_input('Please enter a move: ').strip() action = ACTIONS.get(move) if action is None: print('Entered move does not exist! Try again.') return self.current_piece.move(action) try: self.display.show_piece() except OverlapError: self.current_piece.undo() print('Invalid move! Try again.') return if self.display.check_valid_moves(): self.display.draw() else: self._spawn_piece()
class PtModel: #class variables FPS = 60 SCORE = [0, 40, 100, 300, 1200] TIME = { "fell": -100, "moved": -100, "rotated": -20, "stopped_moving": -30, "stopped_rotating":-30 } INTERVAL = { "move": 0.3, "rotate": 0.3, "gravity": 0.3 } def __init__(self, gravity = 0.3): self.view = PtView() self.board = Board() self.p = Piece(self.board) self.p_next = Piece(self.board) self.score = 0 self.line_erasable = [] self.interval = copy.deepcopy(PtModel.INTERVAL) self.interval['gravity'] = gravity self.time = copy.deepcopy(PtModel.TIME) self.flag = { 'moving': True, 'rotating': True } self.view.renderNext(self.p_next.getShape(), self.p_next.getType()) def getKey(self): pygame.event.pump() keys = pygame.key.get_pressed() # 移動のキーn if self.isMovable(): if keys[K_LEFT]: self.movePiece('left') elif keys[K_RIGHT]: self.movePiece('right') elif keys[K_UP]: self.movePiece('up') elif keys[K_DOWN]: self.movePiece('down') if self.p.isGround() == False: self.time['moved'] = time.clock() else: # 動くのをやめた時だけインターバル回復 # if self.flag['moving']: self.flag['moving'] = False self.time['stopped_moving'] = time.clock() self.interval['move'] = PtModel.INTERVAL['move'] # 回転のキー if self.isRotatable(): if keys[K_z]: self.rotatePiece('ccw') elif keys[K_x]: self.rotatePiece('cw') else: # if self.flag['rotating']: self.flag['rotating'] = False self.time['stopped_rotating'] = time.clock() self.interval['rotate'] = PtModel.INTERVAL['rotate'] def isMovable(self): if (time.clock() - self.time['moved']) > self.interval['move']: return True if (time.clock() - self.time['stopped_moving'])< PtModel.INTERVAL['move']: return True return False def isRotatable(self): if (time.clock() - self.time['rotated']) > self.interval['rotate']: return True if (time.clock() - self.time['stopped_rotating'])< PtModel.INTERVAL['rotate']: return True return False def movePiece(self, direction): if direction == 'up': self.p.drop() else: self.p.move(direction) self.time['moved'] = time.clock() if self.interval['move'] > 0.1: self.interval['move'] *= 0.9 # self.flag['moving'] = True def rotatePiece(self, radius): self.p.rotate(radius) self.time['rotated'] = time.clock() if(self.interval['rotate']>0.1): self.interval['rotate'] *= 0.9 # self.flag['rotating'] = True def fallPiece(self): if time.clock() - self.time['fell'] > self.interval['gravity']: self.time['fell'] = time.clock() self.p.move('down') self.time['moved'] = time.clock() def isAlive(self): for i in self.board.getShape()[3]: if i!=0 and i!=8: return False return True def updateBoard(self): p_shape = self.p.getShape() p_type = self.p.getType() self.board.update(p_shape, p_type, self.p.getX(), self.p.getY()) def updatePiece(self): self.p = copy.deepcopy(self.p_next) self.p.setBoard(self.board) self.p_next = Piece(self.board) self.view.renderNext(self.p_next.getShape(), self.p_next.getType()) def update(self): if self.isWaiting(): return False self.updateBoard() self.erase() self.updatePiece() return True def erase(self): self.score += PtModel.SCORE[self.board.erase()] def isWaiting(self): if self.p.isGround(): if time.clock() - self.time['moved'] < self.interval['gravity']: return True if time.clock() - self.time['rotated'] < self.interval['gravity']: return True return False return True def gameOver(self): pass def tick(self): pygame.time.Clock().tick(15) # boardとpieceを統合して現在の画面の状態を得る def getCurrentBoard(self): b_shape = copy.deepcopy(self.board.getShape()) p_shape = self.p.getShape() p_type = self.p.getType() offset_x = self.p.getX() offset_y = self.p.getY() for i in range(len(p_shape)): for j in range(len(p_shape[i])): if p_shape[i][j]: b_shape[i + offset_y][j + offset_x] = p_type return b_shape def draw(self): self.view.renderBoard(self.getCurrentBoard()) self.view.renderScore(self.score) pygame.display.update() def loop(self): self.tick() self.update() if self.isAlive() == False: self.gameOver() self.getKey() self.fallPiece() self.draw()
class State: MOVE_DELAY = 10 MOVE_INTERVAL = 5 def __init__(self, game_w, game_h, board_w, board_h): self.board = Board(board_w, board_h) self.w = game_w self.h = game_h self.T = 0.2 self.block_pool = list("iotszjl" * 4) random.shuffle(self.block_pool) self.current_piece = Piece(self.block_pool.pop(0), board_w // 2 - 1, 0) self.held_piece_shape = "" self.held_this_turn = False self.player = Player(100, 100, 10) self.tick_num = 0 self.step_max = 30 self.fast_step = 3 self.current_step = self.step_max self.movement = 0 self.counter = State.MOVE_DELAY #self.generate_junk_lines(self.board.h//2) def generate_new_piece(self): for block in self.current_piece.blocks: self.board.board[block[1]][ block[0]] = self.current_piece.colour.value piece_shape = self.block_pool.pop(0) self.current_piece = Piece(piece_shape, self.board.w // 2 - 1, 0) if len(self.block_pool) == 7: self.block_pool += random.sample("iotszjl" * 3, 21) def hold_piece(self): if not (self.held_this_turn): if self.held_piece_shape == "": self.held_piece_shape = self.current_piece.shape piece_shape = self.block_pool.pop(0) self.current_piece = Piece(piece_shape, self.board.w // 2 - 1, 0) if len(self.block_pool) == 7: self.block_pool += random.sample("iotszjl" * 3, 21) else: current_piece_shape = self.current_piece.shape self.current_piece = Piece(self.held_piece_shape, self.board.w // 2 - 1, 0) self.held_piece_shape = current_piece_shape self.held_this_turn = True def step(self): generated_new_piece = False can_move = True for block in self.current_piece.blocks: if block[1] == self.board.h - 1 or self.board.board[block[1] + 1][ block[0]] != 0: can_move = False if can_move: self.current_piece.move([0, 1]) else: self.generate_new_piece() generated_new_piece = True self.check_for_completed_rows() return generated_new_piece def check_for_completed_rows(self): for row_num, row in enumerate(self.board.board): if all(row): self.board.board[row_num] = [0 for _ in range(self.board.w)] for other_row_num in range(row_num - 1, -1, -1): self.board.board[other_row_num + 1] = self.board.board[other_row_num][:] def generate_junk_lines(self, num_of_junk_lines): for row_num in range(num_of_junk_lines, self.board.h): self.board.board[row_num - num_of_junk_lines] = self.board.board[row_num][:] for row_num in range(self.board.h - num_of_junk_lines, self.board.h): empty_pos = random.randint(0, self.board.w - 1) self.board.board[row_num] = [ 0 if _ == empty_pos else random.randint(1, len(Colour) - 1) for _ in range(self.board.w) ] def update(self): if self.tick_num % self.current_step == 0: generated_new_piece = self.step() if generated_new_piece: self.held_this_turn = False if self.movement: self.counter -= 1 if self.counter == 0: can_move = True for block in self.current_piece.blocks: if block[0] == ( 0 if self.movement == -1 else self.board.w - 1 ) or self.board.board[block[1]][block[0] + self.movement] != 0: can_move = False if can_move: self.current_piece.move([self.movement, 0]) self.counter = State.MOVE_INTERVAL self.player.update(self) self.tick_num += 1
class Game: """Manages the interaction between the player and movement, margins, lower pieces, states, score, next piece and level.""" def __init__(self, piece_name = None): self.playing = True self.paused = False self.game_over = False self.running = True self.player = Piece(piece_name, list(PIECE_STAGE_STARTING_POSITION)) self.player.offset_piece() self.next_piece = Piece() self.score = Score() self.bottom_pieces = BottomPieces(self) self.draw = DrawGame(self) self.event_handler = EventHandler(self) self.lower_piece_data = {n:int(48 - 2.4 * n) for n in range(21)} # TODO: explain def run(self): while self.running: self.event_handler.clock.tick() self.event_handler.handle_events() self.draw.draw_game() def set_paused(self, pause = None): self.paused = pause if pause != None else not self.paused self.playing = not self.paused and not self.game_over def player_oversteps_bottom_pieces(self): for coord in self.player.blocks: if coord in self.bottom_pieces: return True return False def player_oversteps_border(self): for coord in self.player.blocks: if not (STAGE_MARGIN[0] <= coord[0] <= STAGE_WIDTH+STAGE_MARGIN[0]) or \ not (coord[1] <= STAGE_HEIGHT+STAGE_MARGIN[1]): return True return False def player_oversteps(self): return self.player_oversteps_border() or self.player_oversteps_bottom_pieces() def move_player(self, coord): self.player.move(coord) if self.player_oversteps(): self.player.move([coord[0]*-1, coord[1]*-1]) if coord[1]: self.change_player() def rotate_player(self): self.player.rotate_cw() if self.player_oversteps(): self.player.rotate_ccw() def change_player(self): self.bottom_pieces.append(self.player) self.player = self.next_piece self.player.set_position(list(PIECE_STAGE_STARTING_POSITION)) self.next_piece = Piece() self.bottom_pieces.check_rows() if self.player_oversteps_bottom_pieces(): self.playing = False self.game_over = True def bottom_pieces_call(self, number): """BottomPieces uses this method when it clears lines""" self.score.add_lines(number) def move_piece_to_limit(self, coord): """It lowers the piece to the bottom in one movement, or it moves it to the right or left until a limit is met""" def has_advanced(previous_pos, current_pos): if coord[0] > 0: return previous_pos[0] < current_pos[0] elif coord[0] < 0: return previous_pos[0] > current_pos[0] elif coord[1] > 0: return previous_pos[1] < current_pos[1] elif coord[1] < 0: return previous_pos[1] > current_pos[1] elif previous_pos == current_pos: return False keep_moving = True while keep_moving: old_position = self.player.position[:] self.move_player(coord) if not has_advanced(old_position, self.player.position): keep_moving = False def trigger_event_lower_piece(self): event_lower_piece = pygame.event.Event(LOWER_PIECE_EVENT_ID) pygame.event.post(event_lower_piece)