Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ keywords = [
dependencies = [
"pygame~=2.6.0",
"typing_extensions>=4.12.2",
"mypy_extensions>=1.0.0",
"trio~=0.26.2",
"cryptography>=43.0.0",
"exceptiongroup; python_version < '3.11'",
Expand All @@ -53,7 +54,7 @@ version = {attr = "checkers.game.__version__"}
"Bug Tracker" = "https://github.com/CoolCat467/Checkers/issues"

[project.scripts]
checkers_game = "checkers.game:cli_run"
checkers_game = "checkers:cli_run"

[tool.setuptools.package-data]
checkers = ["py.typed", "data/*"]
Expand Down
8 changes: 7 additions & 1 deletion src/checkers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Programmed by CoolCat467

# Copyright (C) 2023 CoolCat467
# Copyright (C) 2023-2024 CoolCat467
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -16,3 +16,9 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.


from checkers.game import cli_run as cli_run

if __name__ == "__main__":
cli_run()
20 changes: 3 additions & 17 deletions src/checkers/base2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from checkers.vector import Vector2

if TYPE_CHECKING:
from collections.abc import Callable, Generator, Iterable, Sequence
from collections.abc import Callable, Iterable, Sequence


def amol(
Expand Down Expand Up @@ -148,20 +148,6 @@ def get_colors(
return colors


def average_color(
surface: pygame.surface.Surface,
) -> Generator[int, None, None]:
"""Return the average RGB value of a surface."""
s_r, s_g, s_b = 0, 0, 0
colors = get_colors(surface)
for color in colors:
r, g, b = color
s_r += r
s_g += g
s_b += b
return (int(x / len(colors)) for x in (s_r, s_g, s_b))


def replace_with_color(
surface: pygame.surface.Surface,
color: tuple[int, int, int],
Expand Down Expand Up @@ -357,8 +343,8 @@ def __init__(
self.value = 0
self.max_value = int(states)
self.anim = anim
self.press_time: float = 1
self.last_press: float = 0
self.press_time: float = 1.0
self.last_press: float = 0.0
self.scan = int(max(get_surf_lens(self.anim)) / 2) + 2

keys = list(kwargs.keys())
Expand Down
15 changes: 9 additions & 6 deletions src/checkers/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
write_position,
)

if TYPE_CHECKING:
from mypy_extensions import u8


async def read_advertisements(
timeout: int = 3, # noqa: ASYNC109
Expand Down Expand Up @@ -304,7 +307,7 @@ async def read_create_piece(self, event: Event[bytearray]) -> None:
buffer = Buffer(event.data)

piece_pos = read_position(buffer)
piece_type = buffer.read_value(StructFormat.UBYTE)
piece_type: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(
Event("gameboard_create_piece", (piece_pos, piece_type)),
Expand Down Expand Up @@ -381,7 +384,7 @@ async def read_update_piece_animation(
buffer = Buffer(event.data)

piece_pos = read_position(buffer)
piece_type = buffer.read_value(StructFormat.UBYTE)
piece_type: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(
Event("gameboard_update_piece_animation", (piece_pos, piece_type)),
Expand Down Expand Up @@ -415,7 +418,7 @@ async def read_game_over(self, event: Event[bytearray]) -> None:
"""Read update_piece event from server."""
buffer = Buffer(event.data)

winner = buffer.read_value(StructFormat.UBYTE)
winner: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(Event("game_winner", winner))
self.running = False
Expand All @@ -430,7 +433,7 @@ async def read_action_complete(self, event: Event[bytearray]) -> None:

from_pos = read_position(buffer)
to_pos = read_position(buffer)
current_turn = buffer.read_value(StructFormat.UBYTE)
current_turn: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(
Event("game_action_complete", (from_pos, to_pos, current_turn)),
Expand All @@ -441,7 +444,7 @@ async def read_initial_config(self, event: Event[bytearray]) -> None:
buffer = Buffer(event.data)

board_size = read_position(buffer)
current_turn = buffer.read_value(StructFormat.UBYTE)
current_turn: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(
Event("game_initial_config", (board_size, current_turn)),
Expand All @@ -451,7 +454,7 @@ async def read_playing_as(self, event: Event[bytearray]) -> None:
"""Read playing_as event from server."""
buffer = Buffer(event.data)

playing_as = buffer.read_value(StructFormat.UBYTE)
playing_as: u8 = buffer.read_value(StructFormat.UBYTE)

await self.raise_event(
Event("game_playing_as", playing_as),
Expand Down
4 changes: 3 additions & 1 deletion src/checkers/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable, Generator, Iterable

from mypy_extensions import u8

T = TypeVar("T")


Expand All @@ -45,7 +47,7 @@ def __init__(
self,
name: str,
data: T,
levels: int = 0,
levels: u8 = 0,
) -> None:
"""Initialize event."""
self.name = name
Expand Down
46 changes: 27 additions & 19 deletions src/checkers/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
__title__ = "Checkers"
__author__ = "CoolCat467"
__license__ = "GNU General Public License Version 3"
__version__ = "2.0.1"
__version__ = "2.0.2"

# Note: Tile Ids are chess board tile titles, A1 to H8
# A8 ... H8
Expand All @@ -34,9 +34,8 @@
import contextlib
import platform
from collections import deque
from os import path
from pathlib import Path
from typing import TYPE_CHECKING, Any, Final, TypeAlias, TypeVar
from typing import TYPE_CHECKING, Any, Final, TypeVar

import pygame
import trio
Expand All @@ -53,7 +52,7 @@
Event,
ExternalRaiseManager,
)
from checkers.network_shared import DEFAULT_PORT, find_ip
from checkers.network_shared import DEFAULT_PORT, Pos, find_ip
from checkers.objects import Button, OutlinedText
from checkers.server import GameServer
from checkers.sound import SoundData, play_sound as base_play_sound
Expand Down Expand Up @@ -105,11 +104,17 @@

T = TypeVar("T")

DATA_FOLDER: Final = Path(__file__).parent / "data"
if globals().get("__file__") is None:
import importlib

IS_WINDOWS: Final = platform.system() == "Windows"
__file__ = str(
Path(importlib.import_module("checkers.data").__path__[0]).parent
/ "game.py",
)

DATA_FOLDER: Final = Path(__file__).absolute().parent / "data"

Pos: TypeAlias = tuple[int, int]
IS_WINDOWS: Final = platform.system() == "Windows"


def render_text(
Expand Down Expand Up @@ -704,7 +709,7 @@ def generate_tile_images(self) -> None:
outline_ident = outline.precalculate_outline(name, outline_color)
image.add_image(f"{name}_outlined", outline_ident)

def get_tile_location(self, position: Pos) -> Vector2:
def get_tile_location(self, position: tuple[int, int]) -> Vector2:
"""Return the center point of a given tile position."""
location = Vector2.from_iter(position) * self.tile_size
center = self.tile_size // 2
Expand Down Expand Up @@ -773,7 +778,7 @@ def generate_board_image(self) -> Surface:
### Blit the id of the tile at the tile's location
##surf.blit(
## render_text(
## trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
## DATA_FOLDER / "VeraSerif.ttf",
## 20,
## "".join(map(str, (x, y))),
## GREEN
Expand Down Expand Up @@ -826,7 +831,7 @@ async def update_selected(self) -> None:

if not self.selected:
movement: sprite.MovementComponent = self.get_component("movement")
movement.speed = 0
movement.speed = 0.0

async def click(self, event: Event[dict[str, int]]) -> None:
"""Toggle selected."""
Expand All @@ -841,15 +846,18 @@ async def drag(self, event: Event[Any]) -> None:
self.selected = True
await self.update_selected()
movement: sprite.MovementComponent = self.get_component("movement")
movement.speed = 0
movement.speed = 0.0

async def mouse_down(self, event: Event[dict[str, int | Pos]]) -> None:
async def mouse_down(
self,
event: Event[dict[str, int | tuple[int, int]]],
) -> None:
"""Target click pos if selected."""
if not self.selected:
return
if event.data["button"] == 1:
movement: sprite.MovementComponent = self.get_component("movement")
movement.speed = 200
movement.speed = 200.0
target: sprite.TargetingComponent = self.get_component("targeting")
assert isinstance(event.data["pos"], tuple)
target.destination = Vector2.from_iter(event.data["pos"])
Expand Down Expand Up @@ -944,7 +952,7 @@ class FPSCounter(objects.Text):
def __init__(self) -> None:
"""Initialize FPS counter."""
font = pygame.font.Font(
trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
DATA_FOLDER / "VeraSerif.ttf",
28,
)
super().__init__("fps", font)
Expand Down Expand Up @@ -1112,11 +1120,11 @@ async def entry_actions(self) -> None:
self.id = self.machine.new_group("title")

button_font = pygame.font.Font(
trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
DATA_FOLDER / "VeraSerif.ttf",
28,
)
title_font = pygame.font.Font(
trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
DATA_FOLDER / "VeraSerif.ttf",
56,
)

Expand Down Expand Up @@ -1266,7 +1274,7 @@ def __init__(self) -> None:
self.buttons: dict[tuple[str, int], int] = {}

self.font = pygame.font.Font(
trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
DATA_FOLDER / "VeraSerif.ttf",
28,
)

Expand Down Expand Up @@ -1412,7 +1420,7 @@ async def do_actions(self) -> None:
self.exit_data = (exit_status, message, True)

font = pygame.font.Font(
trio.Path(path.dirname(__file__), "data", "VeraSerif.ttf"),
DATA_FOLDER / "VeraSerif.ttf",
28,
)

Expand Down Expand Up @@ -1503,7 +1511,7 @@ async def async_run() -> None:
client = CheckersClient(event_manager)

background = pygame.image.load(
path.join(path.dirname(__file__), "data", "background.png"),
DATA_FOLDER / "background.png",
).convert()
client.clear(screen, background)

Expand Down
10 changes: 1 addition & 9 deletions src/checkers/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@
TYPE_CHECKING,
Any,
AnyStr,
Generic,
Literal,
NoReturn,
SupportsIndex,
TypeAlias,
)

import trio
Expand All @@ -51,23 +48,18 @@
)

if TYPE_CHECKING:
from collections.abc import Iterable
from types import TracebackType

from typing_extensions import Self

BytesConvertable: TypeAlias = SupportsIndex | Iterable[SupportsIndex]
else:
BytesConvertable = Generic


class NetworkTimeoutError(Exception):
"""Network Timeout Error."""

__slots__ = ()


class NetworkStreamNotConnectedError(RuntimeError):
class NetworkStreamNotConnectedError(Exception):
"""Network Stream Not Connected Error."""

__slots__ = ()
Expand Down
9 changes: 5 additions & 4 deletions src/checkers/network_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Programmed by CoolCat467

# Copyright (C) 2023 CoolCat467
# Copyright (C) 2023-2024 CoolCat467
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -26,6 +26,7 @@
from typing import TYPE_CHECKING, Final, NamedTuple, TypeAlias

import trio
from mypy_extensions import u8

from .base_io import StructFormat

Expand All @@ -37,7 +38,7 @@

DEFAULT_PORT: Final = 31613

Pos: TypeAlias = tuple[int, int]
Pos: TypeAlias = tuple[u8, u8]


class TickEventData(NamedTuple):
Expand All @@ -49,8 +50,8 @@ class TickEventData(NamedTuple):

def read_position(buffer: Buffer) -> Pos:
"""Read a position tuple from buffer."""
pos_x = buffer.read_value(StructFormat.UBYTE)
pos_y = buffer.read_value(StructFormat.UBYTE)
pos_x: u8 = buffer.read_value(StructFormat.UBYTE)
pos_y: u8 = buffer.read_value(StructFormat.UBYTE)

return pos_x, pos_y

Expand Down
2 changes: 1 addition & 1 deletion src/checkers/sound.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def play_sound(
"""Play sound with pygame."""
sound_object = mixer.Sound(filename)
sound_object.set_volume(sound_data.volume)
seconds = sound_object.get_length()
seconds: int | float = sound_object.get_length()
if sound_data.maxtime > 0:
seconds = sound_data.maxtime
_channel = sound_object.play(
Expand Down
Loading