less spaghetti is always better
This commit is contained in:
parent
00ac77e10a
commit
363ae304f0
159
backend/cards.py
159
backend/cards.py
@ -2,12 +2,14 @@ from typing import List, Set, Dict, Tuple, Optional
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
|
|
||||||
class Suit(IntEnum):
|
class Suit(IntEnum):
|
||||||
DIAMONDS = 0 # ♦
|
DIAMONDS = 0 # ♦
|
||||||
CLUBS = 1 # ♣
|
CLUBS = 1 # ♣
|
||||||
HEARTS = 2 # ♥
|
HEARTS = 2 # ♥
|
||||||
SPADES = 3 # ♠
|
SPADES = 3 # ♠
|
||||||
|
|
||||||
|
|
||||||
class Card(ABC):
|
class Card(ABC):
|
||||||
sym = {
|
sym = {
|
||||||
'A': 1,
|
'A': 1,
|
||||||
@ -15,7 +17,8 @@ class Card(ABC):
|
|||||||
'Q': 12,
|
'Q': 12,
|
||||||
'K': 13
|
'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__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.suit = suit
|
self.suit = suit
|
||||||
@ -29,39 +32,50 @@ class Card(ABC):
|
|||||||
self.sight_mod = sight_mod
|
self.sight_mod = sight_mod
|
||||||
self.range = range
|
self.range = range
|
||||||
if self.range != 0 and self.range != 99:
|
if self.range != 0 and self.range != 99:
|
||||||
self.alt_text = f'{self.range} 🔍'
|
self.alt_text = f'{self.range} 🔍'
|
||||||
self.desc = desc
|
self.desc = desc
|
||||||
self.need_target = False
|
self.need_target = False
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
char = ['♦️','♣️','♥️','♠️'][int(self.suit)]
|
char = ['♦️', '♣️', '♥️', '♠️'][int(self.suit)]
|
||||||
return f'{self.name} {char}{self.number}'
|
return f'{self.name} {char}{self.number}'
|
||||||
return super().__str__()
|
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):
|
class Barile(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Barile', number, is_equipment=True)
|
super().__init__(suit, 'Barile', number, is_equipment=True)
|
||||||
self.icon = '🛢'
|
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"
|
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):
|
class Dinamite(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Dinamite', number, is_equipment=True)
|
super().__init__(suit, 'Dinamite', number, is_equipment=True)
|
||||||
self.icon = '🧨'
|
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"
|
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):
|
class Mirino(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Mirino', number, is_equipment=True, sight_mod=1)
|
super().__init__(suit, 'Mirino', number, is_equipment=True, sight_mod=1)
|
||||||
self.icon = '🔎'
|
self.icon = '🔎'
|
||||||
self.desc = "Tu vedi gli altri giocatori a distanza -1"
|
self.desc = "Tu vedi gli altri giocatori a distanza -1"
|
||||||
|
|
||||||
|
|
||||||
class Mustang(Card):
|
class Mustang(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Mustang', number, is_equipment=True, vis_mod=1)
|
super().__init__(suit, 'Mustang', number, is_equipment=True, vis_mod=1)
|
||||||
self.icon = '🐎'
|
self.icon = '🐎'
|
||||||
self.desc = "Gli altri giocatori ti vedono a distanza +1"
|
self.desc = "Gli altri giocatori ti vedono a distanza +1"
|
||||||
|
|
||||||
|
|
||||||
class Prigione(Card):
|
class Prigione(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Prigione', number, is_equipment=True)
|
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.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
|
self.need_target = True
|
||||||
|
|
||||||
|
|
||||||
class Remington(Card):
|
class Remington(Card):
|
||||||
def __init__(self, suit, number):
|
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.icon = '🔫'
|
||||||
self.desc = "Puoi sparare a un giocatore che sia distante 3 o meno"
|
self.desc = "Puoi sparare a un giocatore che sia distante 3 o meno"
|
||||||
|
|
||||||
|
|
||||||
class RevCarabine(Card):
|
class RevCarabine(Card):
|
||||||
def __init__(self, suit, number):
|
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.icon = '🔫'
|
||||||
self.desc = "Puoi sparare a un giocatore che sia distante 4 o meno"
|
self.desc = "Puoi sparare a un giocatore che sia distante 4 o meno"
|
||||||
|
|
||||||
|
|
||||||
class Schofield(Card):
|
class Schofield(Card):
|
||||||
def __init__(self, suit, number):
|
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.icon = '🔫'
|
||||||
self.desc = "Puoi sparare a un giocatore che sia distante 2 o meno"
|
self.desc = "Puoi sparare a un giocatore che sia distante 2 o meno"
|
||||||
|
|
||||||
|
|
||||||
class Volcanic(Card):
|
class Volcanic(Card):
|
||||||
def __init__(self, suit, number):
|
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.icon = '🔫'
|
||||||
self.desc = "Puoi sparare a un giocatore che sia distante 1 o meno, tuttavia puoi giocare quanti bang vuoi"
|
self.desc = "Puoi sparare a un giocatore che sia distante 1 o meno, tuttavia puoi giocare quanti bang vuoi"
|
||||||
|
|
||||||
|
|
||||||
class Winchester(Card):
|
class Winchester(Card):
|
||||||
def __init__(self, suit, number):
|
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.icon = '🔫'
|
||||||
self.desc = "Puoi sparare a un giocatore che sia distante 5 o meno"
|
self.desc = "Puoi sparare a un giocatore che sia distante 5 o meno"
|
||||||
|
|
||||||
|
|
||||||
class Bang(Card):
|
class Bang(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Bang!', 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.desc = "Spara a un giocatore a distanta raggiungibile. Se non hai armi la distanza di default è 1"
|
||||||
self.need_target = True
|
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):
|
class Birra(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Birra', number)
|
super().__init__(suit, 'Birra', number)
|
||||||
self.icon = '🍺'
|
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"
|
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):
|
class CatBalou(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Cat Balou', 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.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
|
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):
|
class Diligenza(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Diligenza', number)
|
super().__init__(suit, 'Diligenza', number)
|
||||||
self.icon = '🚡'
|
self.icon = '🚡'
|
||||||
self.desc = "Pesca 2 carte dalla cima del mazzo"
|
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):
|
class Duello(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Duello', number)
|
super().__init__(suit, 'Duello', number)
|
||||||
@ -132,30 +203,67 @@ class Duello(Card):
|
|||||||
self.icon = '⚔️'
|
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"
|
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):
|
class Emporio(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Emporio', number)
|
super().__init__(suit, 'Emporio', number)
|
||||||
self.icon = '🏪'
|
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"
|
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):
|
class Gatling(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Gatling', number)
|
super().__init__(suit, 'Gatling', number)
|
||||||
self.icon = '🛰'
|
self.icon = '🛰'
|
||||||
self.desc = "Spara a tutti gli altri giocatori"
|
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):
|
class Indiani(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Indiani!', number)
|
super().__init__(suit, 'Indiani!', number)
|
||||||
self.icon = '🏹'
|
self.icon = '🏹'
|
||||||
self.desc = "Tutti gli altri giocatori devono scartare un Bang! o perdere una vita"
|
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):
|
class Mancato(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Mancato!', number)
|
super().__init__(suit, 'Mancato!', number)
|
||||||
self.icon = '😅'
|
self.icon = '😅'
|
||||||
self.desc = "Usa questa carta per annullare un bang"
|
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):
|
class Panico(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Panico!', number, range=1)
|
super().__init__(suit, 'Panico!', number, range=1)
|
||||||
@ -163,18 +271,47 @@ class Panico(Card):
|
|||||||
self.need_target = True
|
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"
|
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):
|
class Saloon(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'Saloon', number)
|
super().__init__(suit, 'Saloon', number)
|
||||||
self.desc = "Tutti i giocatori recuperano un punto vita compreso chi gioca la carta"
|
self.desc = "Tutti i giocatori recuperano un punto vita compreso chi gioca la carta"
|
||||||
self.icon = '🍻'
|
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):
|
class WellsFargo(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
super().__init__(suit, 'WellsFargo', number)
|
super().__init__(suit, 'WellsFargo', number)
|
||||||
self.desc = "Pesca 3 carte dalla cima del mazzo"
|
self.desc = "Pesca 3 carte dalla cima del mazzo"
|
||||||
self.icon = '💸'
|
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]:
|
def get_starting_deck() -> List[Card]:
|
||||||
return [
|
return [
|
||||||
Barile(Suit.SPADES, 'Q'),
|
Barile(Suit.SPADES, 'Q'),
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
from typing import List, Set, Dict, Tuple, Optional
|
from typing import List, Set, Dict, Tuple, Optional
|
||||||
import random
|
import random
|
||||||
from cards import Card, get_starting_deck
|
import cards as cs
|
||||||
|
|
||||||
class Deck:
|
class Deck:
|
||||||
def __init__(self, game):
|
def __init__(self, game):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.cards: List[Card] = get_starting_deck()
|
self.cards: List[cs.Card] = cs.get_starting_deck()
|
||||||
self.game = game
|
self.game = game
|
||||||
random.shuffle(self.cards)
|
random.shuffle(self.cards)
|
||||||
self.scrap_pile: List[Card] = []
|
self.scrap_pile: List[cs.Card] = []
|
||||||
print(f'Deck initialized with {len(self.cards)} cards')
|
print(f'Deck initialized with {len(self.cards)} cards')
|
||||||
|
|
||||||
def peek(self, n_cards: int) -> list:
|
def peek(self, n_cards: int) -> list:
|
||||||
return self.cards[:n_cards]
|
return self.cards[:n_cards]
|
||||||
|
|
||||||
def peek_scrap_pile(self) -> Card:
|
def peek_scrap_pile(self) -> cs.Card:
|
||||||
if len(self.scrap_pile) > 0:
|
if len(self.scrap_pile) > 0:
|
||||||
return self.scrap_pile[-1]
|
return self.scrap_pile[-1]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def pick_and_scrap(self) -> Card:
|
def pick_and_scrap(self) -> cs.Card:
|
||||||
card = self.cards.pop(0)
|
card = self.cards.pop(0)
|
||||||
self.scrap_pile.append(card)
|
self.scrap_pile.append(card)
|
||||||
self.game.notify_scrap_pile()
|
self.game.notify_scrap_pile()
|
||||||
return card
|
return card
|
||||||
|
|
||||||
def put_on_top(self, card: Card):
|
def put_on_top(self, card: cs.Card):
|
||||||
self.cards.insert(0, card)
|
self.cards.insert(0, card)
|
||||||
|
|
||||||
def draw(self) -> Card:
|
def draw(self) -> cs.Card:
|
||||||
card = self.cards.pop(0)
|
card = self.cards.pop(0)
|
||||||
if len(self.cards) == 0:
|
if len(self.cards) == 0:
|
||||||
self.cards = self.scrap_pile[:-1].copy()
|
self.cards = self.scrap_pile[:-1].copy()
|
||||||
@ -37,7 +37,7 @@ class Deck:
|
|||||||
self.scrap_pile = self.scrap_pile[-1:]
|
self.scrap_pile = self.scrap_pile[-1:]
|
||||||
return card
|
return card
|
||||||
|
|
||||||
def draw_from_scrap_pile(self) -> Card:
|
def draw_from_scrap_pile(self) -> cs.Card:
|
||||||
if len(self.scrap_pile) > 0:
|
if len(self.scrap_pile) > 0:
|
||||||
card = self.scrap_pile.pop(-1)
|
card = self.scrap_pile.pop(-1)
|
||||||
self.game.notify_scrap_pile()
|
self.game.notify_scrap_pile()
|
||||||
@ -45,6 +45,6 @@ class Deck:
|
|||||||
else:
|
else:
|
||||||
return self.draw()
|
return self.draw()
|
||||||
|
|
||||||
def scrap(self, card: Card):
|
def scrap(self, card: cs.Card):
|
||||||
self.scrap_pile.append(card)
|
self.scrap_pile.append(card)
|
||||||
self.game.notify_scrap_pile()
|
self.game.notify_scrap_pile()
|
||||||
|
@ -3,11 +3,10 @@ from enum import IntEnum
|
|||||||
import json
|
import json
|
||||||
from random import randrange
|
from random import randrange
|
||||||
import socketio
|
import socketio
|
||||||
import cards
|
|
||||||
|
|
||||||
import roles
|
import roles as r
|
||||||
import cards
|
import cards as cs
|
||||||
import characters
|
import characters as chars
|
||||||
|
|
||||||
class PendingAction(IntEnum):
|
class PendingAction(IntEnum):
|
||||||
PICK = 0
|
PICK = 0
|
||||||
@ -17,19 +16,22 @@ class PendingAction(IntEnum):
|
|||||||
WAIT = 4
|
WAIT = 4
|
||||||
CHOOSE = 5
|
CHOOSE = 5
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
|
import game as g
|
||||||
|
|
||||||
def __init__(self, name, sid, sio):
|
def __init__(self, name, sid, sio):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sid = sid
|
self.sid = sid
|
||||||
self.sio = sio
|
self.sio = sio
|
||||||
self.hand: cards.Card = []
|
self.hand: cs.Card = []
|
||||||
self.equipment: cards.Card = []
|
self.equipment: cs.Card = []
|
||||||
self.role: roles.Role = None
|
self.role: r.Role = None
|
||||||
self.character: characters.Character = None
|
self.character: chars.Character = None
|
||||||
self.lives = 0
|
self.lives = 0
|
||||||
self.max_lives = 0
|
self.max_lives = 0
|
||||||
self.game = None
|
self.game: g = None
|
||||||
self.is_my_turn = False
|
self.is_my_turn = False
|
||||||
self.is_waiting_for_action = True
|
self.is_waiting_for_action = True
|
||||||
self.has_played_bang = False
|
self.has_played_bang = False
|
||||||
@ -41,7 +43,7 @@ class Player:
|
|||||||
self.event_type: str = None
|
self.event_type: str = None
|
||||||
self.expected_response = None
|
self.expected_response = None
|
||||||
self.attacker = None
|
self.attacker = None
|
||||||
self.target_p: str = None
|
self.target_p: str = None
|
||||||
self.is_drawing = False
|
self.is_drawing = False
|
||||||
self.mancato_needed = 0
|
self.mancato_needed = 0
|
||||||
|
|
||||||
@ -52,17 +54,20 @@ class Player:
|
|||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
return self.game.handle_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
|
self.role = role
|
||||||
print(f'I {self.name} am a {role.name}, my goal is "{role.goal}"')
|
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):
|
def set_character(self, character: str):
|
||||||
print(self.available_characters, character)
|
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 = []
|
self.available_characters = []
|
||||||
print(f'I {self.name} chose character {self.character.name}')
|
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()
|
self.game.notify_character_selection()
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
@ -75,7 +80,8 @@ class Player:
|
|||||||
def set_available_character(self, available):
|
def set_available_character(self, available):
|
||||||
self.available_characters = available
|
self.available_characters = available
|
||||||
print(f'I {self.name} have to choose between {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):
|
def notify_card(self, player, card):
|
||||||
mess = {
|
mess = {
|
||||||
@ -86,9 +92,10 @@ class Player:
|
|||||||
self.sio.emit('notify_card', room=self.sid, data=mess)
|
self.sio.emit('notify_card', room=self.sid, data=mess)
|
||||||
|
|
||||||
def notify_self(self):
|
def notify_self(self):
|
||||||
if isinstance(self.character, characters.CalamityJanet):
|
if isinstance(self.character, chars.CalamityJanet):
|
||||||
self.expected_response = [cards.Mancato(0,0).name, cards.Bang(0,0).name]
|
self.expected_response = [
|
||||||
elif isinstance(self.character, characters.SuzyLafayette) and len(self.hand) == 0:
|
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())
|
self.hand.append(self.game.deck.draw())
|
||||||
ser = self.__dict__.copy()
|
ser = self.__dict__.copy()
|
||||||
ser.pop('game')
|
ser.pop('game')
|
||||||
@ -102,14 +109,18 @@ class Player:
|
|||||||
ser['attacker'] = self.attacker.name
|
ser['attacker'] = self.attacker.name
|
||||||
ser['sight'] = self.get_sight()
|
ser['sight'] = self.get_sight()
|
||||||
ser['lives'] = max(ser['lives'], 0)
|
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', room=self.sid, data=json.dumps(
|
||||||
self.sio.emit('self_vis', room=self.sid, data=json.dumps(self.game.get_visible_players(self), default=lambda o: o.__dict__))
|
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:
|
if self.lives <= 0 and self.max_lives > 0:
|
||||||
print('dying, attacker', self.attacker)
|
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.lives += 1
|
||||||
self.game.deck.scrap(self.hand.pop(randrange(0, len(self.hand))))
|
self.game.deck.scrap(self.hand.pop(
|
||||||
self.game.deck.scrap(self.hand.pop(randrange(0, len(self.hand))))
|
randrange(0, len(self.hand))))
|
||||||
|
self.game.deck.scrap(self.hand.pop(
|
||||||
|
randrange(0, len(self.hand))))
|
||||||
self.game.player_death(self)
|
self.game.player_death(self)
|
||||||
self.game.notify_all()
|
self.game.notify_all()
|
||||||
|
|
||||||
@ -117,13 +128,14 @@ class Player:
|
|||||||
if self.lives == 0:
|
if self.lives == 0:
|
||||||
return self.end_turn(forced=True)
|
return self.end_turn(forced=True)
|
||||||
self.scrapped_cards = 0
|
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')
|
print(f'I {self.name} was notified that it is my turn')
|
||||||
self.was_shot = False
|
self.was_shot = False
|
||||||
self.is_my_turn = True
|
self.is_my_turn = True
|
||||||
self.is_waiting_for_action = True
|
self.is_waiting_for_action = True
|
||||||
self.has_played_bang = False
|
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
|
self.pending_action = PendingAction.PICK
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.DRAW
|
self.pending_action = PendingAction.DRAW
|
||||||
@ -132,28 +144,29 @@ class Player:
|
|||||||
def draw(self, pile):
|
def draw(self, pile):
|
||||||
if self.pending_action != PendingAction.DRAW:
|
if self.pending_action != PendingAction.DRAW:
|
||||||
return
|
return
|
||||||
if isinstance(self.character, characters.KitCarlson):
|
if isinstance(self.character, chars.KitCarlson):
|
||||||
self.is_drawing = True
|
self.is_drawing = True
|
||||||
self.available_cards = [self.game.deck.draw() for i in range(3)]
|
self.available_cards = [self.game.deck.draw() for i in range(3)]
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.PLAY
|
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_from_scrap_pile())
|
||||||
self.hand.append(self.game.deck.draw())
|
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:
|
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.get_player_named(pile).hand.pop(
|
||||||
|
randrange(0, len(self.game.get_player_named(pile).hand))))
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
else:
|
else:
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
card: cards.Card = self.game.deck.draw()
|
card: cs.Card = self.game.deck.draw()
|
||||||
self.hand.append(card)
|
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:
|
for p in self.game.players:
|
||||||
if p != self:
|
if p != self:
|
||||||
p.notify_card(self, card)
|
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.hand.append(self.game.deck.draw())
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
@ -163,33 +176,36 @@ class Player:
|
|||||||
pickable_cards = 1 + self.character.pick_mod
|
pickable_cards = 1 + self.character.pick_mod
|
||||||
if self.is_my_turn:
|
if self.is_my_turn:
|
||||||
for i in range(len(self.equipment)):
|
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:
|
while pickable_cards > 0:
|
||||||
pickable_cards -= 1
|
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}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
if picked.suit == cards.Suit.SPADES and 2 <= picked.number <= 9 and pickable_cards == 0:
|
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.lives -= 3
|
||||||
self.game.deck.scrap(self.equipment.pop(i))
|
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.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')
|
print(f'{self.name} Boom, -3 hp')
|
||||||
else:
|
else:
|
||||||
self.game.next_player().equipment.append(self.equipment.pop(i))
|
self.game.next_player().equipment.append(self.equipment.pop(i))
|
||||||
self.game.next_player().notify_self()
|
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()
|
self.notify_self()
|
||||||
return
|
return
|
||||||
for i in range(len(self.equipment)):
|
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:
|
while pickable_cards > 0:
|
||||||
pickable_cards -= 1
|
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}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
if picked.suit != cards.Suit.HEARTS and pickable_cards == 0:
|
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.game.deck.scrap(self.equipment.pop(i))
|
||||||
self.end_turn(forced=True)
|
self.end_turn(forced=True)
|
||||||
return
|
return
|
||||||
@ -207,29 +223,30 @@ class Player:
|
|||||||
playable_cards = []
|
playable_cards = []
|
||||||
for i in range(len(self.hand)):
|
for i in range(len(self.hand)):
|
||||||
card = self.hand[i]
|
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
|
continue
|
||||||
elif isinstance(card, cards.Birra) and self.lives >= self.max_lives:
|
elif isinstance(card, cs.Birra) and self.lives >= self.max_lives:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
playable_cards.append(i)
|
playable_cs.append(i)
|
||||||
return playable_cards
|
return playable_cards
|
||||||
|
|
||||||
def get_public_description(self):
|
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]}"
|
s += f"equipment {[str(c) for c in self.equipment]}"
|
||||||
return s
|
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)):
|
if not (0 <= hand_index < len(self.hand)):
|
||||||
print('illegal')
|
print('illegal')
|
||||||
return
|
return
|
||||||
card: cards.Card = self.hand.pop(hand_index)
|
card: cs.Card = self.hand.pop(hand_index)
|
||||||
print(self.name, 'is playing ', card, ' against:', againts)
|
print(self.name, 'is playing ', card, ' against:', against)
|
||||||
if isinstance(card, cards.Prigione) and not isinstance(self.game.get_player_named(againts).role, roles.Sheriff):
|
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 {againts}.')
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
self.game.get_player_named(againts).equipment.append(card)
|
data=f'{self.name} ha giocato {card.name} contro {against}.')
|
||||||
self.game.get_player_named(againts).notify_self()
|
self.game.get_player_named(against).equipment.append(card)
|
||||||
|
self.game.get_player_named(against).notify_self()
|
||||||
elif card.is_equipment:
|
elif card.is_equipment:
|
||||||
if card.is_weapon:
|
if card.is_weapon:
|
||||||
has_weapon = False
|
has_weapon = False
|
||||||
@ -241,7 +258,7 @@ class Player:
|
|||||||
break
|
break
|
||||||
if not has_weapon:
|
if not has_weapon:
|
||||||
self.equipment.append(card)
|
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)):
|
for i in range(len(self.equipment)):
|
||||||
if type(self.equipment[i]) == type(card):
|
if type(self.equipment[i]) == type(card):
|
||||||
self.game.deck.scrap(self.equipment[i])
|
self.game.deck.scrap(self.equipment[i])
|
||||||
@ -250,74 +267,7 @@ class Player:
|
|||||||
else:
|
else:
|
||||||
self.equipment.append(card)
|
self.equipment.append(card)
|
||||||
else:
|
else:
|
||||||
did_play_card = False
|
did_play_card = card.play_card(self, against)
|
||||||
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
|
|
||||||
if did_play_card:
|
if did_play_card:
|
||||||
self.game.deck.scrap(card)
|
self.game.deck.scrap(card)
|
||||||
else:
|
else:
|
||||||
@ -327,7 +277,7 @@ class Player:
|
|||||||
def choose(self, card_index):
|
def choose(self, card_index):
|
||||||
if self.pending_action != PendingAction.CHOOSE:
|
if self.pending_action != PendingAction.CHOOSE:
|
||||||
return
|
return
|
||||||
if self.target_p and self.target_p != '': # panico, cat balou
|
if self.target_p and self.target_p != '': # panico, cat balou
|
||||||
target = self.game.get_player_named(self.target_p)
|
target = self.game.get_player_named(self.target_p)
|
||||||
card = None
|
card = None
|
||||||
if card_index >= len(target.hand):
|
if card_index >= len(target.hand):
|
||||||
@ -343,70 +293,72 @@ class Player:
|
|||||||
self.choose_action = ''
|
self.choose_action = ''
|
||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
elif self.is_drawing and isinstance(self.character, characters.KitCarlson): # specifico per personaggio
|
# specifico per personaggio
|
||||||
self.hand.append(self.available_cards.pop(card_index))
|
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:
|
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.is_drawing = False
|
||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
else: # emporio
|
else: # emporio
|
||||||
self.game.respond_emporio(self, card_index)
|
self.game.respond_emporio(self, card_index)
|
||||||
|
|
||||||
def barrel_pick(self):
|
def barrel_pick(self):
|
||||||
pickable_cards = 1 + self.character.pick_mod
|
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
|
pickable_cards = 2
|
||||||
while pickable_cards > 0:
|
while pickable_cards > 0:
|
||||||
pickable_cards -= 1
|
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}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'{self.name} ha estratto {picked}.')
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
if picked.suit == cards.Suit.HEARTS:
|
data=f'{self.name} ha estratto {picked}.')
|
||||||
|
if picked.suit == cs.Suit.HEARTS:
|
||||||
self.mancato_needed -= 1
|
self.mancato_needed -= 1
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
if self.mancato_needed <= 0:
|
if self.mancato_needed <= 0:
|
||||||
self.game.responders_did_respond_resume_turn()
|
self.game.responders_did_respond_resume_turn()
|
||||||
return
|
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.take_damage_response()
|
||||||
self.game.responders_did_respond_resume_turn()
|
self.game.responders_did_respond_resume_turn()
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.RESPOND
|
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.on_failed_response_cb = self.take_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def get_banged(self, attacker, double=False):
|
def get_banged(self, attacker, double=False):
|
||||||
self.attacker = attacker
|
self.attacker = attacker
|
||||||
self.mancato_needed = 1 if not double else 2
|
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')
|
print('Cant defend')
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
return False
|
return False
|
||||||
else:
|
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')
|
print('has barrel')
|
||||||
self.pending_action = PendingAction.PICK
|
self.pending_action = PendingAction.PICK
|
||||||
self.on_pick_cb = self.barrel_pick
|
self.on_pick_cb = self.barrel_pick
|
||||||
else:
|
else:
|
||||||
print('has mancato')
|
print('has mancato')
|
||||||
self.pending_action = PendingAction.RESPOND
|
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.on_failed_response_cb = self.take_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_indians(self, attacker):
|
def get_indians(self, attacker):
|
||||||
self.attacker = 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')
|
print('Cant defend')
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print('has bang')
|
print('has bang')
|
||||||
self.pending_action = PendingAction.RESPOND
|
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.event_type = 'indians'
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
@ -414,14 +366,14 @@ class Player:
|
|||||||
|
|
||||||
def get_dueled(self, attacker):
|
def get_dueled(self, attacker):
|
||||||
self.attacker = 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')
|
print('Cant defend')
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
self.game.responders_did_respond_resume_turn()
|
self.game.responders_did_respond_resume_turn()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.RESPOND
|
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.event_type = 'duel'
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
@ -430,17 +382,19 @@ class Player:
|
|||||||
def take_damage_response(self):
|
def take_damage_response(self):
|
||||||
self.lives -= 1
|
self.lives -= 1
|
||||||
if self.lives > 0:
|
if self.lives > 0:
|
||||||
if isinstance(self.character, characters.BartCassidy):
|
if isinstance(self.character, chars.BartCassidy):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
elif isinstance(self.character, characters.ElGringo) and self.attacker and len(self.attacker.hand) > 0:
|
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.hand.append(self.attacker.hand.pop(
|
||||||
|
randrange(0, len(self.attacker.hand))))
|
||||||
self.attacker.notify_self()
|
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)):
|
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.lives += 1
|
||||||
self.game.deck.scrap(self.hand.pop(i))
|
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
|
break
|
||||||
self.mancato_needed = 0
|
self.mancato_needed = 0
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
@ -487,18 +441,20 @@ class Player:
|
|||||||
return self.character.visibility_mod + covers
|
return self.character.visibility_mod + covers
|
||||||
|
|
||||||
def scrap(self, card_index):
|
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
|
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.scrapped_cards = 0
|
||||||
self.lives = min(self.lives+1, self.max_lives)
|
self.lives = min(self.lives+1, self.max_lives)
|
||||||
self.game.deck.scrap(self.hand.pop(card_index))
|
self.game.deck.scrap(self.hand.pop(card_index))
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def end_turn(self, forced=False):
|
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:
|
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:
|
else:
|
||||||
self.is_my_turn = False
|
self.is_my_turn = False
|
||||||
self.pending_action = PendingAction.WAIT
|
self.pending_action = PendingAction.WAIT
|
||||||
|
Loading…
Reference in New Issue
Block a user