mirror of
https://github.com/kristoferssolo/2048.git
synced 2025-10-21 15:20:35 +00:00
refactor(game): add atomic funtions
This commit is contained in:
parent
79c3bee2a3
commit
585ddcd1d0
1
.gitignore
vendored
1
.gitignore
vendored
@ -159,3 +159,4 @@ cython_debug/
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
debug
|
||||
.logs/
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import random
|
||||
|
||||
from typing import Union
|
||||
|
||||
import pygame
|
||||
from loguru import logger
|
||||
|
||||
@ -9,7 +11,7 @@ from .config import Config
|
||||
from .utils import Direction
|
||||
|
||||
|
||||
def _show_pos(pos: int) -> int:
|
||||
def _grid_pos(pos: int) -> int:
|
||||
"""Return the position in the grid."""
|
||||
return pos // Config.BLOCK_SIZE + 1
|
||||
|
||||
@ -36,24 +38,40 @@ class Block(pygame.sprite.Sprite):
|
||||
|
||||
def move(self, direction: Direction) -> None:
|
||||
"""Move the block by `dx` and `dy`."""
|
||||
dx, dy = direction.value
|
||||
dx, dy = direction * Config.BLOCK_SIZE
|
||||
|
||||
while True:
|
||||
new_x = self.rect.x + dx * Config.BLOCK_SIZE
|
||||
new_y = self.rect.y + dy * Config.BLOCK_SIZE
|
||||
new_x, new_y = self._calc_new_pos(direction)
|
||||
|
||||
if not (0 <= new_x <= Config.WIDTH - Config.BLOCK_SIZE and 0 <= new_y <= Config.HEIGHT - Config.BLOCK_SIZE):
|
||||
# logger.debug(f"Block({id(self)}) stayed at {self} (out of bounds)")
|
||||
break
|
||||
if self._is_out_if_bounds(new_x, new_y):
|
||||
logger.debug(f"Block({id(self)}) stayed at {self.pos()} (out of bounds)")
|
||||
return
|
||||
|
||||
collision = any(block.rect.collidepoint(new_x, new_y) for block in self.groups()[0] if block != self)
|
||||
|
||||
if collision:
|
||||
logger.debug(f"Block({id(self)}) collided with another block, stopped at {self}")
|
||||
break
|
||||
if self._has_collision(new_x, new_y):
|
||||
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} => ({_show_pos(new_x)}, {_show_pos(new_y)})")
|
||||
logger.debug(f"Moving block({id(self)}): {self.pos()} => ({_grid_pos(new_x)}, {_grid_pos(new_y)})")
|
||||
|
||||
def _calc_new_pos(self, direction: Direction) -> tuple[int, int]:
|
||||
"""Calculate the new position of the block."""
|
||||
dx, dy = direction * Config.BLOCK_SIZE
|
||||
return self.rect.x + dx, self.rect.y + dy
|
||||
|
||||
def _is_out_if_bounds(self, x: int, y: int) -> bool:
|
||||
"""Return whether the block is out of bounds."""
|
||||
return not (0 <= x <= Config.WIDTH - Config.BLOCK_SIZE and 0 <= y <= Config.HEIGHT - Config.BLOCK_SIZE)
|
||||
|
||||
def _has_collision(self, x: int, y: int) -> bool:
|
||||
"""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 _merge(self, other: "Block") -> None:
|
||||
"""Merge the block with another block."""
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update the block"""
|
||||
@ -79,19 +97,19 @@ class Block(pygame.sprite.Sprite):
|
||||
|
||||
def __add__(self, other: "Block") -> None:
|
||||
"""Add the value of two blocks and update the current block"""
|
||||
logger.debug(f"Merging blocks ({id(self)}) and ({id(other)}) => ({id(self)}), {self}")
|
||||
logger.debug(f"Merging blocks ({id(self)}) and ({id(other)}) => ({id(self)}), {self.pos()}")
|
||||
self.value += other.value
|
||||
self.update()
|
||||
|
||||
def __iadd__(self, other: "Block") -> None:
|
||||
"""Add the value of two blocks and updae the current block"""
|
||||
logger.debug(f"Merging blocks ({id(self)}) and ({id(other)}) => ({id(self)}), {self}")
|
||||
logger.debug(f"Merging blocks ({id(self)}) and ({id(other)}) => ({id(self)}), {self.pos()}")
|
||||
self.value += other.value
|
||||
self.update()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Return a string representation of the block"""
|
||||
return f"({_show_pos(self.rect.x)}, {_show_pos(self.rect.y)})"
|
||||
return f"Block({id(self)}): ({self.pos()})"
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Return a string representation of the block"""
|
||||
@ -100,3 +118,7 @@ class Block(pygame.sprite.Sprite):
|
||||
def __hash__(self) -> int:
|
||||
"""Return a hash of the block"""
|
||||
return hash((self.rect.x, self.rect.y, self.value))
|
||||
|
||||
def pos(self) -> tuple[int, int]:
|
||||
"""Return the position of the block"""
|
||||
return _grid_pos(self.rect.x), _grid_pos(self.rect.y)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user