From 622d8d7330ddccef0c6ac50843bea57fcc2dc62a Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sun, 20 Dec 2020 14:19:50 +0100 Subject: [PATCH] roulette russa --- .../fistful_of_cards/card_events.py | 4 +- backend/bang/game.py | 98 ++++++++++++------- backend/bang/players.py | 12 +-- 3 files changed, 72 insertions(+), 42 deletions(-) diff --git a/backend/bang/expansions/fistful_of_cards/card_events.py b/backend/bang/expansions/fistful_of_cards/card_events.py index 86cd342..5d414fc 100644 --- a/backend/bang/expansions/fistful_of_cards/card_events.py +++ b/backend/bang/expansions/fistful_of_cards/card_events.py @@ -84,7 +84,7 @@ class Rimbalzo(CardEvent): self.desc_eng = "The player can play bang against the cards equipped by the other players, if they do not play miss they are discarded" class RouletteRussa(CardEvent): - def __init__(self):#TODO + def __init__(self): super().__init__("Roulette Russa", "🇷🇺") self.desc = "A partire dallo sceriffo, ogni giocatore scarta 1 mancato, il primo che non lo fa perde 2 vite" self.desc_eng = "Starting from the sheriff, every player discards 1 missed, the first one that doesn't loses 2 HP" @@ -110,6 +110,6 @@ def get_all_events(): Peyote(), # Ranch(), # Rimbalzo(), - # RouletteRussa(), + RouletteRussa(), Vendetta(), ] \ No newline at end of file diff --git a/backend/bang/game.py b/backend/bang/game.py index 7c03837..3b2a3a5 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -2,7 +2,7 @@ from typing import List, Set, Dict, Tuple, Optional import random import socketio -import bang.players as players +import bang.players as pl import bang.characters as characters from bang.deck import Deck import bang.roles as roles @@ -14,8 +14,8 @@ class Game: super().__init__() self.sio = sio self.name = name - self.players: List[players.Player] = [] - self.dead_players: List[players.Player] = [] + self.players: List[pl.Player] = [] + self.dead_players: List[pl.Player] = [] self.deck: Deck = None self.started = False self.turn = 0 @@ -29,6 +29,7 @@ class Game: self.is_competitive = False self.disconnect_bot = True self.player_bangs = 0 + self.is_russian_roulette_on = False def notify_room(self, sid=None): if len([p for p in self.players if p.character == None]) != 0 or sid: @@ -60,7 +61,7 @@ class Game: self.disconnect_bot = not self.disconnect_bot self.notify_room() - def add_player(self, player: players.Player): + def add_player(self, player: pl.Player): if player.is_bot and len(self.players) >= 8: return if player in self.players or len(self.players) >= 10: @@ -140,8 +141,8 @@ class Game: self.turn = i self.players[i].notify_self() - def attack_others(self, attacker: players.Player): - attacker.pending_action = players.PendingAction.WAIT + def attack_others(self, attacker: pl.Player): + attacker.pending_action = pl.PendingAction.WAIT attacker.notify_self() self.waiting_for = 0 self.readyCount = 0 @@ -151,11 +152,11 @@ class Game: self.waiting_for += 1 p.notify_self() if self.waiting_for == 0: - attacker.pending_action = players.PendingAction.PLAY + attacker.pending_action = pl.PendingAction.PLAY attacker.notify_self() - def indian_others(self, attacker: players.Player): - attacker.pending_action = players.PendingAction.WAIT + def indian_others(self, attacker: pl.Player): + attacker.pending_action = pl.PendingAction.WAIT attacker.notify_self() self.waiting_for = 0 self.readyCount = 0 @@ -165,63 +166,83 @@ class Game: self.waiting_for += 1 p.notify_self() if self.waiting_for == 0: - attacker.pending_action = players.PendingAction.PLAY + attacker.pending_action = pl.PendingAction.PLAY attacker.notify_self() - def attack(self, attacker: players.Player, target_username:str, double:bool=False): + def attack(self, attacker: pl.Player, target_username:str, double:bool=False): if self.get_player_named(target_username).get_banged(attacker=attacker, double=double): self.readyCount = 0 self.waiting_for = 1 - attacker.pending_action = players.PendingAction.WAIT + attacker.pending_action = pl.PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() - def duel(self, attacker: players.Player, target_username:str): + def duel(self, attacker: pl.Player, target_username:str): if self.get_player_named(target_username).get_dueled(attacker=attacker): self.readyCount = 0 self.waiting_for = 1 - attacker.pending_action = players.PendingAction.WAIT + attacker.pending_action = pl.PendingAction.WAIT attacker.notify_self() self.get_player_named(target_username).notify_self() def emporio(self): self.available_cards = [self.deck.draw() for i in range(len(self.players))] - self.players[self.turn].pending_action = players.PendingAction.CHOOSE + self.players[self.turn].pending_action = pl.PendingAction.CHOOSE self.players[self.turn].available_cards = self.available_cards self.players[self.turn].notify_self() def respond_emporio(self, player, i): player.hand.append(self.available_cards.pop(i)) player.available_cards = [] - player.pending_action = players.PendingAction.WAIT + player.pending_action = pl.PendingAction.WAIT player.notify_self() nextPlayer = self.players[(self.turn + (len(self.players)-len(self.available_cards))) % len(self.players)] if nextPlayer == self.players[self.turn]: - self.players[self.turn].pending_action = players.PendingAction.PLAY + self.players[self.turn].pending_action = pl.PendingAction.PLAY self.players[self.turn].notify_self() else: - nextPlayer.pending_action = players.PendingAction.CHOOSE + nextPlayer.pending_action = pl.PendingAction.CHOOSE nextPlayer.available_cards = self.available_cards nextPlayer.notify_self() def get_player_named(self, name:str): return self.players[self.players_map[name]] - def responders_did_respond_resume_turn(self): + def responders_did_respond_resume_turn(self, did_lose=False): + print('did_lose', did_lose) if self.player_bangs > 0 and self.check_event(ce.PerUnPugnoDiCarte): self.player_bangs -= 1 if self.player_bangs > 1: - self.players[self.turn].get_banged('') - self.players[self.turn].notify_self() + print('bang again') + if self.players[self.turn].get_banged(self.deck.event_cards[0]): + self.players[self.turn].notify_self() + else: + self.responders_did_respond_resume_turn() else: + print('ok play turn now') self.player_bangs = 0 self.players[self.turn].play_turn() - self.readyCount += 1 - if self.readyCount == self.waiting_for: - self.waiting_for = 0 - self.readyCount = 0 - self.players[self.turn].pending_action = players.PendingAction.PLAY - self.players[self.turn].notify_self() + elif self.is_russian_roulette_on and self.check_event(ce.RouletteRussa): + if did_lose: + print('stop roulette') + self.players[(self.turn+self.player_bangs) % len(self.players)].lives -= 1 + self.players[(self.turn+self.player_bangs) % len(self.players)].notify_self() + self.is_russian_roulette_on = False + self.players[self.turn].play_turn() + else: + self.player_bangs += 1 + print(f'next in line {self.players[(self.turn+self.player_bangs) % len(self.players)].name}') + if self.players[(self.turn+self.player_bangs) % len(self.players)].get_banged(self.deck.event_cards[0]): + self.players[(self.turn+self.player_bangs) % len(self.players)].notify_self() + else: + self.responders_did_respond_resume_turn(did_lose=True) + else: + self.readyCount += 1 + if self.readyCount == self.waiting_for: + self.waiting_for = 0 + self.readyCount = 0 + self.players[self.turn].pending_action = pl.PendingAction.PLAY + self.players[self.turn].notify_self() def next_player(self): return self.players[(self.turn + 1) % len(self.players)] @@ -237,10 +258,19 @@ class Game: self.players[-1].hand.append(self.deck.draw()) self.players_map = {c.name: i for i, c in enumerate(self.players)} self.players[-1].notify_self() + elif self.check_event(ce.RouletteRussa): + self.is_russian_roulette_on = True + if self.players[self.turn].get_banged(self.deck.event_cards[0]): + self.players[self.turn].notify_self() + else: + self.responders_did_respond_resume_turn(did_lose=True) + return if self.check_event(ce.PerUnPugnoDiCarte): self.player_bangs = len(self.players[self.turn].hand) - self.players[self.turn].get_banged('') - self.players[self.turn].notify_self() + if self.players[self.turn].get_banged(self.deck.event_cards[0]): + self.players[self.turn].notify_self() + else: + self.responders_did_respond_resume_turn() else: self.players[self.turn].play_turn() @@ -261,7 +291,7 @@ class Game: else: self.sio.emit('scrap', room=self.name, data=None) - def handle_disconnect(self, player: players.Player): + def handle_disconnect(self, player: pl.Player): print(f'player {player.name} left the game {self.name}') if player in self.players: if self.disconnect_bot and self.started: @@ -281,17 +311,17 @@ class Game: return True else: return False - def player_death(self, player: players.Player, disconnected=False): + def player_death(self, player: pl.Player, disconnected=False): if not player in self.players: return import bang.expansions.dodge_city.characters as chd print(player.attacker) - if player.attacker and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice): + if player.attacker and player.attacker in self.players and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice): for i in range(len(player.attacker.hand)): self.deck.scrap(player.attacker.hand.pop()) for i in range(len(player.attacker.equipment)): self.deck.scrap(player.attacker.equipment.pop()) player.attacker.notify_self() - elif player.attacker and (isinstance(player.role, roles.Outlaw) or self.initial_players == 3): + elif player.attacker and player.attacker in self.players and (isinstance(player.role, roles.Outlaw) or self.initial_players == 3): for i in range(3): player.attacker.hand.append(self.deck.draw()) player.attacker.notify_self() @@ -372,7 +402,7 @@ class Game: if len(self.deck.event_cards) == 0: return False return isinstance(self.deck.event_cards[0], ev) - def get_visible_players(self, player: players.Player): + def get_visible_players(self, player: pl.Player): i = self.players.index(player) sight = player.get_sight() mindist = 99 if not self.check_event(ce.Agguato) else 1 diff --git a/backend/bang/players.py b/backend/bang/players.py index 0e2d65a..84405e4 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -540,12 +540,12 @@ class Player: self.mancato_needed -= 1 self.notify_self() if self.mancato_needed <= 0: - self.game.responders_did_respond_resume_turn() + self.game.responders_did_respond_resume_turn(did_lose=False) return if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang)) or isinstance(self.character, chd.ElenaFuente)]) == 0\ and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0: self.take_damage_response() - self.game.responders_did_respond_resume_turn() + self.game.responders_did_respond_resume_turn(did_lose=True) else: self.pending_action = PendingAction.RESPOND self.expected_response = self.game.deck.mancato_cards @@ -575,7 +575,7 @@ class Player: print('has mancato') self.pending_action = PendingAction.RESPOND self.expected_response = self.game.deck.mancato_cards - if self.attacker and isinstance(self.attacker.character, chd.BelleStar) or self.game.check_event(ce.Lazo): + if self.attacker and self.attacker in self.game.players and isinstance(self.attacker.character, chd.BelleStar) or self.game.check_event(ce.Lazo): self.expected_response = self.game.deck.mancato_cards_not_green if isinstance(self.character, chd.ElenaFuente): self.expected_response = self.game.deck.all_cards_str @@ -601,7 +601,7 @@ class Player: if not self.game.is_competitive and 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() + self.game.responders_did_respond_resume_turn(did_lose=True) return False else: self.pending_action = PendingAction.RESPOND @@ -657,7 +657,7 @@ class Player: if isinstance(self.character, chd.MollyStark) and hand_index < len(self.hand)+1 and not self.is_my_turn: self.molly_discarded_cards += 1 else: - self.game.responders_did_respond_resume_turn() + self.game.responders_did_respond_resume_turn(did_lose=False) self.event_type = '' else: self.pending_action = PendingAction.RESPOND @@ -674,7 +674,7 @@ class Player: self.attacker.molly_discarded_cards = 0 self.attacker.notify_self() self.on_failed_response_cb() - self.game.responders_did_respond_resume_turn() + self.game.responders_did_respond_resume_turn(did_lose=True) if self.mancato_needed <= 0: self.attacker = None