def __init__(self, board: Board, surface: Surface, image_list: List[Surface] = None): Sprite.__init__(self) self.image = surface self.rect = surface.get_rect() self.board = board width, height = self.rect.width, self.rect.height self.board_row_count, self.board_column_count = board.get_board().shape self.block_size = Vector2() self.block_size.x = width / board.get_board().shape[0] self.block_size.y = height / board.get_board().shape[1] if image_list is None: block_images = [ self.get_default_image(number) for number in range(board.block_kind_count) ] else: block_images = image_list.copy() if len(block_images) < board.block_kind_count: more_images = [ self.get_default_image(number) for number in range( len(image_list), board.block_kind_count) ] block_images.extend(more_images) self.block_images = block_images self.new_blocks = [] self.blocks = [] self.sync_board() self.timeline = Timeline(0)
def test_update_3(self): board_obj = Board(4, 4, 4) board_obj.board = numpy.array([[0, 0, 0, 0], [1, 1, 2, 1], [2, 2, 2, 2], [3, 3, 2, 3]]) to_remove = [(2, 0), (2, 1), (1, 2), (2, 2), (3, 2), (2, 3)] to_remove.reverse() diff = board_obj.update(to_remove) test_indices = [(1, 0), (1, 1), (1, 3), (2, 0), (2, 1), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)] expected = [0, 0, 0, 1, 1, 1, 3, 3, 0, 3] for i, e in zip(test_indices, expected): self.assertEqual(board_obj.board[i[0], i[1]], e) value, count = numpy.unique(board_obj.board, return_counts=True) count_dict = dict(zip(value, count)) self.assertRaises(KeyError, lambda: count_dict[-1]) self.assertTrue(-1 < numpy.amax(board_obj.board) < 4) expected_animations = [(2, 0, -1, -1), (2, 1, -1, -1), (1, 2, -1, -1), (2, 2, -1, -1), (3, 2, -1, -1), (2, 3, -1, -1), (1, 0, 2, 0), (0, 0, 1, 0), (-1, 0, 0, 0), (1, 1, 2, 1), (0, 1, 1, 1), (-1, 1, 0, 1), (0, 2, 3, 2), (-1, 2, 2, 2), (-2, 2, 1, 2), (-3, 2, 0, 2), (1, 3, 2, 3), (0, 3, 1, 3), (-1, 3, 0, 3)] self.assertCountEqual(diff, expected_animations)
def __init__(self, context: Context): Scene.__init__(self, context) self.rows = 8 self.columns = 8 self.kinds_of_blocks = 6 self.board = Board(self.rows, self.columns, self.kinds_of_blocks) self.board_position = pygame.Vector2(0, 200) self.board_size = pygame.Vector2(400, 400) board_size_int = int(self.board_size.x), int(self.board_size.y) board_region = pygame.Surface(board_size_int) board_region.blit(self.context.assets["board_image"], (0, 0, 400, 400)) self.board_sprite = BoardSprite(self.board, board_region, context.assets["icon_list"]) self.selected = [] self.selecting = False self.path_sprite = PathSprite(self.board_position, self.board_size, self.board_sprite.get_block_size()) play_position = pygame.Vector2(0, 50) self.play = self.context.data["play"] self.play_sprite = PlaySprite(context.data["play"], context.assets["play_image"], play_position) self.animation_playing = [False, False]
def test_create(self): board_obj = Board(8, 8, 3) board = board_obj.get_board() self.assertEqual(board.shape[0] * board.shape[1], 8 * 8) self.assertTrue(isinstance(board[4, 2], numpy.int8)) count = board_obj.get_count() self.assertEqual(len(count), 3) self.assertEqual(sum(count), 8 * 8)
def test_render(self): board = Board(8, 8, 2) board.board = numpy.zeros([8, 8], numpy.int8) board.board[4][2] = 1 board_surface = Surface((400, 400)) image_list = [Surface((50, 50)), Surface((50, 50))] image_list[0].fill(Color(200, 0, 0)) image_list[1].fill(Color(0, 200, 0)) board_sprite = BoardSprite(board, board_surface, image_list) screen = Surface((400, 600)) position = Vector2(0, 100) board_sprite.render(screen, position, []) self.assertEqual(screen.get_at((125, 325)), Color(0, 200, 0)) self.assertEqual(screen.get_at((225, 225)), Color(200, 0, 0))
def test_create(self): board = Board(8, 8, 3) board_surface = Surface((400, 400)) board_sprite = BoardSprite(board, board_surface) self.assertEqual(board_sprite.block_size, Vector2(400 / 8, 400 / 8)) self.assertEqual(len(board_sprite.blocks), 8 * 8) self.assertEqual(len(board_sprite.block_images), 3) self.assertTrue(isinstance(board_sprite.block_images[2], Surface))
def setUp(self) -> None: global scene scene = MainScene(context) scene.board = Board(4, 4, 4) scene.board.board = board.copy() scene.board_region = pygame.Surface((400, 400)) scene.board_position = pygame.Vector2(0, 100) scene.board_sprite = BoardSprite(scene.board, scene.board_region)
def test_shuffle(self): board = Board(4, 4, 3) board.board = numpy.array([[0, 1, 0, 0], [0, 2, 2, 1], [1, 1, 0, 1], [2, 0, 2, 2]]) prev_count = [6, 5, 5] board.count = prev_count.copy() board.shuffle() new_count = board.count self.assertTrue(board.is_possible_to_move()) self.assertEqual(prev_count, new_count)
class MainScene(Scene): def __init__(self, context: Context): Scene.__init__(self, context) self.rows = 8 self.columns = 8 self.kinds_of_blocks = 6 self.board = Board(self.rows, self.columns, self.kinds_of_blocks) self.board_position = pygame.Vector2(0, 200) self.board_size = pygame.Vector2(400, 400) board_size_int = int(self.board_size.x), int(self.board_size.y) board_region = pygame.Surface(board_size_int) board_region.blit(self.context.assets["board_image"], (0, 0, 400, 400)) self.board_sprite = BoardSprite(self.board, board_region, context.assets["icon_list"]) self.selected = [] self.selecting = False self.path_sprite = PathSprite(self.board_position, self.board_size, self.board_sprite.get_block_size()) play_position = pygame.Vector2(0, 50) self.play = self.context.data["play"] self.play_sprite = PlaySprite(context.data["play"], context.assets["play_image"], play_position) self.animation_playing = [False, False] def on_create(self, context: Context): pass def on_mouse_down(self, button: Tuple, position: Tuple): if not any(self.animation_playing): if button[0]: block = mouse_row, mouse_col = self.mouse_on_which_block( position) if mouse_row > -1 and mouse_col > -1: self.selecting = True self.selected.append(block) def on_mouse_move(self, position: Tuple): if not any(self.animation_playing): if self.selecting: board = self.board.get_board() mouse = mouse_row, mouse_col = self.mouse_on_which_block( position) last_row, last_col = self.selected[-1] backtrack = len( self.selected) > 1 and mouse == self.selected[-2] if backtrack: self.selected.pop() return on_screen = mouse_row > -1 and mouse_col > -1 is_neighbour = abs(mouse_row - last_row) < 2 and abs( mouse_col - last_col) < 2 same_colour = board[mouse_row][mouse_col] == board[last_row][ last_col] not_same = not (mouse_row == last_row and mouse_col == last_col) no_cross = self.selected.count((mouse_row, mouse_col)) == 0 correct = all( [on_screen, is_neighbour, same_colour, not_same, no_cross]) if correct: self.selected.append(mouse) def on_mouse_up(self, button: Tuple, position: Tuple): if not any(self.animation_playing): if len(self.selected) > 2: board = self.board.get_board() row, col = self.selected[0] update_kind = board[row, col] update_count = len(self.selected) self.play.update(update_kind, update_count) diff = self.board.update(self.selected) self.board_sprite.add_animation(diff) self.board_sprite.play_animation(pygame.time.get_ticks()) self.play_sprite.add_animation(update_kind, update_count) self.play_sprite.play_animation(pygame.time.get_ticks()) self.selected = [] self.selecting = False def on_animation_begin(self, timeline_id: int): self.animation_playing[timeline_id] = True def on_animation_end(self, timeline_id: int): self.animation_playing[timeline_id] = False if timeline_id == 0: self.board_sprite.on_animation_end() elif timeline_id == 1: self.play_sprite.on_animation_end() if not any(self.animation_playing): if not self.board.is_possible_to_move(): diff = self.board.shuffle() self.board_sprite.add_animation(diff) self.board_sprite.play_animation(pygame.time.get_ticks()) def update(self, ticks: int): if self.animation_playing[0]: self.board_sprite.update(ticks) if self.animation_playing[1]: self.play_sprite.update(ticks) def render(self): self.board_sprite.render(self.context.screen, self.board_position, self.selected) self.path_sprite.render(self.context.screen, self.selected) self.play_sprite.render(self.context.screen, self.board_sprite.block_images) def mouse_on_which_block(self, position: Tuple) -> Tuple: block_size = self.board_sprite.get_block_size() mouse_position = pygame.Vector2(position) offset = mouse_position - self.board_position column_index, column_remain = divmod(offset.x, block_size.x) row_index, row_remain = divmod(offset.y, block_size.y) column_index = column_index if -1 < column_index < self.columns else -1 row_index = row_index if -1 < row_index < self.rows else -1 row_col = int(row_index), int(column_index) touch_ratio = 0.8 touch_low, touch_high = 0.5 - touch_ratio / 2, 0.5 + touch_ratio / 2 column_in_touch = touch_low < column_remain / block_size.x < touch_high row_in_touch = touch_low < row_remain / block_size.y < touch_high if column_in_touch and row_in_touch: return row_col else: return -1, -1
def test_check_if_possible_1(self): board = Board(4, 4, 3) board.board = numpy.array([[1, 0, 0, 1], [0, 2, 2, 0], [0, 1, 0, 1], [2, 0, 2, 2]]) self.assertTrue(board.is_possible_to_move())