From fa045c235f6c6b56756d0259359111bd1e1fa0e9 Mon Sep 17 00:00:00 2001 From: legonzaur Date: Sat, 20 Apr 2024 14:30:03 +0200 Subject: [PATCH] add PLAY_NEXT_CARD_BOUGHT CardEffect --- src/controller/client.py | 11 ++++- src/model/__init__.py | 1 + src/model/card_board.py | 13 ++++++ src/model/card_validator.py | 1 + src/model/player.py | 91 ++++++++++++++++++++++++++++++++++--- 5 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 src/model/card_board.py diff --git a/src/controller/client.py b/src/controller/client.py index b89bf1b..1f9e78e 100644 --- a/src/controller/client.py +++ b/src/controller/client.py @@ -78,8 +78,14 @@ class ClientController(ClientControllerInterface): @vibe_check(Message) async def game_context(self, message: Message): - - print(message) + if self.player.team != self.game_controller.game.turn: + return await self.send_error("it is not your turn to play!") + if message.type == "action": + if message.data_type == "buy": + for c in message.data: + await self.player.buy_card(c) + elif message.data_type == "play_cards": + await self.player.play_cards(message.data) @vibe_check(LoginMessage) async def login_context(self, message: LoginMessage): @@ -143,3 +149,4 @@ class ClientController(ClientControllerInterface): self.player.ready = bool(message.data) if all(p.ready for p in self.game_controller.game.players): await self.game_controller.start_game() + self.on_message = self.game_context diff --git a/src/model/__init__.py b/src/model/__init__.py index 742a72d..782d8b1 100644 --- a/src/model/__init__.py +++ b/src/model/__init__.py @@ -9,6 +9,7 @@ from model.card_validator import ( ) from model.card_loader import load_cards from model.card import Card +from model.card_board import BoardCard from model.team import Team from model.player import Player from model.game import Game diff --git a/src/model/card_board.py b/src/model/card_board.py new file mode 100644 index 0000000..24dc009 --- /dev/null +++ b/src/model/card_board.py @@ -0,0 +1,13 @@ +from typing import List +from model import Card, Serializable + + +class BoardCard(Serializable): + """Represents a card on a player's board during a game turn""" + + def __init__(self, card: Card): + super().__init__() + self.card = card + + def reset(self): + pass diff --git a/src/model/card_validator.py b/src/model/card_validator.py index a0bdf42..7667d89 100644 --- a/src/model/card_validator.py +++ b/src/model/card_validator.py @@ -46,6 +46,7 @@ class CardEffects(str, Enum): RESTACK_DISCARDED_CARD = "restack_discarded_card" STACK_NEXT_ACTION_BOUGHT = "stack_next_action_bought" STACK_NEXT_CARD_BOUGHT = "stack_next_card_bough" + PLAY_NEXT_CARD_BOUGHT = "play_next_card_bought" class EffectTimes(str, Enum): diff --git a/src/model/player.py b/src/model/player.py index c810d7b..0fe39a8 100644 --- a/src/model/player.py +++ b/src/model/player.py @@ -1,7 +1,8 @@ +import asyncio import random from typing import List -from model import Card, Team, Serializable +from model import Card, Team, Serializable, BoardCard, CardType class Player(Serializable): @@ -15,7 +16,7 @@ class Player(Serializable): team: Team hand: List[Card] - board: List[Card] + board: List[BoardCard] game: Serializable @@ -39,7 +40,7 @@ class Player(Serializable): self.stack_pile: List[Card] = [] self.discard_pile: List[Card] = [] self.hand: List[Card] = [] - self.board: List[Card] = [] + self.board: List[BoardCard] = [] self.team = team self.username = username @@ -50,7 +51,7 @@ class Player(Serializable): "discard_pile": [card.uuid for card in self.discard_pile], "team": self.team.uuid, "hand": [None for card in self.hand], - "board": [card.uuid for card in self.board], + "board": [card_board.card.uuid for card_board in self.board], } return {k: data[k] for k in data.keys() - ["game"]} @@ -85,7 +86,85 @@ class Player(Serializable): self.hand.append(self.stack_pile.pop()) amount = amount - 1 finally: - await self.team.notify_controller("update", self.serialize_team()) - await self.game.notify_controller( + await self.notify_update() + + async def notify_update(self): + """Correctly updates player data for team and other clients. + To be used whenever the player object needs to be updated""" + + notifies = [] + notifies.append(self.team.notify_controller("update", self.serialize_team())) + notifies.append( + self.game.notify_controller( "update", self.serialize_guest(), lambda p: p.team != self.team ) + ) + + await asyncio.gather(*notifies) + + async def play_cards(self, cards_ids: List[str]): + for s in cards_ids: + card = next( + (m for m in self.hand if str(m.uuid) == s), + None, + ) + if card is None: + print("Card not found in player hand") + continue + self.board.append(BoardCard(card)) + self.hand.remove(card) + await self.notify_update() + + async def discard_card(self, cards_ids: List[str]): + pass + + async def end_turn(self): + for c in self.board: + if c.card.card_type in [ + CardType.HERO, + CardType.HERO_ABILITY, + CardType.CHAMPION, + ]: + c.reset() + else: + self.board.remove(c) + self.discard_pile.append(c.card) + + for c in self.hand: + self.hand.remove(c) + self.discard_pile.append(c) + + await self.draw(5) + + async def buy_card(self, card_id: str): + card = next( + ( + m + for m in [f for f in self.game.market if f is not None] + if str(m.uuid) == card_id + ), + None, + ) + if card is not None: + index = self.game.market.index(card) + self.game.market[index] = None + self.discard_pile.append(card) + await self.game.distribute_market_cards() + else: + card = next( + ( + m + for m in [f for f in self.game.gem_stack if f is not None] + if str(m.uuid) == card_id + ), + None, + ) + if card is not None: + self.game.gem_stack.remove(card) + self.discard_pile.append(card) + await self.game.notify_controller("update", self.game.serialize_guest()) + else: + print("Card not found in market or gem_stack") + return + + await self.notify_update()