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
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
checks:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: '3.12'
- name: Install dependencies
run: uv sync
- name: Run lint
run: uv run ruff check
- name: Run type-check
run: uv run pyrefly check --summarize-errors
- name: Run tests
run: uv run pytest -v

build:
runs-on: ubuntu-latest
needs: checks
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: '3.12'
- name: Build
run: uv build --wheel
5 changes: 2 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# This is a sample Python script.
from clanker_bench.agents.agent import Agent
from clanker_bench.agents.random_agent import RandomAgent
from clanker_bench.game.setup import new_game
from clanker_bench.runner.run import play_game

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
if __name__ == "__main__":
random_agents: list[Agent] = [RandomAgent() for i in range(3)]
play_game(random_agents, 0)


# See PyCharm help at https://www.jetbrains.com/help/pycharm/
39 changes: 38 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,51 @@ version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.13.4",
"pyrefly>=0.60.0",
]

[dependency-groups]
dev = [
"hypothesis>=6.155.7",
"pytest>=9.1.1",
"ruff>=0.15.21",
]


[tool.pytest.ini_options]
pythonpath = ["src", "tests"]
pythonpath = ["src", "tests"]

[tool.ruff.lint]
extend-select = [
"F", # Pyflakes rules
"W", # PyCodeStyle warnings
"E", # PyCodeStyle errors
"I", # Sort imports properly
"UP", # Warn if certain things can changed due to newer Python versions
"C4", # Catch incorrect use of comprehensions, dict, list, etc
"FA", # Enforce from __future__ import annotations
"ISC", # Good use of string concatenation
"ICN", # Use common import conventions
"RET", # Good return practices
"SIM", # Common simplification rules
"TID", # Some good import practices
"TC", # Enforce importing certain types in a TYPE_CHECKING block
"PTH", # Use pathlib instead of os.path
"TD", # Be diligent with TO-DO comments
"NPY", # Some numpy-specific things
"A", # detect shadowed builtins
"BLE", # disallow catch-all exceptions
"COM", # enforce trailing comma rules
"FBT", # detect boolean traps
"N", # enforce naming conventions, e.g. ClassName vs function_name
]

ignore = ["E501"] # Formatter does that

[tool.pyrefly]
project-includes = [
"**/*.py*",
"**/*.ipynb",
]

search-path = ["src", "."]
6 changes: 4 additions & 2 deletions src/clanker_bench/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@

class Agent(ABC):
@abstractmethod
def act(self, observation: Observation, action_space: tuple[GameAction, ...]) -> GameAction:
pass
def act(
self, observation: Observation, action_space: tuple[GameAction, ...],
) -> GameAction:
pass
10 changes: 7 additions & 3 deletions src/clanker_bench/agents/random_agent.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import random

from clanker_bench.agents.agent import Agent
from clanker_bench.game.model.action import GameAction
from clanker_bench.game.model.gamestate import Observation
import random


class RandomAgent(Agent):
def act(self, observation: Observation, action_space: tuple[GameAction, ...]) -> GameAction:
rng = random.randint(0, len(action_space)-1)
def act(
self, observation: Observation, action_space: tuple[GameAction, ...],
) -> GameAction:
rng = random.randint(0, len(action_space) - 1)
return action_space[rng]
13 changes: 7 additions & 6 deletions src/clanker_bench/game/deck.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import random
from typing import Sequence
from collections.abc import Sequence

from clanker_bench.game.model.card import Card, Suit


def shuffle_deck(cards: Sequence[Card], rng: random.Random) -> list[Card]:
shuffled_deck = list(cards)
rng.shuffle(shuffled_deck)
Expand All @@ -11,19 +12,21 @@ def shuffle_deck(cards: Sequence[Card], rng: random.Random) -> list[Card]:

def init_deck() -> list[Card]:
cards: list[Card] = []
for (suit) in Suit:
for suit in Suit:
if suit == Suit.CLANKER or suit == Suit.SINGULARITY:
cards.extend([Card(suit=suit)] * 4)
continue
for rank in range(13):
cards.append(Card(suit=suit, rank=rank + 1))
return cards


def deal_cards(current_round: int, deck: list[Card]) -> tuple[list[Card], list[Card]]:
dealt = deck[:current_round]
remaining = deck[current_round:]
return dealt, remaining


def determine_trump(card_list: list[Card]) -> tuple[None | Suit, bool]:
if not card_list:
return None, False
Expand All @@ -32,8 +35,6 @@ def determine_trump(card_list: list[Card]) -> tuple[None | Suit, bool]:
return None, False
if card.suit == Suit.CLANKER:
return None, False
elif card.suit == Suit.SINGULARITY:
if card.suit == Suit.SINGULARITY:
return None, True
else:
return card.suit, False

return card.suit, False
Loading
Loading