diff --git a/backend/bang/expansions/dodge_city/characters.py b/backend/bang/expansions/dodge_city/characters.py index 81db24f..1f287e3 100644 --- a/backend/bang/expansions/dodge_city/characters.py +++ b/backend/bang/expansions/dodge_city/characters.py @@ -1,5 +1,6 @@ from typing import List from bang.characters import Character +from globals import PendingAction class PixiePete(Character): @@ -165,8 +166,6 @@ class DocHolyday(Character): def special(self, player, data): if super().special(player, data): - from bang.players import PendingAction - if ( player.special_use_count < 1 and player.pending_action == PendingAction.PLAY diff --git a/backend/bang/expansions/gold_rush/shop_cards.py b/backend/bang/expansions/gold_rush/shop_cards.py index 5ff68c9..e75a3ae 100644 --- a/backend/bang/expansions/gold_rush/shop_cards.py +++ b/backend/bang/expansions/gold_rush/shop_cards.py @@ -1,7 +1,7 @@ from bang.cards import * import bang.roles as r import bang.players as pl -from globals import G +from globals import G, PendingAction class ShopCardKind(IntEnum): BROWN = 0 # Se l’equipaggiamento ha il bordo marrone, applicane subito l’effetto e poi scartalo. @@ -47,7 +47,7 @@ class Bicchierino(ShopCard): 'is_player': True } for p in player.game.get_alive_players()] player.choose_text = 'choose_bicchierino' - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.notify_self() return super().play_card(player, against, _with) @@ -64,7 +64,7 @@ class Bottiglia(ShopCard): for i in range(len(player.available_cards)): player.available_cards[i].must_be_used = True player.choose_text = 'choose_bottiglia' - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.notify_self() return super().play_card(player, against, _with) @@ -79,7 +79,7 @@ class Complice(ShopCard): for i in range(len(player.available_cards)): player.available_cards[i].must_be_used = True player.choose_text = 'choose_complice' - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.notify_self() return super().play_card(player, against, _with) @@ -175,7 +175,7 @@ class Ricercato(ShopCard): } for p in player.game.get_alive_players() if p != player and not isinstance(p.role, r.Sheriff)] player.available_cards.append({'name': player.name, 'number':0,'icon': 'you', 'is_character': True}) player.choose_text = 'choose_ricercato' - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.notify_self() return True # la giochi su un altro giocatore, ricompensa di 2 carte e 1 pepita a chi lo uccide diff --git a/backend/bang/expansions/the_valley_of_shadows/cards.py b/backend/bang/expansions/the_valley_of_shadows/cards.py index 53f02d8..9a9ca52 100644 --- a/backend/bang/expansions/the_valley_of_shadows/cards.py +++ b/backend/bang/expansions/the_valley_of_shadows/cards.py @@ -3,7 +3,7 @@ import bang.roles as r import bang.players as pl from bang.cards import Card, Suit, Bang, Mancato import bang.expansions.fistful_of_cards.card_events as ce -from globals import G +from globals import G, PendingAction class Fantasma(Card): @@ -15,7 +15,7 @@ class Fantasma(Card): if (player.game.check_event(ce.IlGiudice)) or not self.can_be_used_now: return False if len(player.game.get_dead_players(include_ghosts=False)) > 0: - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.choose_text = "choose_fantasma" player.available_cards = [ { @@ -181,7 +181,7 @@ class Sventagliata( if p["name"] != player.name and p["name"] != t.name and p["dist"] ] if len(player.available_cards) > 0: - player.pending_action = pl.PendingAction.CHOOSE + player.pending_action = PendingAction.CHOOSE player.choose_text = "choose_sventagliata" else: player.available_cards = [] diff --git a/backend/bang/expansions/train_robbery/stations.py b/backend/bang/expansions/train_robbery/stations.py index 88a036d..0d5bfc2 100644 --- a/backend/bang/expansions/train_robbery/stations.py +++ b/backend/bang/expansions/train_robbery/stations.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING import bang.cards as cs -import bang.players as pl +from globals import PendingAction if TYPE_CHECKING: from bang.players import Player @@ -28,7 +28,7 @@ class StationCard: player.game.deck.scrap(card, True, player=player) player.equipment.append(self.attached_train) self.attached_train = None - player.pending_action = pl.PendingAction.PLAY + player.pending_action = PendingAction.PLAY def check_price(self, player: "Player") -> bool: """Check if the card can be used to rob the train""" diff --git a/backend/bang/expansions/train_robbery/trains.py b/backend/bang/expansions/train_robbery/trains.py index 2a4de64..cc95533 100644 --- a/backend/bang/expansions/train_robbery/trains.py +++ b/backend/bang/expansions/train_robbery/trains.py @@ -1,8 +1,13 @@ import random from bang.cards import Card, Bang, Panico, CatBalou, Mancato -from bang.players import Player, PendingAction +from typing import TYPE_CHECKING + from globals import G +if TYPE_CHECKING: + from bang.players import Player, PendingAction + + class TrainCard(Card): def __init__(self, name: str, is_locomotive: bool = False): super().__init__(suit=5, number=0, name=name) @@ -103,7 +108,7 @@ class BaggageCar(TrainCard): super().__init__("Baggage Car") self.icon = "🚋🛄" - def choose_callback(self, player: Player, card_index): + def choose_callback(self, player: 'Player', card_index): player.hand.append(player.available_cards[card_index]) player.pending_action = PendingAction.PLAY @@ -227,7 +232,7 @@ class MailCar(TrainCard): super().__init__("Mail Car") self.icon = "🚋📮" - def choose_card_callback(self, player: Player, card_index): + def choose_card_callback(self, player: 'Player', card_index): chosen_card = player.available_cards.pop(card_index) player.hand.extend(player.available_cards) player.set_choose_action( @@ -236,7 +241,7 @@ class MailCar(TrainCard): lambda p, other_player_index: self.choose_player_callback(p, other_player_index, chosen_card) ) - def choose_player_callback(self, player: Player, other_player_index, chosen_card): + def choose_player_callback(self, player: 'Player', other_player_index, chosen_card): pl_name = player.game.get_other_players(player)[other_player_index]["name"] other_player = player.game.get_player_named(pl_name) other_player.hand.append(chosen_card) @@ -311,8 +316,22 @@ class SleeperCar(TrainCard): super().__init__("Sleeper Car") self.icon = "🚋🛌" + def choose_card_callback(self, player: 'Player', card_index): + player.game.deck.scrap(player.equipment.pop(card_index), player=player) + player.pending_action = PendingAction.PLAY + self.usable_next_turn = True + self.can_be_used_now = False + player.notify_self() + def play_card(self, player, against=None, _with=None) -> bool: - return True + if not self.can_be_used_now: + return False + player.set_choose_action( + "choose_sleeper_car", + player.equipment, + self.choose_card_callback, + ) + return False def get_all_cards(rng=random): diff --git a/backend/bang/game.py b/backend/bang/game.py index 92e72b6..8dcd5d3 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -18,7 +18,7 @@ import bang.expansions.gold_rush.shop_cards as grc import bang.expansions.gold_rush.characters as grch import bang.expansions.the_valley_of_shadows.cards as tvosc from metrics import Metrics -from globals import G +from globals import G, PendingAction debug_commands = [ @@ -464,7 +464,7 @@ class Game: def discard_others(self, attacker: pl.Player, card_name: str = None): self.attack_in_progress = True - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.waiting_for = 0 self.ready_count = 0 @@ -474,7 +474,7 @@ class Game: self.waiting_for += 1 p.notify_self() if self.waiting_for == 0: - attacker.pending_action = pl.PendingAction.PLAY + attacker.pending_action = PendingAction.PLAY attacker.notify_self() self.attack_in_progress = False elif card_name == "Poker": @@ -482,7 +482,7 @@ class Game: def attack_others(self, attacker: pl.Player, card_name: str = None): self.attack_in_progress = True - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.waiting_for = 0 self.ready_count = 0 @@ -492,7 +492,7 @@ class Game: self.waiting_for += 1 p.notify_self() if self.waiting_for == 0: - attacker.pending_action = pl.PendingAction.PLAY + attacker.pending_action = PendingAction.PLAY attacker.notify_self() self.attack_in_progress = False if self.pending_winners and not self.someone_won: @@ -500,7 +500,7 @@ class Game: def indian_others(self, attacker: pl.Player): self.attack_in_progress = True - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.waiting_for = 0 self.ready_count = 0 @@ -510,7 +510,7 @@ class Game: self.waiting_for += 1 p.notify_self() if self.waiting_for == 0: - attacker.pending_action = pl.PendingAction.PLAY + attacker.pending_action = PendingAction.PLAY attacker.notify_self() self.attack_in_progress = False if self.pending_winners and not self.someone_won: @@ -547,11 +547,11 @@ class Game: self.attack_in_progress = True self.ready_count = 0 self.waiting_for = 1 - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() elif not attacker.is_my_turn or len(self.attack_queue) == 0: - self.players[self.turn].pending_action = pl.PendingAction.PLAY + self.players[self.turn].pending_action = PendingAction.PLAY def steal_discard(self, attacker: pl.Player, target_username: str, card: cs.Card): p = self.get_player_named(target_username) @@ -562,11 +562,11 @@ class Game: ): self.ready_count = 0 self.waiting_for = 1 - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() else: - attacker.pending_action = pl.PendingAction.CHOOSE + attacker.pending_action = PendingAction.CHOOSE attacker.target_p = target_username if isinstance(card, cs.CatBalou): attacker.choose_action = "discard" @@ -580,7 +580,7 @@ class Game: ): self.ready_count = 0 self.waiting_for = 1 - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() @@ -588,14 +588,14 @@ class Game: if self.get_player_named(target_username).get_dueled(attacker=attacker): self.ready_count = 0 self.waiting_for = 1 - attacker.pending_action = pl.PendingAction.WAIT + attacker.pending_action = PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() def emporio(self): pls = self.get_alive_players() self.available_cards = [self.deck.draw(True) for i in range(len(pls))] - self.players[self.turn].pending_action = pl.PendingAction.CHOOSE + self.players[self.turn].pending_action = PendingAction.CHOOSE self.players[self.turn].choose_text = "choose_card_to_get" self.players[self.turn].available_cards = self.available_cards G.sio.emit( @@ -617,7 +617,7 @@ class Game: ) player.hand.append(card) player.available_cards = [] - player.pending_action = pl.PendingAction.WAIT + player.pending_action = PendingAction.WAIT player.notify_self() pls = self.get_alive_players() next_player = pls[ @@ -636,14 +636,14 @@ class Game: next_player.hand.append(self.available_cards.pop()) next_player.notify_self() G.sio.emit("emporio", room=self.name, data='{"name":"","cards":[]}') - self.players[self.turn].pending_action = pl.PendingAction.PLAY + self.players[self.turn].pending_action = PendingAction.PLAY self.players[self.turn].notify_self() elif next_player == self.players[self.turn]: G.sio.emit("emporio", room=self.name, data='{"name":"","cards":[]}') - self.players[self.turn].pending_action = pl.PendingAction.PLAY + self.players[self.turn].pending_action = PendingAction.PLAY self.players[self.turn].notify_self() else: - next_player.pending_action = pl.PendingAction.CHOOSE + next_player.pending_action = PendingAction.CHOOSE next_player.choose_text = "choose_card_to_get" next_player.available_cards = self.available_cards G.sio.emit( @@ -729,7 +729,7 @@ class Game: elif self.poker_on and not any( c.number == 1 for c in self.deck.scrap_pile[-tmp:] ): - self.players[self.turn].pending_action = pl.PendingAction.CHOOSE + self.players[self.turn].pending_action = PendingAction.CHOOSE self.players[ self.turn ].choose_text = f"choose_from_poker;{min(2, tmp)}" @@ -740,10 +740,10 @@ class Game: print("attack completed, next attack") atk = self.attack_queue.pop(0) self.attack(atk[0], atk[1], atk[2], atk[3], skip_queue=True) - elif self.players[self.turn].pending_action == pl.PendingAction.CHOOSE: + elif self.players[self.turn].pending_action == PendingAction.CHOOSE: self.players[self.turn].notify_self() else: - self.players[self.turn].pending_action = pl.PendingAction.PLAY + self.players[self.turn].pending_action = PendingAction.PLAY self.poker_on = False self.players[self.turn].notify_self() @@ -1036,9 +1036,9 @@ class Game: self.deck.draw(True, player=player.attacker) player.attacker.notify_self() print(f"{self.name}: player {player.name} died") - if self.waiting_for > 0 and player.pending_action == pl.PendingAction.RESPOND: + if self.waiting_for > 0 and player.pending_action == PendingAction.RESPOND: self.responders_did_respond_resume_turn() - player.pending_action = pl.PendingAction.WAIT + player.pending_action = PendingAction.WAIT if player.is_dead: return diff --git a/backend/bang/players.py b/backend/bang/players.py index fe90547..95b58b8 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -1,5 +1,4 @@ from __future__ import annotations -from enum import IntEnum import json from random import randrange, sample, uniform, randint import bang.roles as r @@ -16,9 +15,10 @@ import bang.expansions.gold_rush.characters as grch import bang.expansions.the_valley_of_shadows.cards as tvosc import bang.expansions.the_valley_of_shadows.characters as tvosch import bang.expansions.train_robbery.stations as trs +import bang.expansions.train_robbery.trains as trt from typing import List, TYPE_CHECKING, Callable from metrics import Metrics -from globals import G +from globals import G, PendingAction import sys if TYPE_CHECKING: @@ -44,15 +44,6 @@ robot_pictures = [ ] -class PendingAction(IntEnum): - PICK = 0 - DRAW = 1 - PLAY = 2 - RESPOND = 3 - WAIT = 4 - CHOOSE = 5 - - class Player: def is_admin(self): return self.discord_id in {"244893980960096266", "539795574019457034"} @@ -2556,7 +2547,6 @@ class Player: self.notify_self() def buy_train(self, index): - import bang.expansions.train_robbery.trains as trt if self.pending_action != PendingAction.PLAY: return print( @@ -2701,6 +2691,8 @@ class Player: and not self.equipment[i].can_be_used_now ): self.equipment[i].can_be_used_now = True + if isinstance(self.equipment[i], trt.TrainCard): + self.equipment[i].usable_next_turn = False for i in range(len(self.hand)): if self.hand[i].must_be_used: self.hand[i].must_be_used = False diff --git a/backend/globals.py b/backend/globals.py index 2c31932..3d4f607 100644 --- a/backend/globals.py +++ b/backend/globals.py @@ -1,6 +1,17 @@ +from enum import IntEnum + class G: sio = None def __init__(self): - pass \ No newline at end of file + pass + + +class PendingAction(IntEnum): + PICK = 0 + DRAW = 1 + PLAY = 2 + RESPOND = 3 + WAIT = 4 + CHOOSE = 5 diff --git a/backend/server.py b/backend/server.py index 441f228..cac1360 100644 --- a/backend/server.py +++ b/backend/server.py @@ -16,8 +16,8 @@ import socketio from discord_webhook import DiscordWebhook from bang.game import Game -from bang.players import PendingAction, Player -from globals import G +from bang.players import Player +from globals import G, PendingAction from metrics import Metrics sys.setrecursionlimit(10**6) # this should prevents bots from stopping diff --git a/backend/tests/cards_test.py b/backend/tests/cards_test.py index 67732f7..91cdacc 100644 --- a/backend/tests/cards_test.py +++ b/backend/tests/cards_test.py @@ -3,7 +3,8 @@ from bang.characters import Character from bang.cards import * from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player +from globals import PendingAction # test card Barile def test_barile(): diff --git a/backend/tests/character_test.py b/backend/tests/character_test.py index 3963f97..fdc5ad5 100644 --- a/backend/tests/character_test.py +++ b/backend/tests/character_test.py @@ -2,7 +2,8 @@ from random import randint from bang.characters import * from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player +from globals import PendingAction from bang.cards import * def test_bartcassidy(): diff --git a/backend/tests/dodge_city_test.py b/backend/tests/dodge_city_test.py index 5d7ac38..b2bbb8a 100644 --- a/backend/tests/dodge_city_test.py +++ b/backend/tests/dodge_city_test.py @@ -3,7 +3,7 @@ from bang.characters import Character from bang.expansions.dodge_city.cards import * from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player import bang.cards as cs # test Borraccia diff --git a/backend/tests/game_test.py b/backend/tests/game_test.py index 280138c..5ae066b 100644 --- a/backend/tests/game_test.py +++ b/backend/tests/game_test.py @@ -1,8 +1,9 @@ from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player from bang.roles import * from bang.cards import * +from globals import PendingAction from tests import started_game diff --git a/backend/tests/roles_test.py b/backend/tests/roles_test.py index 9f2c34f..34353bd 100644 --- a/backend/tests/roles_test.py +++ b/backend/tests/roles_test.py @@ -1,7 +1,8 @@ from bang.characters import Character from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player +from globals import PendingAction from bang.roles import * from bang.cards import * diff --git a/backend/tests/valley_of_shadows_characters_test.py b/backend/tests/valley_of_shadows_characters_test.py index a144a68..5ba723c 100644 --- a/backend/tests/valley_of_shadows_characters_test.py +++ b/backend/tests/valley_of_shadows_characters_test.py @@ -3,8 +3,9 @@ from bang.characters import Character from bang.expansions.the_valley_of_shadows.characters import * from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player import bang.cards as cs +from globals import PendingAction # test TucoFranziskaner def test_TucoFranziskaner(): diff --git a/backend/tests/valley_of_shadows_test.py b/backend/tests/valley_of_shadows_test.py index 63e5251..e361e53 100644 --- a/backend/tests/valley_of_shadows_test.py +++ b/backend/tests/valley_of_shadows_test.py @@ -3,8 +3,9 @@ from bang.characters import Character from bang.expansions.the_valley_of_shadows.cards import * from bang.deck import Deck from bang.game import Game -from bang.players import Player, PendingAction +from bang.players import Player import bang.cards as cs +from globals import PendingAction from tests import started_game, set_events, current_player, next_player, current_player_with_cards diff --git a/backend/tests/wild_west_show_characters_test.py b/backend/tests/wild_west_show_characters_test.py index ca3ec32..b022bf4 100644 --- a/backend/tests/wild_west_show_characters_test.py +++ b/backend/tests/wild_west_show_characters_test.py @@ -4,7 +4,7 @@ from tests import started_game, set_events, current_player, next_player, current from bang.expansions.wild_west_show.characters import * from bang.cards import Card, Suit import bang.roles as roles -from bang.players import PendingAction +from globals import PendingAction # test TerenKill diff --git a/backend/tests/wild_west_show_events_test.py b/backend/tests/wild_west_show_events_test.py index 4a85cbc..9af8851 100644 --- a/backend/tests/wild_west_show_events_test.py +++ b/backend/tests/wild_west_show_events_test.py @@ -4,7 +4,7 @@ from tests import started_game, set_events, current_player, next_player, current from bang.expansions.wild_west_show.card_events import * from bang.cards import Card, Suit import bang.roles as roles -from bang.players import PendingAction +from globals import PendingAction # test Camposanto