Skip to content

Commit

Permalink
Merge pull request #505 from albertoxamin/train-robbery
Browse files Browse the repository at this point in the history
Add Train robbery expansion
  • Loading branch information
albertoxamin authored Jun 14, 2024
2 parents 9bc1922 + 7dab001 commit 5d0e46f
Show file tree
Hide file tree
Showing 36 changed files with 2,238 additions and 864 deletions.
23 changes: 14 additions & 9 deletions backend/bang/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Suit(IntEnum):
HEARTS = 2 # ♥
SPADES = 3 # ♠
GOLD = 4 # 🤑
TRAIN = 5 # 🚂


class Card(ABC):
Expand Down Expand Up @@ -66,7 +67,7 @@ def __init__(

def __str__(self) -> str:
if str(self.suit).isnumeric():
char = ["♦️", "♣️", "♥️", "♠️", "🤑"][int(self.suit)]
char = ["♦️", "♣️", "♥️", "♠️", "🤑", "🚋"][int(self.suit)]
else:
char = self.suit
return f"{self.name} {char}{self.number}"
Expand Down Expand Up @@ -370,14 +371,18 @@ def play_card(self, player, against=None, _with=None, skipChecks=False):
player.game.deck.draw(True, player=p)
p.notify_self()
if "gold_rush" in player.game.expansions and self.number != 42:
from bang.players import PendingAction

player.available_cards = [
{"name": "Pepita", "icon": "💵️", "alt_text": "1", "noDesc": True},
self,
]
player.choose_text = "choose_birra_function"
player.pending_action = PendingAction.CHOOSE
player.set_choose_action(
"choose_birra_function",
[
{
"name": "Pepita",
"icon": "💵️",
"alt_text": "1",
"noDesc": True,
},
self,
],
)
player.notify_self()
return True
if (
Expand Down
28 changes: 24 additions & 4 deletions backend/bang/deck.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from typing import List, Set, Dict, Tuple, Optional, TYPE_CHECKING
import random
import bang.cards as cs
import bang.expansions.fistful_of_cards.card_events as ce
import bang.expansions.high_noon.card_events as ceh
import bang.expansions.wild_west_show.card_events as cew
import bang.expansions.wild_west_show.characters as chw
import bang.expansions.gold_rush.shop_cards as grc
import bang.expansions.train_robbery.stations as trs
import bang.expansions.train_robbery.trains as trt
from globals import G

if TYPE_CHECKING:
from bang.game import Game
from bang.players import Player


class Deck:
Expand All @@ -35,6 +37,9 @@ def __init__(self, game: "Game"):
self.game = game
self.event_cards: List[ce.CardEvent] = []
self.event_cards_wildwestshow: List[ce.CardEvent] = []
self.stations: List[trs.StationCard] = []
self.train_pile: List[trt.TrainCard] = []
self.current_train: List[trt.TrainCard] = []
endgame_cards: List[ce.CardEvent] = []
if "fistful_of_cards" in game.expansions:
self.event_cards.extend(ce.get_all_events(game.rng))
Expand All @@ -47,6 +52,12 @@ def __init__(self, game: "Game"):
game.rng.shuffle(self.event_cards_wildwestshow)
self.event_cards_wildwestshow.insert(0, None)
self.event_cards_wildwestshow.append(cew.get_endgame_card())
if "train_robbery" in game.expansions:
self.stations = game.rng.sample(trs.get_all_stations(), len(game.players))
self.train_pile = trt.get_all_cards(game.rng)
self.current_train = [trt.get_locomotives(game.rng)[0]] + self.train_pile[
:3
]
if len(self.event_cards) > 0:
game.rng.shuffle(self.event_cards)
self.event_cards = self.event_cards[:12]
Expand Down Expand Up @@ -106,12 +117,21 @@ def fill_gold_rush_shop(self):
self.shop_cards[i].reset_card()
self.game.notify_gold_rush_shop()

def move_train_forward(self):
if len(self.stations) == 0:
return
if len(self.current_train) == len(self.stations) + 4:
return
if len(self.current_train) > 0:
self.current_train.append(None)
self.game.notify_stations()

def peek(self, n_cards: int) -> list:
return self.cards[:n_cards]

def peek_scrap_pile(self) -> cs.Card:
def peek_scrap_pile(self, n_cards: int=1) -> List[cs.Card]:
if len(self.scrap_pile) > 0:
return self.scrap_pile[-1]
return self.scrap_pile[-n_cards:]
else:
return None

Expand Down Expand Up @@ -176,7 +196,7 @@ def draw_from_scrap_pile(self) -> cs.Card:
else:
return self.draw()

def scrap(self, card: cs.Card, ignore_event=False, player=None):
def scrap(self, card: cs.Card, ignore_event:bool=False, player:'Player'=None):
if card.number == 42:
return
card.reset_card()
Expand Down
3 changes: 1 addition & 2 deletions backend/bang/expansions/dodge_city/characters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List
from bang.characters import Character
from globals import PendingAction


class PixiePete(Character):
Expand Down Expand Up @@ -165,8 +166,6 @@ def __init__(self):

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
Expand Down
10 changes: 5 additions & 5 deletions backend/bang/expansions/gold_rush/shop_cards.py
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -47,7 +47,7 @@ def play_card(self, player, against=None, _with=None):
'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)

Expand All @@ -64,7 +64,7 @@ def play_card(self, player, against=None, _with=None):
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)

Expand All @@ -79,7 +79,7 @@ def play_card(self, player, against=None, _with=None):
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)

Expand Down Expand Up @@ -175,7 +175,7 @@ def play_card(self, player, against=None, _with=None):
} 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
Expand Down
12 changes: 4 additions & 8 deletions backend/bang/expansions/the_valley_of_shadows/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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):
Expand All @@ -15,7 +15,7 @@ def play_card(self, player, against, _with=None):
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 = [
{
Expand Down Expand Up @@ -60,11 +60,7 @@ def play_card(self, player, against, _with=None):
for p in player.game.get_visible_players(player)
)
):
from bang.players import PendingAction

player.available_cards = player.hand.copy()
player.pending_action = PendingAction.CHOOSE
player.choose_text = "choose_play_as_bang"
player.set_choose_action("choose_play_as_bang", player.hand.copy())
player.notify_self()
return False

Expand Down Expand Up @@ -185,7 +181,7 @@ def play_card(self, player, against, _with=None):
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 = []
Expand Down
9 changes: 4 additions & 5 deletions backend/bang/expansions/the_valley_of_shadows/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ def special(self, player, data): # fiori = suit.Clubs
for p in player.game.get_visible_players(player)
)
) and super().special(player, data):
from bang.players import PendingAction

player.available_cards = [c for c in player.hand if c.suit == cs.Suit.CLUBS]
player.special_use_count += 1
player.pending_action = PendingAction.CHOOSE
player.choose_text = "choose_play_as_bang"
player.set_choose_action(
"choose_play_as_bang",
[c for c in player.hand if c.suit == cs.Suit.CLUBS],
)
player.notify_self()


Expand Down
Empty file.
Empty file.
Loading

0 comments on commit 5d0e46f

Please sign in to comment.