Skip to content

Commit

Permalink
Merge pull request #258 from Whist-Team/feature/next_rubber
Browse files Browse the repository at this point in the history
FEATURE: next rubber
  • Loading branch information
iTitus authored Nov 8, 2022
2 parents 6a10d74 + 90cd96f commit bec2618
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 20 deletions.
58 changes: 48 additions & 10 deletions tests/whist_core/session/test_table.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from unittest.mock import patch

from tests.whist_core.base_test_case import BaseTestCase
from whist_core.error.table_error import TeamFullError, TableFullError, TableNotReadyError, \
TableNotStartedError, PlayerNotJoinedError, TableSettingsError
from whist_core.game.errors import RubberNotDoneError
from whist_core.game.rubber import Rubber
from whist_core.session.matcher import RandomMatcher, RoundRobinMatcher
from whist_core.session.table import Table
Expand Down Expand Up @@ -68,36 +71,71 @@ def test_join_full_table(self):

def test_conversion(self):
self.table.join(self.player)
table_dict = self.table.dict()
table_dict = self.table.dict(exclude={'matcher'})
table = Table(**table_dict)
self.assertEqual(self.table, table)

def test_start_random(self):
table = Table(name='test table', min_player=1, max_player=4, matcher=RandomMatcher())
second_player = Player(username='miles', rating=3000)
self.table.join(self.player)
self.table.join(second_player)
self.table.player_ready(self.player)
self.table.player_ready(second_player)
self.table.start(RandomMatcher)
self.assertTrue(self.table.started)
self.assertIsInstance(self.table.current_rubber, Rubber)
table.join(self.player)
table.join(second_player)
table.player_ready(self.player)
table.player_ready(second_player)
table.start()
self.assertTrue(table.started)
self.assertIsInstance(table.current_rubber, Rubber)
self.assertTrue(isinstance(table.matcher, RandomMatcher))

def test_start_robin(self):
second_player = Player(username='miles', rating=3000)
self.table.join(self.player)
self.table.join(second_player)
self.table.player_ready(self.player)
self.table.player_ready(second_player)
self.table.start(RoundRobinMatcher)
self.table.start()
self.assertTrue(self.table.started)
self.assertIsInstance(self.table.current_rubber, Rubber)
self.assertTrue(isinstance(self.table.matcher, RoundRobinMatcher))

def test_not_ready_start(self):
self.table.join(self.player)
with self.assertRaises(TableNotReadyError):
self.table.start(RandomMatcher)
self.table.start()
self.assertFalse(self.table.started)

def test_rubber_without_start(self):
with self.assertRaises(TableNotStartedError):
_ = self.table.current_rubber

def test_next_rubber(self):
second_player = Player(username='miles', rating=3000)
self.table.join(self.player)
self.table.join(second_player)
self.table.player_ready(self.player)
self.table.player_ready(second_player)
self.table.start()
with patch('whist_core.game.rubber.Rubber.done', return_value=True):
self.table.next_rubber()
self.assertEqual(2, len(self.table.rubbers))

def test_next_rubber_not_done(self):
second_player = Player(username='miles', rating=3000)
self.table.join(self.player)
self.table.join(second_player)
self.table.player_ready(self.player)
self.table.player_ready(second_player)
self.table.start()
with self.assertRaises(RubberNotDoneError):
self.table.next_rubber()
self.assertEqual(1, len(self.table.rubbers))

def test_next_rubber_first(self):
second_player = Player(username='miles', rating=3000)
self.table.join(self.player)
self.table.join(second_player)
self.table.player_ready(self.player)
self.table.player_ready(second_player)
with self.assertRaises(TableNotStartedError):
self.table.next_rubber()
self.assertEqual(0, len(self.table.rubbers))
6 changes: 6 additions & 0 deletions whist_core/game/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ class NoTrumpSelectedError(Exception):
"""


class RubberNotDoneError(Exception):
"""
Raised if the current rubber is not done, but action requested requires it to be done.
"""


class TrickDoneError(Exception):
"""
Raised when the trick is already done.
Expand Down
4 changes: 3 additions & 1 deletion whist_core/session/matcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import abc
import random

from pydantic import BaseModel

from whist_core.error.matcher_error import NotEnoughPlayersError
from whist_core.scoring.team import Team
from whist_core.session.userlist import UserList


# pylint: disable=too-few-public-methods
class Matcher(abc.ABC):
class Matcher(abc.ABC, BaseModel):
"""
Abstrakt class for player to teams matching.
"""
Expand Down
37 changes: 28 additions & 9 deletions whist_core/session/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

from whist_core.error.table_error import TableFullError, TeamFullError, TableNotReadyError, \
TableNotStartedError, TableSettingsError
from whist_core.game.errors import RubberNotDoneError
from whist_core.game.rubber import Rubber
from whist_core.session.matcher import Matcher
from whist_core.session.matcher import Matcher, RoundRobinMatcher
from whist_core.session.session import Session
from whist_core.user.player import Player

Expand All @@ -18,6 +19,7 @@ class Table(Session):
team_size: int = 2
started: bool = False
rubbers: list[Rubber] = []
matcher: Matcher = RoundRobinMatcher()

# pylint: disable=no-self-argument
@root_validator(pre=True)
Expand Down Expand Up @@ -67,20 +69,27 @@ def current_rubber(self) -> Rubber:
raise TableNotStartedError()
return self.rubbers[-1]

def start(self, matcher: Matcher) -> None:
def next_rubber(self) -> Rubber:
"""
Creates the next rubber. In order to create the first rubber use 'Table.start()'.
:return: the new rubber
"""
if len(self.rubbers) == 0:
raise TableNotStartedError()
if self.rubbers[-1].done:
self.rubbers.append(self._create_rubber())
else:
raise RubberNotDoneError()
return self.current_rubber

def start(self) -> None:
"""
Starts the table, but will check if every player is ready first.
"""
if not self.ready:
raise TableNotReadyError()

team_numbers = 2
players_available_per_team = int(len(self.users) / team_numbers)
teams = matcher.distribute(num_teams=team_numbers,
team_size=min(players_available_per_team, self.team_size),
users=self.users)
rubber = Rubber(teams=teams)
self.rubbers.append(rubber)
self.rubbers.append(self._create_rubber())
self.started = True

def join(self, player: Player) -> None:
Expand Down Expand Up @@ -142,3 +151,13 @@ def player_unready(self, player) -> None:
:rtype: None
"""
self.users.player_unready(player)

def _create_rubber(self):
team_numbers = 2
players_available_per_team = int(len(self.users) / team_numbers)
teams = self.matcher.distribute(num_teams=team_numbers,
team_size=min(players_available_per_team,
self.team_size),
users=self.users)
rubber = Rubber(teams=teams)
return rubber

0 comments on commit bec2618

Please sign in to comment.