buy trains
This commit is contained in:
parent
a6029cdb0d
commit
f716a96334
@ -67,7 +67,7 @@ class Card(ABC):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
if str(self.suit).isnumeric():
|
if str(self.suit).isnumeric():
|
||||||
char = ["♦️", "♣️", "♥️", "♠️", "🤑"][int(self.suit)]
|
char = ["♦️", "♣️", "♥️", "♠️", "🤑", "🚋"][int(self.suit)]
|
||||||
else:
|
else:
|
||||||
char = self.suit
|
char = self.suit
|
||||||
return f"{self.name} {char}{self.number}"
|
return f"{self.name} {char}{self.number}"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
import bang.cards as cs
|
import bang.cards as cs
|
||||||
|
import bang.players as pl
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bang.players import Player
|
from bang.players import Player
|
||||||
@ -10,6 +11,22 @@ class StationCard:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.expansion = "train_robbery"
|
self.expansion = "train_robbery"
|
||||||
self.price: list[dict] = []
|
self.price: list[dict] = []
|
||||||
|
self.attached_train = None
|
||||||
|
|
||||||
|
def discard_and_buy_train(self, player: "Player", card_index: int):
|
||||||
|
"""Discard the card and buy the train"""
|
||||||
|
card = player.available_cards.pop(card_index)
|
||||||
|
for i, card in enumerate(player.hand):
|
||||||
|
if card == self:
|
||||||
|
player.hand.pop(i)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
player.lives -= 1
|
||||||
|
card = player.hand.pop(card_index)
|
||||||
|
player.game.deck.scrap(card, True, player=player)
|
||||||
|
player.hand.append(self.attached_train)
|
||||||
|
self.attached_train = None
|
||||||
|
player.pending_action = pl.PendingAction.PLAY
|
||||||
|
|
||||||
def check_price(self, player: "Player") -> bool:
|
def check_price(self, player: "Player") -> bool:
|
||||||
"""Check if the card can be used to rob the train"""
|
"""Check if the card can be used to rob the train"""
|
||||||
@ -28,6 +45,12 @@ class BoomTown(StationCard):
|
|||||||
not isinstance(c, cs.Bang) for c in player.hand
|
not isinstance(c, cs.Bang) for c in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if isinstance(c, cs.Bang)],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Caticor(StationCard):
|
class Caticor(StationCard):
|
||||||
@ -43,6 +66,16 @@ class Caticor(StationCard):
|
|||||||
for card in player.hand
|
for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[
|
||||||
|
c
|
||||||
|
for c in player.hand
|
||||||
|
if isinstance(c, cs.CatBalou) or isinstance(c, cs.Panico)
|
||||||
|
],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CreepyCreek(StationCard):
|
class CreepyCreek(StationCard):
|
||||||
@ -57,6 +90,12 @@ class CreepyCreek(StationCard):
|
|||||||
card.suit != cs.Suit.SPADES for card in player.hand
|
card.suit != cs.Suit.SPADES for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.suit == cs.Suit.SPADES],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CrownsHole(StationCard):
|
class CrownsHole(StationCard):
|
||||||
@ -71,6 +110,12 @@ class CrownsHole(StationCard):
|
|||||||
not isinstance(card, cs.Birra) for card in player.hand
|
not isinstance(card, cs.Birra) for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if isinstance(c, cs.Birra)],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Deadwood(StationCard):
|
class Deadwood(StationCard):
|
||||||
@ -85,6 +130,12 @@ class Deadwood(StationCard):
|
|||||||
not card.is_equipment for card in player.hand
|
not card.is_equipment for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.is_equipment],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Dodgeville(StationCard):
|
class Dodgeville(StationCard):
|
||||||
@ -99,6 +150,12 @@ class Dodgeville(StationCard):
|
|||||||
not isinstance(card, cs.Mancato) for card in player.hand
|
not isinstance(card, cs.Mancato) for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if isinstance(c, cs.Mancato)],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class FortWorth(StationCard):
|
class FortWorth(StationCard):
|
||||||
@ -113,6 +170,12 @@ class FortWorth(StationCard):
|
|||||||
card.number not in {1, 10, 11, 12, 13} for card in player.hand
|
card.number not in {1, 10, 11, 12, 13} for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.number in {1, 10, 11, 12, 13}],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Frisco(StationCard):
|
class Frisco(StationCard):
|
||||||
@ -127,6 +190,12 @@ class Frisco(StationCard):
|
|||||||
card.suit != cs.Suit.CLUBS for card in player.hand
|
card.suit != cs.Suit.CLUBS for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.suit == cs.Suit.CLUBS],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class MinersOath(StationCard):
|
class MinersOath(StationCard):
|
||||||
@ -141,6 +210,12 @@ class MinersOath(StationCard):
|
|||||||
card.suit != cs.Suit.DIAMONDS for card in player.hand
|
card.suit != cs.Suit.DIAMONDS for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.suit == cs.Suit.DIAMONDS],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class SanTafe(StationCard):
|
class SanTafe(StationCard):
|
||||||
@ -155,6 +230,12 @@ class SanTafe(StationCard):
|
|||||||
card.suit != cs.Suit.HEARTS for card in player.hand
|
card.suit != cs.Suit.HEARTS for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if c.suit == cs.Suit.HEARTS],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Tombrock(StationCard):
|
class Tombrock(StationCard):
|
||||||
@ -167,6 +248,12 @@ class Tombrock(StationCard):
|
|||||||
def check_price(self, player: "Player"):
|
def check_price(self, player: "Player"):
|
||||||
if player.lives <= 1:
|
if player.lives <= 1:
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[{"icon": "💔"}],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Yooma(StationCard):
|
class Yooma(StationCard):
|
||||||
@ -181,6 +268,12 @@ class Yooma(StationCard):
|
|||||||
not (2 <= card.number <= 9) for card in player.hand
|
not (2 <= card.number <= 9) for card in player.hand
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
[c for c in player.hand if 2 <= c.number <= 9],
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class VirginiaTown(StationCard):
|
class VirginiaTown(StationCard):
|
||||||
@ -193,6 +286,12 @@ class VirginiaTown(StationCard):
|
|||||||
def check_price(self, player: "Player"):
|
def check_price(self, player: "Player"):
|
||||||
if super().check_price(player) and len(player.hand < 2):
|
if super().check_price(player) and len(player.hand < 2):
|
||||||
return False
|
return False
|
||||||
|
player.set_choose_action(
|
||||||
|
"choose_buy_train",
|
||||||
|
player.hand.copy(),
|
||||||
|
self.discard_and_buy_train,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_all_stations():
|
def get_all_stations():
|
||||||
|
@ -9,6 +9,7 @@ class TrainCard(Card):
|
|||||||
self.is_equipment = True
|
self.is_equipment = True
|
||||||
self.is_locomotive = is_locomotive
|
self.is_locomotive = is_locomotive
|
||||||
self.expansion = "train_robbery"
|
self.expansion = "train_robbery"
|
||||||
|
self.type = "train"
|
||||||
|
|
||||||
|
|
||||||
# Circus Wagon: gli altri giocatori
|
# Circus Wagon: gli altri giocatori
|
||||||
|
@ -19,7 +19,7 @@ import bang.expansions.the_valley_of_shadows.cards as tvosc
|
|||||||
import bang.expansions.the_valley_of_shadows.characters as tvosch
|
import bang.expansions.the_valley_of_shadows.characters as tvosch
|
||||||
import bang.expansions.train_robbery.stations as trs
|
import bang.expansions.train_robbery.stations as trs
|
||||||
import bang.expansions.train_robbery.trains as trt
|
import bang.expansions.train_robbery.trains as trt
|
||||||
from typing import List, TYPE_CHECKING
|
from typing import List, TYPE_CHECKING, Callable
|
||||||
from metrics import Metrics
|
from metrics import Metrics
|
||||||
from globals import G
|
from globals import G
|
||||||
import sys
|
import sys
|
||||||
@ -104,6 +104,7 @@ class Player:
|
|||||||
self.is_bot = bot
|
self.is_bot = bot
|
||||||
self.discord_token = discord_token
|
self.discord_token = discord_token
|
||||||
self.discord_id = None
|
self.discord_id = None
|
||||||
|
self.did_choose_callback = None
|
||||||
self.played_cards = 0
|
self.played_cards = 0
|
||||||
self.avatar = ""
|
self.avatar = ""
|
||||||
self.last_played_card: cs.Card = None
|
self.last_played_card: cs.Card = None
|
||||||
@ -1402,6 +1403,9 @@ class Player:
|
|||||||
self.target_p = self.rissa_targets.pop(0).name
|
self.target_p = self.rissa_targets.pop(0).name
|
||||||
print(f"rissa targets: {self.rissa_targets}")
|
print(f"rissa targets: {self.rissa_targets}")
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
elif self.did_choose_callback is not None:
|
||||||
|
self.did_choose_callback(self, card_index)
|
||||||
|
self.notify_self()
|
||||||
elif self.choose_text == "choose_ricercato":
|
elif self.choose_text == "choose_ricercato":
|
||||||
player = self.game.get_player_named(
|
player = self.game.get_player_named(
|
||||||
self.available_cards[card_index]["name"]
|
self.available_cards[card_index]["name"]
|
||||||
@ -2569,12 +2573,26 @@ class Player:
|
|||||||
if train is not None and not train.is_locomotive:
|
if train is not None and not train.is_locomotive:
|
||||||
if station.check_price(self):
|
if station.check_price(self):
|
||||||
print(f"{station=} {train=}")
|
print(f"{station=} {train=}")
|
||||||
|
station.attached_train = train
|
||||||
|
# shift train forward
|
||||||
|
for i in range(train_index, len(self.game.deck.current_train) - 1):
|
||||||
|
self.game.deck.current_train[i] = self.game.deck.current_train[
|
||||||
|
i + 1
|
||||||
|
]
|
||||||
|
self.game.notify_stations()
|
||||||
|
# self.game.deck.current_train[train_index] = None
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def set_choose_action(self, choose_text: str, available_cards: List):
|
def set_choose_action(
|
||||||
|
self,
|
||||||
|
choose_text: str,
|
||||||
|
available_cards: List,
|
||||||
|
did_choose_callback: Callable(Player, int) = None,
|
||||||
|
):
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
self.choose_text = choose_text
|
self.choose_text = choose_text
|
||||||
self.available_cards = available_cards
|
self.available_cards = available_cards
|
||||||
|
self.did_choose_callback = did_choose_callback
|
||||||
|
|
||||||
def check_can_end_turn(self):
|
def check_can_end_turn(self):
|
||||||
must_be_used_cards = [c for c in self.hand if c.must_be_used]
|
must_be_used_cards = [c for c in self.hand if c.must_be_used]
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
'gold-rush': card.expansion === 'gold_rush',
|
'gold-rush': card.expansion === 'gold_rush',
|
||||||
brown: card.kind === 0,
|
brown: card.kind === 0,
|
||||||
black: card.kind === 1,
|
black: card.kind === 1,
|
||||||
|
'train-piece': card.type && card.type === 'train',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<h4>{{ cardName }}</h4>
|
<h4>{{ cardName }}</h4>
|
||||||
|
Loading…
Reference in New Issue
Block a user