less spaghetti is always better

This commit is contained in:
Alberto Xamin 2020-11-25 11:18:04 +01:00
parent 00ac77e10a
commit 363ae304f0
No known key found for this signature in database
GPG Key ID: 4F026F48309500A2
3 changed files with 264 additions and 171 deletions

View File

@ -2,12 +2,14 @@ from typing import List, Set, Dict, Tuple, Optional
from abc import ABC, abstractmethod
from enum import IntEnum
class Suit(IntEnum):
DIAMONDS = 0 # ♦
CLUBS = 1 # ♣
HEARTS = 2 # ♥
SPADES = 3 # ♠
class Card(ABC):
sym = {
'A': 1,
@ -15,7 +17,8 @@ class Card(ABC):
'Q': 12,
'K': 13
}
def __init__(self, suit: Suit, name: str, number, is_equipment:bool=False, is_weapon:bool=False, vis_mod:int=0, sight_mod:int=0, range:int=99, desc:str=''):
def __init__(self, suit: Suit, name: str, number, is_equipment: bool = False, is_weapon: bool = False, vis_mod: int = 0, sight_mod: int = 0, range: int = 99, desc: str = ''):
super().__init__()
self.name = name
self.suit = suit
@ -34,34 +37,45 @@ class Card(ABC):
self.need_target = False
def __str__(self):
char = ['♦️','♣️','♥️','♠️'][int(self.suit)]
char = ['♦️', '♣️', '♥️', '♠️'][int(self.suit)]
return f'{self.name} {char}{self.number}'
return super().__str__()
def play_card(self, player, against):
contro = f'contro {against}' if against else ''
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha giocato {self.name}{contro}.')
return True
class Barile(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Barile', number, is_equipment=True)
self.icon = '🛢'
self.desc = "Quando sei bersagliato da un Bang puoi estrarre la prima carta dalla cima del mazzo, se la carta estratta è del seme Cuori allora vale come un Mancato"
class Dinamite(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Dinamite', number, is_equipment=True)
self.icon = '🧨'
self.desc = "Giocando la Dinamite, posizionala davanti a te, resterà innocua per un intero giro. All'inizio del prossimo turno prima di pescare e prima di una eventuale estrazione (es. Prigione), estrai una carta dalla cima del mazzo. Se esce una carta tra il 2 il 9 di picche (compresi) allora la dinamite esplode: perdi 3 vite e scarta la carta, altrimenti passa la dinamite al giocatore successivo, il quale estrarà a sua volta dopo che tu avrai passato il tuo turno"
class Mirino(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Mirino', number, is_equipment=True, sight_mod=1)
self.icon = '🔎'
self.desc = "Tu vedi gli altri giocatori a distanza -1"
class Mustang(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Mustang', number, is_equipment=True, vis_mod=1)
self.icon = '🐎'
self.desc = "Gli altri giocatori ti vedono a distanza +1"
class Prigione(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Prigione', number, is_equipment=True)
@ -69,36 +83,47 @@ class Prigione(Card):
self.desc = "Equipaggia questa carta a un altro giocatore, tranne lo Sceriffo. Il giocatore scelto all'inizio del suo turno, prima di pescare dovrà estrarre: se esce Cuori scarta questa carta e gioca normalmente il turno, altrimenti scarta questa carta e salta il turno"
self.need_target = True
class Remington(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Remington', number, is_equipment=True, is_weapon=True, range=3)
super().__init__(suit, 'Remington', number,
is_equipment=True, is_weapon=True, range=3)
self.icon = '🔫'
self.desc = "Puoi sparare a un giocatore che sia distante 3 o meno"
class RevCarabine(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Rev. Carabine', number, is_equipment=True, is_weapon=True, range=4)
super().__init__(suit, 'Rev. Carabine', number,
is_equipment=True, is_weapon=True, range=4)
self.icon = '🔫'
self.desc = "Puoi sparare a un giocatore che sia distante 4 o meno"
class Schofield(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Schofield', number, is_equipment=True, is_weapon=True, range=2)
super().__init__(suit, 'Schofield', number,
is_equipment=True, is_weapon=True, range=2)
self.icon = '🔫'
self.desc = "Puoi sparare a un giocatore che sia distante 2 o meno"
class Volcanic(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Volcanic', number, is_equipment=True, is_weapon=True, range=1)
super().__init__(suit, 'Volcanic', number,
is_equipment=True, is_weapon=True, range=1)
self.icon = '🔫'
self.desc = "Puoi sparare a un giocatore che sia distante 1 o meno, tuttavia puoi giocare quanti bang vuoi"
class Winchester(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Winchester', number, is_equipment=True, is_weapon=True, range=5)
super().__init__(suit, 'Winchester', number,
is_equipment=True, is_weapon=True, range=5)
self.icon = '🔫'
self.desc = "Puoi sparare a un giocatore che sia distante 5 o meno"
class Bang(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Bang!', number)
@ -106,12 +131,37 @@ class Bang(Card):
self.desc = "Spara a un giocatore a distanta raggiungibile. Se non hai armi la distanza di default è 1"
self.need_target = True
def play_card(self, player, against):
if player.has_played_bang and not any([isinstance(c, Volcanic) for c in player.equipment]) and against != None:
return False
elif against != None:
import characters as chars
super().play_card(player, against=against)
player.has_played_bang = not isinstance(
player.character, chars.WillyTheKid)
player.game.attack(player, against)
return True
return False
class Birra(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Birra', number)
self.icon = '🍺'
self.desc = "Gioca questa carta per recuperare un punto vita. Non puoi andare oltre al limite massimo del tuo personaggio. Se stai per perdere l'ultimo punto vita puoi giocare questa carta anche nel turno dell'avversario. La birra non ha più effetto se ci sono solo due giocatori"
def play_card(self, player, against):
if len(player.game.players) != 2 and player.lives != player.max_lives:
super().play_card(player, against=against)
player.lives = min(player.lives+1, player.max_lives)
return True
elif len(player.game.players) == 2:
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha rovesciato una {self.name}.')
return True
return False
class CatBalou(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Cat Balou', number)
@ -119,12 +169,33 @@ class CatBalou(Card):
self.desc = "Fai scartare una carta a un qualsiasi giocatore, scegli a caso dalla mano, oppure fra quelle che ha in gioco"
self.need_target = True
def play_card(self, player, against):
if against != None:
super().play_card(player, against=against)
from players import PendingAction
player.pending_action = PendingAction.CHOOSE
player.choose_action = 'discard'
player.target_p = against
print('choose now')
return True
return False
class Diligenza(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Diligenza', number)
self.icon = '🚡'
self.desc = "Pesca 2 carte dalla cima del mazzo"
def play_card(self, player, against):
super().play_card(player, against=against)
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha giocato {self.name} e ha pescato 2 carte.')
for i in range(2):
player.hand.append(player.game.deck.draw())
return True
class Duello(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Duello', number)
@ -132,30 +203,67 @@ class Duello(Card):
self.icon = '⚔️'
self.desc = "Gioca questa carta contro un qualsiasi giocatore. A turno, cominciando dal tuo avversario, potete scartare una carta Bang!, il primo giocatore che non lo fa perde 1 vita"
def play_card(self, player, against):
if against != None:
super().play_card(player, against=against)
player.game.duel(player, against)
return True
return False
class Emporio(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Emporio', number)
self.icon = '🏪'
self.desc = "Scopri dal mazzo tante carte quanto il numero di giocatori, a turno, partendo da te, scegliete una carta e aggiungetela alla vostra mano"
def play_card(self, player, against):
super().play_card(player, against=against)
player.game.emporio()
return True
class Gatling(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Gatling', number)
self.icon = '🛰'
self.desc = "Spara a tutti gli altri giocatori"
def play_card(self, player, against):
super().play_card(player, against=against)
player.game.attack_others(player)
return True
class Indiani(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Indiani!', number)
self.icon = '🏹'
self.desc = "Tutti gli altri giocatori devono scartare un Bang! o perdere una vita"
def play_card(self, player, against):
super().play_card(player, against=against)
player.game.indian_others(player)
return True
class Mancato(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Mancato!', number)
self.icon = '😅'
self.desc = "Usa questa carta per annullare un bang"
def play_card(self, player, against):
import characters as chars
if (not player.has_played_bang and against != None and isinstance(player.character, chars.CalamityJanet)):
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha giocato {self.name} come un BANG! contro {against}.')
player.has_played_bang = True
player.game.attack(player, against)
return True
return False
class Panico(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Panico!', number, range=1)
@ -163,18 +271,47 @@ class Panico(Card):
self.need_target = True
self.desc = "Pesca una carta da un giocatore a distanza 1, scegli a caso dalla mano, oppure fra quelle che ha in gioco"
def play_card(self, player, against):
if against != None:
super().play_card(player, against=against)
from players import PendingAction
player.pending_action = PendingAction.CHOOSE
player.choose_action = 'steal'
player.target_p = against
print('choose now')
return True
return False
class Saloon(Card):
def __init__(self, suit, number):
super().__init__(suit, 'Saloon', number)
self.desc = "Tutti i giocatori recuperano un punto vita compreso chi gioca la carta"
self.icon = '🍻'
def play_card(self, player, against):
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha giocato {self.name} e ha curato 1 punto vita a tutti.')
for p in player.game.players:
p.lives = min(p.lives+1, p.max_lives)
p.notify_self()
return True
class WellsFargo(Card):
def __init__(self, suit, number):
super().__init__(suit, 'WellsFargo', number)
self.desc = "Pesca 3 carte dalla cima del mazzo"
self.icon = '💸'
def play_card(self, player, against):
player.sio.emit('chat_message', room=player.game.name,
data=f'{player.name} ha giocato {self.name} e ha pescato 3 carte.')
for i in range(3):
player.hand.append(player.game.deck.draw())
return True
def get_starting_deck() -> List[Card]:
return [
Barile(Suit.SPADES, 'Q'),

View File

@ -1,35 +1,35 @@
from typing import List, Set, Dict, Tuple, Optional
import random
from cards import Card, get_starting_deck
import cards as cs
class Deck:
def __init__(self, game):
super().__init__()
self.cards: List[Card] = get_starting_deck()
self.cards: List[cs.Card] = cs.get_starting_deck()
self.game = game
random.shuffle(self.cards)
self.scrap_pile: List[Card] = []
self.scrap_pile: List[cs.Card] = []
print(f'Deck initialized with {len(self.cards)} cards')
def peek(self, n_cards: int) -> list:
return self.cards[:n_cards]
def peek_scrap_pile(self) -> Card:
def peek_scrap_pile(self) -> cs.Card:
if len(self.scrap_pile) > 0:
return self.scrap_pile[-1]
else:
return None
def pick_and_scrap(self) -> Card:
def pick_and_scrap(self) -> cs.Card:
card = self.cards.pop(0)
self.scrap_pile.append(card)
self.game.notify_scrap_pile()
return card
def put_on_top(self, card: Card):
def put_on_top(self, card: cs.Card):
self.cards.insert(0, card)
def draw(self) -> Card:
def draw(self) -> cs.Card:
card = self.cards.pop(0)
if len(self.cards) == 0:
self.cards = self.scrap_pile[:-1].copy()
@ -37,7 +37,7 @@ class Deck:
self.scrap_pile = self.scrap_pile[-1:]
return card
def draw_from_scrap_pile(self) -> Card:
def draw_from_scrap_pile(self) -> cs.Card:
if len(self.scrap_pile) > 0:
card = self.scrap_pile.pop(-1)
self.game.notify_scrap_pile()
@ -45,6 +45,6 @@ class Deck:
else:
return self.draw()
def scrap(self, card: Card):
def scrap(self, card: cs.Card):
self.scrap_pile.append(card)
self.game.notify_scrap_pile()

View File

@ -3,11 +3,10 @@ from enum import IntEnum
import json
from random import randrange
import socketio
import cards
import roles
import cards
import characters
import roles as r
import cards as cs
import characters as chars
class PendingAction(IntEnum):
PICK = 0
@ -17,19 +16,22 @@ class PendingAction(IntEnum):
WAIT = 4
CHOOSE = 5
class Player:
import game as g
def __init__(self, name, sid, sio):
super().__init__()
self.name = name
self.sid = sid
self.sio = sio
self.hand: cards.Card = []
self.equipment: cards.Card = []
self.role: roles.Role = None
self.character: characters.Character = None
self.hand: cs.Card = []
self.equipment: cs.Card = []
self.role: r.Role = None
self.character: chars.Character = None
self.lives = 0
self.max_lives = 0
self.game = None
self.game: g = None
self.is_my_turn = False
self.is_waiting_for_action = True
self.has_played_bang = False
@ -52,17 +54,20 @@ class Player:
def disconnect(self):
return self.game.handle_disconnect(self)
def set_role(self, role: roles.Role):
def set_role(self, role: r.Role):
self.role = role
print(f'I {self.name} am a {role.name}, my goal is "{role.goal}"')
self.sio.emit('role', room=self.sid, data=json.dumps(role, default=lambda o: o.__dict__))
self.sio.emit('role', room=self.sid, data=json.dumps(
role, default=lambda o: o.__dict__))
def set_character(self, character: str):
print(self.available_characters, character)
self.character = next(x for x in self.available_characters if x.name==character)
self.character = next(
x for x in self.available_characters if x.name == character)
self.available_characters = []
print(f'I {self.name} chose character {self.character.name}')
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha scelto il personaggio.')
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha scelto il personaggio.')
self.game.notify_character_selection()
def prepare(self):
@ -75,7 +80,8 @@ class Player:
def set_available_character(self, available):
self.available_characters = available
print(f'I {self.name} have to choose between {available}')
self.sio.emit('characters', room=self.sid, data=json.dumps(available, default=lambda o: o.__dict__))
self.sio.emit('characters', room=self.sid, data=json.dumps(
available, default=lambda o: o.__dict__))
def notify_card(self, player, card):
mess = {
@ -86,9 +92,10 @@ class Player:
self.sio.emit('notify_card', room=self.sid, data=mess)
def notify_self(self):
if isinstance(self.character, characters.CalamityJanet):
self.expected_response = [cards.Mancato(0,0).name, cards.Bang(0,0).name]
elif isinstance(self.character, characters.SuzyLafayette) and len(self.hand) == 0:
if isinstance(self.character, chars.CalamityJanet):
self.expected_response = [
cs.Mancato(0, 0).name, cs.Bang(0, 0).name]
elif isinstance(self.character, chars.SuzyLafayette) and len(self.hand) == 0:
self.hand.append(self.game.deck.draw())
ser = self.__dict__.copy()
ser.pop('game')
@ -102,14 +109,18 @@ class Player:
ser['attacker'] = self.attacker.name
ser['sight'] = self.get_sight()
ser['lives'] = max(ser['lives'], 0)
self.sio.emit('self', room=self.sid, data=json.dumps(ser, default=lambda o: o.__dict__))
self.sio.emit('self_vis', room=self.sid, data=json.dumps(self.game.get_visible_players(self), default=lambda o: o.__dict__))
self.sio.emit('self', room=self.sid, data=json.dumps(
ser, default=lambda o: o.__dict__))
self.sio.emit('self_vis', room=self.sid, data=json.dumps(
self.game.get_visible_players(self), default=lambda o: o.__dict__))
if self.lives <= 0 and self.max_lives > 0:
print('dying, attacker', self.attacker)
if isinstance(self.character, characters.SidKetchum) and len(self.hand) > 1:
if isinstance(self.character, chars.SidKetchum) and len(self.hand) > 1:
self.lives += 1
self.game.deck.scrap(self.hand.pop(randrange(0, len(self.hand))))
self.game.deck.scrap(self.hand.pop(randrange(0, len(self.hand))))
self.game.deck.scrap(self.hand.pop(
randrange(0, len(self.hand))))
self.game.deck.scrap(self.hand.pop(
randrange(0, len(self.hand))))
self.game.player_death(self)
self.game.notify_all()
@ -117,13 +128,14 @@ class Player:
if self.lives == 0:
return self.end_turn(forced=True)
self.scrapped_cards = 0
self.sio.emit('chat_message', room=self.game.name, data=f'È il turno di {self.name}.')
self.sio.emit('chat_message', room=self.game.name,
data=f'È il turno di {self.name}.')
print(f'I {self.name} was notified that it is my turn')
self.was_shot = False
self.is_my_turn = True
self.is_waiting_for_action = True
self.has_played_bang = False
if any([isinstance(c, cards.Dinamite) or isinstance(c, cards.Prigione) for c in self.equipment]):
if any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) for c in self.equipment]):
self.pending_action = PendingAction.PICK
else:
self.pending_action = PendingAction.DRAW
@ -132,28 +144,29 @@ class Player:
def draw(self, pile):
if self.pending_action != PendingAction.DRAW:
return
if isinstance(self.character, characters.KitCarlson):
if isinstance(self.character, chars.KitCarlson):
self.is_drawing = True
self.available_cards = [self.game.deck.draw() for i in range(3)]
self.pending_action = PendingAction.CHOOSE
self.notify_self()
else:
self.pending_action = PendingAction.PLAY
if pile == 'scrap' and isinstance(self.character, characters.PedroRamirez):
if pile == 'scrap' and isinstance(self.character, chars.PedroRamirez):
self.hand.append(self.game.deck.draw_from_scrap_pile())
self.hand.append(self.game.deck.draw())
elif type(pile) == str and pile != self.name and pile in self.game.players_map and isinstance(self.character, characters.JesseJones) and len(self.game.get_player_named(pile).hand) > 0:
self.hand.append(self.game.get_player_named(pile).hand.pop(randrange(0, len(self.game.get_player_named(pile).hand))))
elif type(pile) == str and pile != self.name and pile in self.game.players_map and isinstance(self.character, chars.JesseJones) and len(self.game.get_player_named(pile).hand) > 0:
self.hand.append(self.game.get_player_named(pile).hand.pop(
randrange(0, len(self.game.get_player_named(pile).hand))))
self.hand.append(self.game.deck.draw())
else:
for i in range(2):
card: cards.Card = self.game.deck.draw()
card: cs.Card = self.game.deck.draw()
self.hand.append(card)
if i == 1 and isinstance(self.character, characters.BlackJack):
if i == 1 and isinstance(self.character, chars.BlackJack):
for p in self.game.players:
if p != self:
p.notify_card(self, card)
if card.suit == cards.Suit.HEARTS or card.suit == cards.Suit.DIAMONDS:
if card.suit == cs.Suit.HEARTS or card.suit == cs.Suit.DIAMONDS:
self.hand.append(self.game.deck.draw())
self.notify_self()
@ -163,33 +176,36 @@ class Player:
pickable_cards = 1 + self.character.pick_mod
if self.is_my_turn:
for i in range(len(self.equipment)):
if isinstance(self.equipment[i], cards.Dinamite):
if isinstance(self.equipment[i], cs.Dinamite):
while pickable_cards > 0:
pickable_cards -= 1
picked: cards.Card = self.game.deck.pick_and_scrap()
picked: cs.Card = self.game.deck.pick_and_scrap()
print(f'Did pick {picked}')
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
if picked.suit == cards.Suit.SPADES and 2 <= picked.number <= 9 and pickable_cards == 0:
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha estratto {picked}.')
if picked.suit == cs.Suit.SPADES and 2 <= picked.number <= 9 and pickable_cards == 0:
self.lives -= 3
self.game.deck.scrap(self.equipment.pop(i))
if isinstance(self.character, characters.BartCassidy):
if isinstance(self.character, chars.BartCassidy):
self.hand.append(self.game.deck.draw())
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha fatto esplodere la dinamite.')
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha fatto esplodere la dinamite.')
print(f'{self.name} Boom, -3 hp')
else:
self.game.next_player().equipment.append(self.equipment.pop(i))
self.game.next_player().notify_self()
if any([isinstance(c, cards.Dinamite) or isinstance(c, cards.Prigione) for c in self.equipment]):
if any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) for c in self.equipment]):
self.notify_self()
return
for i in range(len(self.equipment)):
if isinstance(self.equipment[i], cards.Prigione):
if isinstance(self.equipment[i], cs.Prigione):
while pickable_cards > 0:
pickable_cards -= 1
picked: cards.Card = self.game.deck.pick_and_scrap()
picked: cs.Card = self.game.deck.pick_and_scrap()
print(f'Did pick {picked}')
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
if picked.suit != cards.Suit.HEARTS and pickable_cards == 0:
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha estratto {picked}.')
if picked.suit != cs.Suit.HEARTS and pickable_cards == 0:
self.game.deck.scrap(self.equipment.pop(i))
self.end_turn(forced=True)
return
@ -207,29 +223,30 @@ class Player:
playable_cards = []
for i in range(len(self.hand)):
card = self.hand[i]
if isinstance(card, cards.Bang) and self.has_played_bang and not any([isinstance(c, cards.Volcanic) for c in self.equipment]):
if isinstance(card, cs.Bang) and self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment]):
continue
elif isinstance(card, cards.Birra) and self.lives >= self.max_lives:
elif isinstance(card, cs.Birra) and self.lives >= self.max_lives:
continue
else:
playable_cards.append(i)
playable_cs.append(i)
return playable_cards
def get_public_description(self):
s = f"{self.name} {'Sheriff ⭐️' if isinstance(self.role, roles.Sheriff) else ''} ({self.lives}/{self.max_lives} ⁍) {len(self.hand)} Cards in hand, "
s = f"{self.name} {'Sheriff ⭐️' if isinstance(self.role, r.Sheriff) else ''} ({self.lives}/{self.max_lives} ⁍) {len(self.hand)} Cards in hand, "
s += f"equipment {[str(c) for c in self.equipment]}"
return s
def play_card(self, hand_index: int, againts=None):
def play_card(self, hand_index: int, against=None):
if not (0 <= hand_index < len(self.hand)):
print('illegal')
return
card: cards.Card = self.hand.pop(hand_index)
print(self.name, 'is playing ', card, ' against:', againts)
if isinstance(card, cards.Prigione) and not isinstance(self.game.get_player_named(againts).role, roles.Sheriff):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} contro {againts}.')
self.game.get_player_named(againts).equipment.append(card)
self.game.get_player_named(againts).notify_self()
card: cs.Card = self.hand.pop(hand_index)
print(self.name, 'is playing ', card, ' against:', against)
if isinstance(card, cs.Prigione) and not isinstance(self.game.get_player_named(against).role, r.Sheriff):
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha giocato {card.name} contro {against}.')
self.game.get_player_named(against).equipment.append(card)
self.game.get_player_named(against).notify_self()
elif card.is_equipment:
if card.is_weapon:
has_weapon = False
@ -241,7 +258,7 @@ class Player:
break
if not has_weapon:
self.equipment.append(card)
elif card.name in [c.name for c in self.equipment if not isinstance(c, cards.Dinamite)]:
elif card.name in [c.name for c in self.equipment if not isinstance(c, cs.Dinamite)]:
for i in range(len(self.equipment)):
if type(self.equipment[i]) == type(card):
self.game.deck.scrap(self.equipment[i])
@ -250,74 +267,7 @@ class Player:
else:
self.equipment.append(card)
else:
did_play_card = False
if isinstance(card, cards.Bang) and self.has_played_bang and not any([isinstance(c, cards.Volcanic) for c in self.equipment]) and againts != None:
self.hand.insert(hand_index, card)
return
elif isinstance(card, cards.Bang) and againts != None:
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} contro {againts}.')
self.has_played_bang = not isinstance(self.character, characters.WillyTheKid)
self.game.attack(self, againts)
did_play_card = True
elif isinstance(card, cards.Birra):
if len(self.game.players) != 2 and self.lives != self.max_lives:
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato una {card.name}.')
self.lives = min(self.lives+1, self.max_lives)
did_play_card = True
elif len(self.game.players) == 2:
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha rovesciato una {card.name}.')
did_play_card = True
elif isinstance(card, cards.CatBalou) and againts != None:
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} contro {againts}.')
self.pending_action = PendingAction.CHOOSE
self.choose_action = 'discard'
self.target_p = againts
did_play_card = True
print('choose now')
elif isinstance(card, cards.Diligenza):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} e ha pescato 2 carte.')
for i in range(2):
self.hand.append(self.game.deck.draw())
did_play_card = True
elif isinstance(card, cards.Duello):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} contro {againts}.')
self.game.duel(self, againts)
did_play_card = True
elif isinstance(card, cards.Emporio):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name}.')
self.game.emporio()
did_play_card = True
elif isinstance(card, cards.Gatling):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name}.')
self.game.attack_others(self)
did_play_card = True
elif isinstance(card, cards.Indiani):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name}.')
self.game.indian_others(self)
did_play_card = True
elif isinstance(card, cards.Mancato) and (not self.has_played_bang and againts != None and isinstance(self.character, characters.CalamityJanet)):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} come un BANG! contro {againts}.')
self.has_played_bang = True
self.game.attack(self, againts)
did_play_card = True
elif isinstance(card, cards.Panico) and againts != None:
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} contro {againts}.')
self.pending_action = PendingAction.CHOOSE
self.choose_action = 'steal'
self.target_p = againts
print('choose now')
did_play_card = True
elif isinstance(card, cards.Saloon):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} e ha curato 1 punto vita a tutti.')
for p in self.game.players:
p.lives = min(p.lives+1, p.max_lives)
p.notify_self()
did_play_card = True
elif isinstance(card, cards.WellsFargo):
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha giocato {card.name} e ha pescato 3 carte.')
for i in range(3):
self.hand.append(self.game.deck.draw())
did_play_card = True
did_play_card = card.play_card(self, against)
if did_play_card:
self.game.deck.scrap(card)
else:
@ -343,10 +293,11 @@ class Player:
self.choose_action = ''
self.pending_action = PendingAction.PLAY
self.notify_self()
elif self.is_drawing and isinstance(self.character, characters.KitCarlson): # specifico per personaggio
self.hand.append(self.available_cards.pop(card_index))
# specifico per personaggio
elif self.is_drawing and isinstance(self.character, chars.KitCarlson):
self.hand.append(self.available_cs.pop(card_index))
if len(self.available_cards) == 1:
self.game.deck.put_on_top(self.available_cards.pop())
self.game.deck.put_on_top(self.available_cs.pop())
self.is_drawing = False
self.pending_action = PendingAction.PLAY
self.notify_self()
@ -355,58 +306,59 @@ class Player:
def barrel_pick(self):
pickable_cards = 1 + self.character.pick_mod
if len([c for c in self.equipment if isinstance(c, cards.Barile)]) > 0 and isinstance(self.character, characters.Jourdonnais):
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 and isinstance(self.character, chars.Jourdonnais):
pickable_cards = 2
while pickable_cards > 0:
pickable_cards -= 1
picked: cards.Card = self.game.deck.pick_and_scrap()
picked: cs.Card = self.game.deck.pick_and_scrap()
print(f'Did pick {picked}')
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
if picked.suit == cards.Suit.HEARTS:
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha estratto {picked}.')
if picked.suit == cs.Suit.HEARTS:
self.mancato_needed -= 1
self.notify_self()
if self.mancato_needed <= 0:
self.game.responders_did_respond_resume_turn()
return
if len([c for c in self.hand if isinstance(c, cards.Mancato) or (isinstance(self.character, characters.CalamityJanet) and isinstance(c, cards.Bang))]) == 0:
if len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang))]) == 0:
self.take_damage_response()
self.game.responders_did_respond_resume_turn()
else:
self.pending_action = PendingAction.RESPOND
self.expected_response = [cards.Mancato(0,0).name]
self.expected_response = [cs.Mancato(0, 0).name]
self.on_failed_response_cb = self.take_damage_response
self.notify_self()
def get_banged(self, attacker, double=False):
self.attacker = attacker
self.mancato_needed = 1 if not double else 2
if len([c for c in self.hand if isinstance(c, cards.Mancato) or (isinstance(self.character, characters.CalamityJanet) and isinstance(c, cards.Bang))]) == 0 and len([c for c in self.equipment if isinstance(c, cards.Barile)]) == 0 and not isinstance(self.character, characters.Jourdonnais):
if len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang))]) == 0 and len([c for c in self.equipment if isinstance(c, cs.Barile)]) == 0 and not isinstance(self.character, chars.Jourdonnais):
print('Cant defend')
self.take_damage_response()
return False
else:
if len([c for c in self.equipment if isinstance(c, cards.Barile)]) > 0 or isinstance(self.character, characters.Jourdonnais):
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 or isinstance(self.character, chars.Jourdonnais):
print('has barrel')
self.pending_action = PendingAction.PICK
self.on_pick_cb = self.barrel_pick
else:
print('has mancato')
self.pending_action = PendingAction.RESPOND
self.expected_response = [cards.Mancato(0,0).name]
self.expected_response = [cs.Mancato(0, 0).name]
self.on_failed_response_cb = self.take_damage_response
self.notify_self()
return True
def get_indians(self, attacker):
self.attacker = attacker
if len([c for c in self.hand if isinstance(c, cards.Bang) or (isinstance(self.character, characters.CalamityJanet) and isinstance(c, cards.Mancato))]) == 0:
if len([c for c in self.hand if isinstance(c, cs.Bang) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0:
print('Cant defend')
self.take_damage_response()
return False
else:
print('has bang')
self.pending_action = PendingAction.RESPOND
self.expected_response = [cards.Bang(0,0).name]
self.expected_response = [cs.Bang(0, 0).name]
self.event_type = 'indians'
self.on_failed_response_cb = self.take_damage_response
self.notify_self()
@ -414,14 +366,14 @@ class Player:
def get_dueled(self, attacker):
self.attacker = attacker
if len([c for c in self.hand if isinstance(c, cards.Bang) or (isinstance(self.character, characters.CalamityJanet) and isinstance(c, cards.Mancato))]) == 0:
if len([c for c in self.hand if isinstance(c, cs.Bang) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0:
print('Cant defend')
self.take_damage_response()
self.game.responders_did_respond_resume_turn()
return False
else:
self.pending_action = PendingAction.RESPOND
self.expected_response = [cards.Bang(0,0).name]
self.expected_response = [cs.Bang(0, 0).name]
self.event_type = 'duel'
self.on_failed_response_cb = self.take_damage_response
self.notify_self()
@ -430,17 +382,19 @@ class Player:
def take_damage_response(self):
self.lives -= 1
if self.lives > 0:
if isinstance(self.character, characters.BartCassidy):
if isinstance(self.character, chars.BartCassidy):
self.hand.append(self.game.deck.draw())
elif isinstance(self.character, characters.ElGringo) and self.attacker and len(self.attacker.hand) > 0:
self.hand.append(self.attacker.hand.pop(randrange(0, len(self.attacker.hand))))
elif isinstance(self.character, chars.ElGringo) and self.attacker and len(self.attacker.hand) > 0:
self.hand.append(self.attacker.hand.pop(
randrange(0, len(self.attacker.hand))))
self.attacker.notify_self()
while self.lives <= 0 and len(self.game.players) > 2 and len([c for c in self.hand if isinstance(c, cards.Birra)]) > 0:
while self.lives <= 0 and len(self.game.players) > 2 and len([c for c in self.hand if isinstance(c, cs.Birra)]) > 0:
for i in range(len(self.hand)):
if isinstance(self.hand[i], cards.Birra):
if isinstance(self.hand[i], cs.Birra):
self.lives += 1
self.game.deck.scrap(self.hand.pop(i))
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha usato una birra per recuperare una vita.')
self.sio.emit('chat_message', room=self.game.name,
data=f'{self.name} ha usato una birra per recuperare una vita.')
break
self.mancato_needed = 0
self.notify_self()
@ -487,18 +441,20 @@ class Player:
return self.character.visibility_mod + covers
def scrap(self, card_index):
if self.is_my_turn or isinstance(self.character, characters.SidKetchum):
if self.is_my_turn or isinstance(self.character, chars.SidKetchum):
self.scrapped_cards += 1
if isinstance(self.character, characters.SidKetchum) and self.scrapped_cards == 2:
if isinstance(self.character, chars.SidKetchum) and self.scrapped_cards == 2:
self.scrapped_cards = 0
self.lives = min(self.lives+1, self.max_lives)
self.game.deck.scrap(self.hand.pop(card_index))
self.notify_self()
def end_turn(self, forced=False):
if not self.is_my_turn: return
if not self.is_my_turn:
return
if len(self.hand) > self.max_lives and not forced:
print(f"I {self.name} have to many cards in my hand and I can't end the turn")
print(
f"I {self.name} have to many cards in my hand and I can't end the turn")
else:
self.is_my_turn = False
self.pending_action = PendingAction.WAIT