add fantasma, serpente a sonagli

This commit is contained in:
Alberto Xamin 2023-01-06 17:16:18 +00:00
parent e7bfcb02ff
commit 0668fbf670
6 changed files with 204 additions and 62 deletions

View File

@ -1,11 +1,31 @@
from typing import List from typing import List
from bang.cards import Card, Suit import bang.roles as r
import bang.players as pl
from bang.cards import Card, Suit, Bang
import bang.expansions.fistful_of_cards.card_events as ce
class Fantasma(Card): class Fantasma(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Fantasma', number, is_equipment=True) super().__init__(suit, 'Fantasma', number, is_equipment=True)
self.icon = '👻️' #porta in vita i giocatori morti ma non self.icon = '👻️' #porta in vita i giocatori morti ma non
#TODO
def play_card(self, player, against, _with=None):
if (player.game.check_event(ce.IlGiudice)):
return False
if len(player.game.get_dead_players(include_ghosts=False)) > 0:
player.pending_action = pl.PendingAction.CHOOSE
player.choose_text = 'choose_fantasma'
player.available_cards = [{
'name': p.name,
'icon': p.role.icon if(player.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
'avatar': p.avatar,
'alt_text': ''.join(['❤️']*p.lives)+''.join(['💀']*(p.max_lives-p.lives)),
'is_character': True,
'noDesc': True
} for p in player.game.get_dead_players(include_ghosts=False)]
player.game.deck.scrap(self, True)
return True
return False
class Lemat(Card): class Lemat(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
@ -19,11 +39,22 @@ class SerpenteASonagli(Card):
self.need_target = True self.need_target = True
self.icon = '🐍️' # Ogni turno pesca se il seme picche -1hp self.icon = '🐍️' # Ogni turno pesca se il seme picche -1hp
self.alt_text = "♠️ =💔" self.alt_text = "♠️ =💔"
#TODO
def play_card(self, player, against, _with=None):
if (player.game.check_event(ce.IlGiudice)):
return False
if against != None:
self.reset_card()
player.sio.emit('chat_message', room=player.game.name,
data=f'_play_card_against|{player.name}|{self.name}|{against}')
player.game.get_player_named(against).equipment.append(self)
player.game.get_player_named(against).notify_self()
return True
return False
class Shotgun(Card): class Shotgun(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Shotgun', number, is_equipment=True, range=1) super().__init__(suit, 'Shotgun', number, is_equipment=True, is_weapon=True, range=1)
self.icon = '🔫' # Ogni volta che colpisci un giocatore deve scartare una carta self.icon = '🔫' # Ogni volta che colpisci un giocatore deve scartare una carta
#TODO #TODO
@ -57,16 +88,17 @@ class Tomahawk(Card):
self.need_target = True self.need_target = True
def play_card(self, player, against, _with=None): def play_card(self, player, against, _with=None):
if against != None: if against != None and player.game.can_card_reach(self, player, against):
super().play_card(player, against=against) super().play_card(player, against=against)
player.game.attack(player, against) player.game.attack(player, against, card_name=self.name)
return True return True
return False return False
class Sventagliata(Card): class Sventagliata(Bang):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Sventagliata', number) super().__init__(suit, number)
self.icon = '💕️' self.name = 'Sventagliata'
self.icon = '🎏'
self.alt_text = "💥💥" # spara al target e anche, a uno a distanza 1 dal target self.alt_text = "💥💥" # spara al target e anche, a uno a distanza 1 dal target
self.need_target = True self.need_target = True
@ -74,7 +106,7 @@ class Sventagliata(Card):
if against != None: if against != None:
#TODO #TODO
# super().play_card(player, against=against) # super().play_card(player, against=against)
# player.game.attack(player, against) # player.game.attack(player, against, card_name=self.name)
return True return True
return False return False
@ -89,7 +121,7 @@ class Salvo(Card):
if against != None: if against != None:
#TODO #TODO
# super().play_card(player, against=against) # super().play_card(player, against=against)
# player.game.attack(player, against) # player.game.attack(player, against, card_name=self.name)
return True return True
return False return False
@ -97,7 +129,7 @@ class Mira(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Mira', number) super().__init__(suit, 'Mira', number)
self.icon = '👌🏻' self.icon = '👌🏻'
self.alt_text = "💥🃏 | 👤💥💥" self.alt_text = "💥🃏💔💔"
self.need_target = True self.need_target = True
self.need_with = True self.need_with = True
@ -105,7 +137,7 @@ class Mira(Card):
if against != None: if against != None:
#TODO #TODO
# super().play_card(player, against=against) # super().play_card(player, against=against)
# player.game.attack(player, against) # player.game.attack(player, against, card_name=self.name)
return True return True
return False return False
@ -113,7 +145,7 @@ class Bandidos(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Bandidos', number) super().__init__(suit, 'Bandidos', number)
self.icon = '🤠️' self.icon = '🤠️'
self.alt_text = "👤🃏🃏 | 👤💔" self.alt_text = "👤🃏🃏/💔"
def play_card(self, player, against, _with=None): def play_card(self, player, against, _with=None):
#TODO #TODO
@ -161,19 +193,19 @@ def get_starting_deck() -> List[Card]:
cards = [ cards = [
Fantasma(Suit.SPADES, 9), Fantasma(Suit.SPADES, 9),
Fantasma(Suit.SPADES, 10), Fantasma(Suit.SPADES, 10),
Lemat(Suit.DIAMONDS, 4), # Lemat(Suit.DIAMONDS, 4),
SerpenteASonagli(Suit.HEARTS, 7), SerpenteASonagli(Suit.HEARTS, 7),
Shotgun(Suit.SPADES, 'K'), # Shotgun(Suit.SPADES, 'K'),
Taglia(Suit.CLUBS, 9), # Taglia(Suit.CLUBS, 9),
UltimoGiro(Suit.DIAMONDS, 8), UltimoGiro(Suit.DIAMONDS, 8),
Tomahawk(Suit.DIAMONDS, 'A'), Tomahawk(Suit.DIAMONDS, 'A'),
Sventagliata(Suit.SPADES, 2), # Sventagliata(Suit.SPADES, 2),
Salvo(Suit.HEARTS, 5), # Salvo(Suit.HEARTS, 5),
Bandidos(Suit.DIAMONDS,'Q'), # gli altri giocatori scelgono se scartare 2 carte o perdere 1 punto vita # Bandidos(Suit.DIAMONDS,'Q'), # gli altri giocatori scelgono se scartare 2 carte o perdere 1 punto vita
Fuga(Suit.HEARTS, 3), # evita l'effetto di carte marroni (tipo panico cat balou) di cui sei bersaglio # Fuga(Suit.HEARTS, 3), # evita l'effetto di carte marroni (tipo panico cat balou) di cui sei bersaglio
Mira(Suit.CLUBS, 6), # Mira(Suit.CLUBS, 6),
Poker(Suit.HEARTS, 'J'), # tutti gli altri scartano 1 carta a scelta, se non ci sono assi allora pesca 2 dal mazzo # Poker(Suit.HEARTS, 'J'), # tutti gli altri scartano 1 carta a scelta, se non ci sono assi allora pesca 2 dal mazzo
RitornoDiFiamma(Suit.CLUBS, 'Q'), # un mancato che fa bang # RitornoDiFiamma(Suit.CLUBS, 'Q'), # un mancato che fa bang
] ]
for c in cards: for c in cards:
c.expansion_icon = '👻️' c.expansion_icon = '👻️'

View File

@ -5,6 +5,7 @@ import socketio
import eventlet import eventlet
import bang.players as pl import bang.players as pl
import bang.cards as cs
import bang.characters as characters import bang.characters as characters
import bang.expansions.dodge_city.characters as chd import bang.expansions.dodge_city.characters as chd
from bang.deck import Deck from bang.deck import Deck
@ -15,6 +16,33 @@ import bang.expansions.gold_rush.shop_cards as grc
import bang.expansions.gold_rush.characters as grch import bang.expansions.gold_rush.characters as grch
from metrics import Metrics from metrics import Metrics
debug_commands = [
{'cmd':'/debug', 'help':'Toggles the debug mode'},
{'cmd':'/set_chars', 'help':'Set how many characters to distribute - sample /set_chars 3'},
{'cmd':'/suicide', 'help':'Kills you'},
{'cmd':'/nextevent', 'help':'Flip the next event card'},
{'cmd':'/notify', 'help':'Send a message to a player - sample /notify player hi!'},
{'cmd':'/show_cards', 'help':'View the hand of another - sample /show_cards player'},
{'cmd':'/ddc', 'help':'Destroy all cards - sample /ddc player'},
{'cmd':'/dsh', 'help':'Set health - sample /dsh player'},
# {'cmd':'/togglebot', 'help':''},
{'cmd':'/cancelgame', 'help':'Stops the current game'},
{'cmd':'/startgame', 'help':'Force starts the game'},
{'cmd':'/setbotspeed', 'help':'Changes the bot response time - sample /setbotspeed 0.5'},
# {'cmd':'/addex', 'help':''},
{'cmd':'/setcharacter', 'help':'Changes your current character - sample /setcharacter Willy The Kid'},
{'cmd':'/setevent', 'help':'Changes the event deck - sample /setevent 0 Manette'},
{'cmd':'/removecard', 'help':'Remove a card from hand/equip - sample /removecard 0'},
{'cmd':'/getcard', 'help':'Get a brand new card - sample /getcard Birra'},
{'cmd':'/meinfo', 'help':'Get player data'},
{'cmd':'/gameinfo', 'help':'Get game data'},
{'cmd':'/playerinfo', 'help':'Get player data - sample /playerinfo player'},
{'cmd':'/mebot', 'help':'Toggles bot mode'},
{'cmd':'/getnuggets', 'help':'Adds nuggets to yourself - sample /getnuggets 5'},
{'cmd':'/startwithseed', 'help':'start the game with custom seed'},
{'cmd':'/getset', 'help':'get extension set of cards sample - /get valley', 'admin':True},
]
class Game: class Game:
def __init__(self, name, sio:socketio): def __init__(self, name, sio:socketio):
super().__init__() super().__init__()
@ -158,31 +186,7 @@ class Game:
}) })
self.sio.emit('debug', room=self.name, data=self.debug) self.sio.emit('debug', room=self.name, data=self.debug)
if self.debug: if self.debug:
commands = [ self.sio.emit('commands', room=self.name, data=[x for x in debug_commands if 'admin' not in x])
{'cmd':'/debug', 'help':'Toggles the debug mode'},
{'cmd':'/set_chars', 'help':'Set how many characters to distribute - sample /set_chars 3'},
{'cmd':'/suicide', 'help':'Kills you'},
{'cmd':'/nextevent', 'help':'Flip the next event card'},
{'cmd':'/notify', 'help':'Send a message to a player - sample /notify player hi!'},
{'cmd':'/show_cards', 'help':'View the hand of another - sample /show_cards player'},
{'cmd':'/ddc', 'help':'Destroy all cards - sample /ddc player'},
{'cmd':'/dsh', 'help':'Set health - sample /dsh player'},
# {'cmd':'/togglebot', 'help':''},
{'cmd':'/cancelgame', 'help':'Stops the current game'},
{'cmd':'/startgame', 'help':'Force starts the game'},
{'cmd':'/setbotspeed', 'help':'Changes the bot response time - sample /setbotspeed 0.5'},
# {'cmd':'/addex', 'help':''},
{'cmd':'/setcharacter', 'help':'Changes your current character - sample /setcharacter Willy The Kid'},
{'cmd':'/setevent', 'help':'Changes the event deck - sample /setevent 0 Manette'},
{'cmd':'/removecard', 'help':'Remove a card from hand/equip - sample /removecard 0'},
{'cmd':'/getcard', 'help':'Get a brand new card - sample /getcard Birra'},
{'cmd':'/meinfo', 'help':'Get player data'},
{'cmd':'/gameinfo', 'help':'Get game data'},
{'cmd':'/playerinfo', 'help':'Get player data - sample /playerinfo player'},
{'cmd':'/mebot', 'help':'Toggles bot mode'},
{'cmd':'/getnuggets', 'help':'Adds nuggets to yourself - sample /getnuggets 5'},
{'cmd':'/startwithseed', 'help':'start the game with custom seed'}]
self.sio.emit('commands', room=self.name, data=commands)
else: else:
self.sio.emit('commands', room=self.name, data=[{'cmd':'/debug', 'help':'Toggles the debug mode'}]) self.sio.emit('commands', room=self.name, data=[{'cmd':'/debug', 'help':'Toggles the debug mode'}])
self.sio.emit('spectators', room=self.name, data=len(self.spectators)) self.sio.emit('spectators', room=self.name, data=len(self.spectators))
@ -205,6 +209,7 @@ class Game:
self.notify_room() self.notify_room()
def feature_flags(self): def feature_flags(self):
if 'the_valley_of_shadows' not in self.expansions:
self.available_expansions.append('the_valley_of_shadows') self.available_expansions.append('the_valley_of_shadows')
self.notify_room() self.notify_room()
@ -346,6 +351,11 @@ class Game:
if self.pending_winners and not self.someone_won: if self.pending_winners and not self.someone_won:
return self.announces_winners() return self.announces_winners()
def can_card_reach(self, card: cs.Card, player: pl.Player, target:str):
if card and card.range != 0 and card.range < 99:
return not any((True for p in self.get_visible_players(player) if p['name'] == target and p['dist'] >= card.range))
return True
def attack(self, attacker: pl.Player, target_username:str, double:bool=False, card_name:str=None): def attack(self, attacker: pl.Player, target_username:str, double:bool=False, card_name:str=None):
if self.get_player_named(target_username).get_banged(attacker=attacker, double=double, card_name=card_name): if self.get_player_named(target_username).get_banged(attacker=attacker, double=double, card_name=card_name):
self.ready_count = 0 self.ready_count = 0
@ -510,7 +520,7 @@ class Game:
pl.hand.append(self.deck.draw()) pl.hand.append(self.deck.draw())
pl.hand.append(self.deck.draw()) pl.hand.append(self.deck.draw())
pl.notify_self() pl.notify_self()
elif self.check_event(ceh.CittaFantasma): elif self.check_event(ceh.CittaFantasma) or self.players[self.turn].is_ghost:
print(f'{self.name}: {self.players[self.turn]} is dead, event ghost') print(f'{self.name}: {self.players[self.turn]} is dead, event ghost')
self.players[self.turn].is_ghost = True self.players[self.turn].is_ghost = True
else: else:
@ -777,8 +787,8 @@ class Game:
def get_alive_players(self): def get_alive_players(self):
return [p for p in self.players if not p.is_dead or p.is_ghost] return [p for p in self.players if not p.is_dead or p.is_ghost]
def get_dead_players(self): def get_dead_players(self, include_ghosts=True):
return [p for p in self.players if p.is_dead] return [p for p in self.players if p.is_dead and (include_ghosts or not p.is_ghost)]
def notify_all(self): def notify_all(self):
if self.started: if self.started:

View File

@ -12,6 +12,7 @@ import bang.expansions.fistful_of_cards.card_events as ce
import bang.expansions.high_noon.card_events as ceh import bang.expansions.high_noon.card_events as ceh
import bang.expansions.gold_rush.shop_cards as grc import bang.expansions.gold_rush.shop_cards as grc
import bang.expansions.gold_rush.characters as grch import bang.expansions.gold_rush.characters as grch
import bang.expansions.the_valley_of_shadows.cards as tvosc
import eventlet import eventlet
from typing import List from typing import List
from metrics import Metrics from metrics import Metrics
@ -208,6 +209,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 any((True for c in self.equipment if isinstance(c, tvosc.Fantasma))):
self.is_ghost = True
elif self.is_ghost and not self.game.check_event(ceh.CittaFantasma):
self.is_ghost = False
if self.is_ghost: self.lives = 0 if self.is_ghost: self.lives = 0
if self.pending_action == PendingAction.DRAW and self.game.check_event(ce.Peyote): if self.pending_action == PendingAction.DRAW and self.game.check_event(ce.Peyote):
self.available_cards = [{ self.available_cards = [{
@ -247,6 +252,7 @@ class Player:
self.choose_text = 'choose_sid_scrap' self.choose_text = 'choose_sid_scrap'
self.available_cards = self.hand self.available_cards = self.hand
self.lives += 1 self.lives += 1
ser = self.__dict__.copy() ser = self.__dict__.copy()
ser.pop('game') ser.pop('game')
ser.pop('sio') ser.pop('sio')
@ -269,14 +275,12 @@ class Player:
self.pending_action = PendingAction.WAIT self.pending_action = PendingAction.WAIT
ser['hand'] = [] ser['hand'] = []
ser['equipment'] = [] ser['equipment'] = []
self.sio.emit('self', room=self.sid, data=json.dumps( self.sio.emit('self', room=self.sid, data=json.dumps(ser, default=lambda o: o.__dict__))
ser, default=lambda o: o.__dict__))
self.game.player_death(self) self.game.player_death(self)
if self.game and self.game.started: # falso quando un bot viene eliminato dalla partita if self.game and self.game.started: # falso quando un bot viene eliminato dalla partita
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_vis', room=self.sid, data=json.dumps(self.game.get_visible_players(self), default=lambda o: o.__dict__))
self.game.notify_all() self.game.notify_all()
self.sio.emit('self', room=self.sid, data=json.dumps( self.sio.emit('self', room=self.sid, data=json.dumps(ser, default=lambda o: o.__dict__))
ser, default=lambda o: o.__dict__))
def bot_spin(self): def bot_spin(self):
while self.is_bot and self.game != None and not self.game.shutting_down: while self.is_bot and self.game != None and not self.game.shutting_down:
@ -449,6 +453,7 @@ class Player:
'name': p.name, 'name': p.name,
'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠', 'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
'alt_text': ''.join(['❤️']*p.lives)+''.join(['💀']*(p.max_lives-p.lives)), 'alt_text': ''.join(['❤️']*p.lives)+''.join(['💀']*(p.max_lives-p.lives)),
'avatar': p.avatar,
'is_character': True, 'is_character': True,
'noDesc': True 'noDesc': True
} for p in self.game.get_alive_players() if p != self and p.lives < p.max_lives] } for p in self.game.get_alive_players() if p != self and p.lives < p.max_lives]
@ -460,7 +465,7 @@ class Player:
self.available_cards = [self.character, self.not_chosen_character] self.available_cards = [self.character, self.not_chosen_character]
self.choose_text = 'choose_nuova_identita' self.choose_text = 'choose_nuova_identita'
self.pending_action = PendingAction.CHOOSE self.pending_action = PendingAction.CHOOSE
elif not self.game.check_event(ce.Lazo) and any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) for c in self.equipment]): elif not self.game.check_event(ce.Lazo) and any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) or isinstance(c, tvosc.SerpenteASonagli) for c in self.equipment]):
self.is_giving_life = False self.is_giving_life = False
self.pending_action = PendingAction.PICK self.pending_action = PendingAction.PICK
else: else:
@ -490,6 +495,7 @@ class Player:
'name': p.name, 'name': p.name,
'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠', 'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
'is_character': True, 'is_character': True,
'avatar': p.avatar,
'noDesc': True 'noDesc': True
} for p in self.game.get_alive_players() if len(p.equipment) > 0 and p != self] } for p in self.game.get_alive_players() if len(p.equipment) > 0 and p != self]
self.available_cards.append({'icon': '', 'noDesc': True}) self.available_cards.append({'icon': '', 'noDesc': True})
@ -624,7 +630,20 @@ class Player:
self.sio.emit('chat_message', room=self.game.name, data=f'_prison_free|{self.name}') self.sio.emit('chat_message', room=self.game.name, data=f'_prison_free|{self.name}')
break break
break break
if any([isinstance(c, cs.Prigione) for c in self.equipment]): for i in range(len(self.equipment)):
if isinstance(self.equipment[i], tvosc.SerpenteASonagli):
while pickable_cards > 0:
pickable_cards -= 1
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'_flipped|{self.name}|{picked.name}|{picked.num_suit()}')
if picked.check_suit(self.game, [cs.Suit.SPADES]) and pickable_cards == 0:
self.lives -= 1
self.sio.emit('chat_message', room=self.game.name, data=f'_snake_bit|{self.name}')
self.end_turn(forced=True)
return
if any((isinstance(c, cs.Prigione) for c in self.equipment)):
self.notify_self() self.notify_self()
return return
if isinstance(self.real_character, chd.VeraCuster): if isinstance(self.real_character, chd.VeraCuster):
@ -799,6 +818,15 @@ class Player:
player.notify_self() player.notify_self()
self.pending_action = PendingAction.PLAY self.pending_action = PendingAction.PLAY
self.notify_self() self.notify_self()
elif 'choose_fantasma' in self.choose_text:
if card_index <= len(self.available_cards):
player = self.game.get_player_named(self.available_cards[card_index]['name'])
player.equipment.append(self.game.deck.scrap_pile.pop(-1))
player.notify_self()
self.game.notify_all()
self.sio.emit('chat_message', room=player.game.name, data=f'_play_card_against|{player.name}|Fantasma|{player.name}')
self.pending_action = PendingAction.PLAY
self.notify_self()
elif self.game.check_event(ceh.NuovaIdentita) and self.choose_text == 'choose_nuova_identita': elif self.game.check_event(ceh.NuovaIdentita) and self.choose_text == 'choose_nuova_identita':
if card_index == 1: # the other character if card_index == 1: # the other character
self.character = self.not_chosen_character self.character = self.not_chosen_character
@ -1251,6 +1279,7 @@ class Player:
'name': p.name, 'name': p.name,
'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠', 'icon': p.role.icon if(self.game.initial_players == 3) else '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
'is_character': True, 'is_character': True,
'avatar': p.avatar,
'alt_text': ''.join(['🎴️'] * len(p.gold_rush_equipment)), 'alt_text': ''.join(['🎴️'] * len(p.gold_rush_equipment)),
'noDesc': True 'noDesc': True
} for p in self.game.get_alive_players() if p != self and len([e for e in p.gold_rush_equipment if e.number + 1 <= self.gold_nuggets]) > 0] } for p in self.game.get_alive_players() if p != self and len([e for e in p.gold_rush_equipment if e.number + 1 <= self.gold_nuggets]) > 0]
@ -1336,7 +1365,7 @@ class Player:
self.play_turn(can_play_vendetta=False) self.play_turn(can_play_vendetta=False)
return return
##Ghost## ##Ghost##
if self.is_dead and self.is_ghost and self.game.check_event(ceh.CittaFantasma): if self.is_dead and self.is_ghost and self.game.check_event(ceh.CittaFantasma) and not any((True for c in self.equipment if isinstance(c, tvosc.Fantasma))):
self.is_ghost = False self.is_ghost = False
for i in range(len(self.hand)): for i in range(len(self.hand)):
self.game.deck.scrap(self.hand.pop(), True) self.game.deck.scrap(self.hand.pop(), True)

View File

@ -0,0 +1,71 @@
from random import randint
from bang.characters import Character
from bang.expansions.the_valley_of_shadows.cards import *
from tests.dummy_socket import DummySocket
from bang.deck import Deck
from bang.game import Game
from bang.players import Player, PendingAction
# test UltimoGiro
def test_ultimo_giro():
sio = DummySocket()
g = Game('test', sio)
ps = [Player(f'p{i}', f'p{i}', sio) for i in range(3)]
for p in ps:
g.add_player(p)
g.start_game()
for p in ps:
p.available_characters = [Character('test_char', 4)]
p.set_character(p.available_characters[0].name)
ultimo_giro_guy = g.players[g.turn]
ultimo_giro_guy.draw('')
ultimo_giro_guy.lives = 3
ultimo_giro_guy.hand = [UltimoGiro(0,0)]
assert ultimo_giro_guy.lives == 3
ultimo_giro_guy.play_card(0)
assert ultimo_giro_guy.lives == 4
# test Tomahawk
def test_tomahawk():
sio = DummySocket()
g = Game('test', sio)
ps = [Player(f'p{i}', f'p{i}', sio) for i in range(6)]
for p in ps:
g.add_player(p)
g.start_game()
for p in ps:
p.available_characters = [Character('test_char', 4)]
p.set_character(p.available_characters[0].name)
tomahawk_guy = g.players[g.turn]
tomahawk_guy.draw('')
tomahawk_guy.hand = [Tomahawk(0,0)]
assert len(tomahawk_guy.hand) == 1
tomahawk_guy.play_card(0, g.players[(g.turn+3)%6].name)
assert len(tomahawk_guy.hand) == 1
tomahawk_guy.play_card(0, g.players[(g.turn+1)%6].name)
assert len(tomahawk_guy.hand) == 0
# test Fantasma
def test_fantasma():
sio = DummySocket()
g = Game('test', sio)
ps = [Player(f'p{i}', f'p{i}', sio) for i in range(3)]
for p in ps:
g.add_player(p)
g.start_game()
for p in ps:
p.available_characters = [Character('test_char', 4)]
p.set_character(p.available_characters[0].name)
fantasma_guy = g.players[g.turn]
fantasma_guy.lives = 0
fantasma_guy.notify_self()
pl = g.players[g.turn]
pl.draw('')
pl.hand = [Fantasma(0,0)]
pl.play_card(0)
assert pl.pending_action == PendingAction.CHOOSE
assert pl.available_cards[0]['name'] == fantasma_guy.name
pl.choose(0)
assert pl.pending_action == PendingAction.PLAY
assert len(fantasma_guy.equipment) == 1 and isinstance(fantasma_guy.equipment[0], Fantasma)

View File

@ -713,7 +713,7 @@
}, },
"Sventagliata": { "Sventagliata": {
"name": "Sventagliata", "name": "Sventagliata",
"desc": "Conta come l'unico BANGI del turno. Anche un giocatore a tua scelta a distanza 1 dal bersaglio (se ce, te escluso) è bersaglio di un BANG.." "desc": "Conta come l'unico BANG! del turno. Anche un giocatore a tua scelta a distanza 1 dal bersaglio (se ce, te escluso) è bersaglio di un BANG."
}, },
"UltimoGiro": { "UltimoGiro": {
"name": "Ultimo Giro", "name": "Ultimo Giro",