From 2b6b4c34d99aee23dd2328f21309992ac7483bcd Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 30 Dec 2023 20:36:37 +0200 Subject: [PATCH] feat(game): generate block with given coords feat(game): update `generate_block` Method accepts coords where to spawn blocks --- src/py2048/block.py | 19 +++++++++++++++---- src/py2048/game.py | 3 ++- src/py2048/grid.py | 17 +++++++++++------ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/py2048/block.py b/src/py2048/block.py index 01f8900..329d9f6 100644 --- a/src/py2048/block.py +++ b/src/py2048/block.py @@ -43,8 +43,12 @@ class Block(pygame.sprite.Sprite): return if self._has_collision(new_x, new_y): - logger.debug(f"Block({id(self)}) collided with another, stopped at {self.pos()}") - return + collided_block = self._get_collided_block(new_x, new_y) + if collided_block and collided_block.value == self.value: + self._merge(collided_block) + else: + logger.debug(f"Block({id(self)}) collided with another, stopped at {self.pos()}") + return self.rect.topleft = new_x, new_y logger.debug(f"Moving block({id(self)}): {self.pos()} => ({grid_pos(new_x)}, {grid_pos(new_y)})") @@ -62,11 +66,18 @@ class Block(pygame.sprite.Sprite): """Checks whether the block has a collision with any other block.""" return any(block.rect.collidepoint(x, y) for block in self.groups()[0] if block != self) - def _get_collided_block(self) -> Union["Block", None]: - """Get the block that collides with the given rectangle.""" + def _get_collided_block(self, x: int, y: int) -> Union["Block", None]: + """Get the block that collides with the given block.""" + + logger.error(list(block for block in self.groups()[0] if block != self and block.rect.collidepoint(x, y))) + return next((block for block in self.groups()[0] if block != self and block.rect.collidepoint(x, y)), None) def _merge(self, other: "Block") -> None: """Merge the block with another block.""" + self.value += other.value + self.update() + logger.debug(f"Merging block({id(self)}) with block({id(other)}") + self.groups()[0].remove(other) def update(self) -> None: """Update the block""" diff --git a/src/py2048/game.py b/src/py2048/game.py index 8a52e74..40e910c 100644 --- a/src/py2048/game.py +++ b/src/py2048/game.py @@ -19,7 +19,8 @@ class Game: self.screen: pygame.Surface = pygame.display.set_mode((Config.WIDTH, Config.HEIGHT)) pygame.display.set_caption("2048") self.blocks = Grid() - self.blocks.generate_random_block(Config.INITIAL_BLOCK_COUNT) + # self.blocks.generate_block(Config.INITIAL_BLOCK_COUNT) + self.blocks.generate_block(2, (1, 1), (1, 3)) def run(self) -> None: """Run the game loop.""" diff --git a/src/py2048/grid.py b/src/py2048/grid.py index c7b9afa..d47260b 100644 --- a/src/py2048/grid.py +++ b/src/py2048/grid.py @@ -20,15 +20,20 @@ class Grid(pygame.sprite.Group): for block in blocks: block.move(direction) - def generate_random_block(self, count: int = 1) -> None: - """Generate `count` number of random blocks.""" - for _ in range(count): + def generate_block(self, amount: int = 1, *pos: tuple[int, int]) -> None: + """Generate `amount` number of blocks.""" + if pos: + for coords in pos: + self.add(Block(coords[0] * Config.BLOCK_SIZE, coords[1] * Config.BLOCK_SIZE)) + return + + for _ in range(amount): while True: - x = random.randint(0, 2) * Config.BLOCK_SIZE # random column position - y = random.randint(0, 2) * Config.BLOCK_SIZE # random row position + x = random.randint(0, 3) * Config.BLOCK_SIZE # random column position + y = random.randint(0, 3) * Config.BLOCK_SIZE # random row position block = Block(x, y) - colliding_blocks = pygame.sprite.spritecollide(block, self, False) # check collision + colliding_blocks = self.spritecollide(block, self, False) # check collision if not colliding_blocks: self.add(block)