Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
f390769
ADD: header example
Segelzwerg Nov 15, 2022
c43cf88
UPDATE: use list for players
Segelzwerg Nov 15, 2022
595a0db
UPDATE: use standard as filename
Segelzwerg Nov 15, 2022
fbf8773
ADD: autosectionlabel extension
Segelzwerg Nov 15, 2022
58956d5
UPDATE: use auto section ref
Segelzwerg Nov 15, 2022
31d0bf2
ENABLE: autosection
Segelzwerg Nov 15, 2022
0e833fa
REMOVE: enumartion
Segelzwerg Nov 15, 2022
53bb906
Merge branch 'setup' into feature/notation_definition
Segelzwerg Nov 15, 2022
e0d485b
UPDATE: enable if invalid reference
Segelzwerg Nov 15, 2022
45c7d15
FIX: ref syntax
Segelzwerg Nov 15, 2022
ada4d3b
REMOVE: language tag
Segelzwerg Nov 15, 2022
6fa573a
REMOVE: fail on warning
Segelzwerg Nov 15, 2022
1b25e96
REMOVE: language at all
Segelzwerg Nov 15, 2022
1cf7d48
REMOVE: caption
Segelzwerg Nov 15, 2022
e687761
FIX: caption header
Segelzwerg Nov 15, 2022
c4118a9
REMOVE: fail on warning
Segelzwerg Nov 15, 2022
f624c83
REMOVE: caption
Segelzwerg Nov 15, 2022
005eedb
Revert "REMOVE: fail on warning"
Segelzwerg Nov 15, 2022
b94bd69
REMOVE: empty line
Segelzwerg Nov 15, 2022
becc601
ADD: language toml tag
Segelzwerg Nov 15, 2022
fa24eb4
FIX: empyt line before code
Segelzwerg Nov 15, 2022
47532e3
REMOVE: fail on warning
Segelzwerg Nov 15, 2022
7efec69
ADD: time and location details
Segelzwerg Nov 15, 2022
2cad108
FIX: array name
Segelzwerg Nov 15, 2022
c11f692
UPDATE: dependencies
Segelzwerg Jul 30, 2023
b73f3f3
Merge branch 'main' into feature/notation_definition
Segelzwerg Jul 30, 2023
fb13763
ADD: stack notation
Segelzwerg Jul 30, 2023
21e6095
ADD: make strings
Segelzwerg Jul 30, 2023
ab0489b
ADD: make strings
Segelzwerg Jul 30, 2023
cc80c86
ADD: players hand
Segelzwerg Jul 30, 2023
313267d
Merge branch 'main' into feature/notation_definition
Segelzwerg Jul 30, 2023
8735169
FIX: lock file
Segelzwerg Jul 30, 2023
4f221fe
ADD: card model
Segelzwerg Jul 30, 2023
8dd38bf
UPDATE: documentation
Segelzwerg Jul 30, 2023
54e99ce
FIX: spacing
Segelzwerg Jul 30, 2023
58cb60c
Create test_card.py
Segelzwerg Jul 31, 2023
ba5fc0e
ADD: general validation
Segelzwerg Jul 31, 2023
998b893
FORMAT
Segelzwerg Jul 31, 2023
e1ac6ab
REFACTOR: rename test
Segelzwerg Jul 31, 2023
f62036f
REMOVE: init
Segelzwerg Jul 31, 2023
a6be886
ADD: more tests
Segelzwerg Jul 31, 2023
daa08f3
FIX: tests
Segelzwerg Jul 31, 2023
afdd286
FIX: test name
Segelzwerg Jul 31, 2023
97be351
WIP: stack
Segelzwerg Oct 6, 2024
7f20625
Merge branch 'main' into feature/notation_definition
Segelzwerg Oct 24, 2024
310aabb
ADD: stack implementation
Segelzwerg Oct 29, 2024
b9ee2c8
ADD: tomlkit
Segelzwerg Oct 29, 2024
42e3aff
ADD: card properties
Segelzwerg Oct 29, 2024
fefe97b
FIX: array of tables
Segelzwerg Oct 29, 2024
d10aa96
REMOVE: tomli_w
Segelzwerg Oct 29, 2024
6caa052
UPDATE: documentation
Segelzwerg Oct 29, 2024
6b65dd2
ADD: team flake config
Segelzwerg Oct 29, 2024
342cc33
REFACTOR: constants
Segelzwerg Oct 29, 2024
e785d7e
UPDATE: use seat instead of names
Segelzwerg Nov 1, 2024
1bbc37e
ADD: builder player
Segelzwerg Nov 1, 2024
037aa1c
ADD: player class
Segelzwerg Nov 1, 2024
6f4e141
ADD: header
Segelzwerg Nov 1, 2024
a92d4a5
UPDATE: check for pausible team setups
Segelzwerg Nov 1, 2024
e0b314d
FIX: player names
Segelzwerg Nov 2, 2024
2d2c82b
UPDATE: test edge cases
Segelzwerg Nov 2, 2024
2154797
ADD: player dict
Segelzwerg Nov 2, 2024
cadbc24
ADD: card dict
Segelzwerg Nov 2, 2024
f5b48a7
ADD: location support
Segelzwerg Nov 2, 2024
82398a0
UPDATE: documentation
Segelzwerg Nov 2, 2024
92177ed
Update notation/header.py
Segelzwerg Nov 2, 2024
8f6c775
Update docs/source/standard.rst
Segelzwerg Nov 2, 2024
6ea1087
Update docs/source/standard.rst
Segelzwerg Nov 2, 2024
5e71ae3
REMOVE: unused row
Segelzwerg Nov 2, 2024
07471a5
UPDATE: move seat to attribute
Segelzwerg Nov 2, 2024
9db26c6
UPDATE: tests
Segelzwerg Nov 2, 2024
4af5909
FIX: f string notation
Segelzwerg Nov 2, 2024
66f81bf
REMOVE: double wrap
Segelzwerg Nov 2, 2024
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
15 changes: 15 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[flake8]
exclude =
.git
.github
.venv
__pycache__
.eggs
*.egg
*.egg-info
build
dist
venv
ignore = D200, D204, D205, D400, D401
max-line-length = 100
max-complexity = 10
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build:

sphinx:
configuration: docs/source/conf.py

formats:
- pdf

Expand Down
5 changes: 3 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'autoapi.extension'
'autoapi.extension',
'sphinx.ext.autosectionlabel',
]

autoapi_dirs = ['../../notation']

autosectionlabel_prefix_document = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

Expand Down
5 changes: 4 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. Whist-Core documentation master file, created by
.. Notations documentation master file, created by
sphinx-quickstart on Mon May 10 14:28:49 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Expand All @@ -12,6 +12,9 @@ Welcome to Notation's documentation!

autoapi/notation/index.rst


:ref:`standard:Card Game Notation Standard`

Indices and tables
==================

Expand Down
55 changes: 55 additions & 0 deletions docs/source/standard.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Card Game Notation Standard
===========================
This standard uses TOML_ as notation language.
Comment thread
iTitus marked this conversation as resolved.

Header
-------
All meta data is defined in the Header.
This contains information about teams and players.
Furthermore, the location and datetime is stated.

.. code-block:: toml

[header]
# Timestamp of the starting time in RFC 3339
timestamp = 2022-08-06T11:22:00
# Location of the game or the server url
location = "Hamburg"
# Unsigned Integer
number_of_teams = 2
[[players]]
# Unsigned Integer: ID of team starting with 0
team = 0
name = "John"
[[players]]
team = 1
Name = "Lucy"

Stack
-----
The data contains one mandatory field ``stack`` that is a list of strings representing a card.
Furthermore it has an optional field ``hands`` that is a table of the players' cards in hand.
One card can be represented with

.. code-block:: toml

suit = "[♦♣♥♠]"
rank = "[2-10JQKA]"
Comment thread
iTitus marked this conversation as resolved.

.. code-block:: toml


[[stack]]
suit="heart"
rank="A"
[[stack]]
suit="heart"
rank="K"

[[hands.player_1]]
[[hands.player_1.card]]
Comment thread
iTitus marked this conversation as resolved.
suit="heart"
rank="2"


.. _TOML: https://toml.io/en/
70 changes: 70 additions & 0 deletions notation/card.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Python implementation of a general card and specific versions."""
import tomlkit

FRENCH_SUITS = ('♦', '♣', '♥', '♠')

FRENCH_RANKS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K')


class Card:
"""General representation of a card."""

def __init__(self, suit: str, rank: str) -> None:
"""
Construct a card.

:param suit: The suit of the card.
:param rank: The rank of the card.
"""
self._suit: str = self._valid_suit(suit)
self._rank: str = self._valid_rank(rank)

@staticmethod
def _valid_suit(suit: str) -> str:
if not isinstance(suit, str):
raise ValueError('Suit must be string.')
if not suit:
raise ValueError('Suit cannot be empty.')
return suit

@staticmethod
def _valid_rank(rank: str) -> str:
if not isinstance(rank, str):
raise ValueError('Rank must be string.')
if not rank:
raise ValueError('Rank must not be empty.')
return rank

@property
def suit(self) -> str:
"""Returns the suit of a card as string."""
return self._suit

@property
def rank(self) -> str:
"""Returns the rank of a card as string."""
return self._rank

def dumps(self) -> str:
"""Return the card as TOML string."""
return tomlkit.dumps(self.dict())

def dict(self):
"""Return the card as dictionary."""
return {'suit': self._suit, 'rank': self._rank}


class FrenchCard(Card):
"""Represents a French card."""

@staticmethod
def _valid_suit(suit: str) -> str:
if suit not in FRENCH_SUITS:
raise ValueError('Not a correct french suit.')
return suit

@staticmethod
def _valid_rank(rank: str) -> str:
if rank not in FRENCH_RANKS:
raise ValueError('Not a correct french rank.')
return rank
39 changes: 39 additions & 0 deletions notation/header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Header containing the meta data of a game."""
from datetime import datetime
from typing import Optional

import tomlkit

from notation.player import Player


# pylint: disable=too-few-public-methods
class Header:
"""Class implementation of a meta data wrapper."""

def __init__(self, start_time: datetime, players: list[Player],
number_teams: int, location: Optional[str] = None, ):
"""Constructor.
:param start_time: The start time of the game as datetime object
:param players: The list of players.
:param number_teams: The number of teams.
:param location: Optional. Where the game to place.
"""
self._start_time: datetime = start_time
self._location = location
if players is None or len(players) == 0:
raise ValueError('Player list cannot be empty')
if number_teams > len(players):
raise ValueError('Number teams cannot be greater than amount of players')
self._players = players
self._number_teams = number_teams

def dumps(self) -> str:
"""Return a TOML string representation of the header."""
players = [tomlkit.dumps({'players': [player.dict()]}) for player in self._players]
header_dump = {'header': {'timestamp': self._start_time.isoformat(),
'number_of_teams': self._number_teams}}
if self._location:
header_dump['header']['location'] = self._location
player_string = '\n'.join(players)
return f'{tomlkit.dumps(header_dump)}\n{player_string}'
20 changes: 20 additions & 0 deletions notation/player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Wrapper for player data."""


# pylint: disable=too-few-public-methods
class Player:
"""Class containing player data."""

def __init__(self, name: str, team: int, seat: int):
"""Constructs
:param name: name of player
:param team: integer of the team ID
:param seat: The unique identifier of place at table for that player.
"""
self._name = name
self._team = team
self._seat = seat

def dict(self) -> dict[str, str]:
"""Return player data as dictionary."""
return {'name': self._name, 'team': self._team, 'seat': self._seat}
24 changes: 24 additions & 0 deletions notation/stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Implementation of a stack of cards."""
from typing import List

import tomlkit

from notation.card import Card


# pylint: disable=too-few-public-methods
class Stack:
"""A list of cards."""

def __init__(self, cards: List[Card]):
"""
Construct a stack of cards.

:param cards: A list of cards.
"""
self._card_list: List[Card] = cards

def dumps(self) -> str:
"""Return the stack as TOML string."""
card_dump = [card.dict() for card in self._card_list]
return tomlkit.dumps({'stack': card_dump})
Loading