diff --git a/backend/__init__.py b/backend/__init__.py index e489c94..1afa6ac 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -196,176 +196,180 @@ def chat_message(sid, msg): ses: Player = sio.get_session(sid) if len(msg) > 0: if msg[0] == '/': - if '/addbot' in msg and not ses.game.started: - if len(msg.split()) > 1: - # for _ in range(int(msg.split()[1])): - # ses.game.add_player(Player(f'AI_{random.randint(0,1000)}', 'bot', sio, bot=True)) - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'Only 1 bot at the time'}) - else: - bot = Player(f'AI_{random.randint(0,10)}', 'bot', sio, bot=True) - while any([p for p in ses.game.players if p.name == bot.name]): - bot = Player(f'AI_{random.randint(0,10)}', 'bot', sio, bot=True) - ses.game.add_player(bot) - bot.bot_spin() - return - elif '/removebot' in msg and not ses.game.started: - if any([p.is_bot for p in ses.game.players]): - [p for p in ses.game.players if p.is_bot][-1].disconnect() - return - elif '/togglecomp' in msg and ses.game: - ses.game.toggle_competitive() - return - if '/debug' in msg: - cmd = msg.split() - if len(cmd) == 2 and 'DEPLOY_KEY' in os.environ and cmd[1] == os.environ['DEPLOY_KEY']: # solo chi ha la deploy key può attivare la modalità debug - ses.game.debug = not ses.game.debug - ses.game.notify_room() - elif ses == ses.game.players[0]: # solo l'owner può attivare la modalità debug - ses.game.debug = not ses.game.debug - ses.game.notify_room() - if ses.game.debug: - sio.emit('chat_message', room=sid, data={'color': f'red','text':f'debug mode is now active, only the owner of the room can disable it with /debug'}) - return - if not ses.game.debug: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'debug mode is not active, only the owner of the room can enable it with /debug'}) - elif '/set_chars' in msg and not ses.game.started: - cmd = msg.split() - if len(cmd) == 2 and int(cmd[1]) > 0: - ses.game.characters_to_distribute = int(cmd[1]) - elif '/suicide' in msg and ses.game.started and ses.lives > 0: - ses.lives = 0 - ses.notify_self() - elif '/nextevent' in msg and ses.game.started: - ses.game.deck.flip_event() - elif '/notify' in msg and ses.game.started: - cmd = msg.split() - if len(cmd) >= 3: - if cmd[1] in ses.game.players_map: - ses.game.get_player_named(cmd[1]).notify_card(ses, { - 'name': ' '.join(cmd[2:]), - 'icon': '🚨', - 'suit': 4, - 'number': ' '.join(cmd[2:]) - }) - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) - elif '/show_cards' in msg and ses.game.started: - cmd = msg.split() - if len(cmd) == 2: - if cmd[1] in ses.game.players_map: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and is looking at {cmd[1]} hand'}) - for c in ses.game.get_player_named(cmd[1]).hand: - ses.notify_card(ses, c) - eventlet.sleep(0.3) - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) - elif '/ddc' in msg and ses.game.started: # debug destroy cards usage: [/ddc *] [/ddc username] - cmd = msg.split() - if len(cmd) == 2: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode destroyed {cmd[1]} cards'}) - if cmd[1] == "*": - for p in ses.game.players_map: - ses.game.get_player_named(p).hand = [] - ses.game.get_player_named(p).equipment = [] - ses.game.get_player_named(p).notify_self() - elif cmd[1] in ses.game.players_map: - ses.game.get_player_named(cmd[1]).hand = [] - ses.game.get_player_named(cmd[1]).equipment = [] - ses.game.get_player_named(cmd[1]).notify_self() - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) - elif '/dsh' in msg and ses.game.started: #debug set health usage [/dsh * hp] [/dsh username hp] - cmd = msg.split() - if len(cmd) == 3: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and is changing {cmd[1]} health'}) - if cmd[1] == "*": - for p in ses.game.players_map: - ses.game.get_player_named(p).lives = int(cmd[2]) - ses.game.get_player_named(p).notify_self() - elif cmd[1] in ses.game.players_map: - ses.game.get_player_named(cmd[1]).lives = int(cmd[2]) - ses.game.get_player_named(cmd[1]).notify_self() - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) - elif '/togglebot' in msg and ses.game: - ses.game.toggle_disconnect_bot() - elif '/cancelgame' in msg and ses.game.started: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} stopped the current game'}) - ses.game.reset() - elif '/startgame' in msg and not ses.game.started: - ses.game.start_game() - elif '/setbotspeed' in msg: - ses.game.bot_speed = float(msg.split()[1]) - elif '/addex' in msg and not ses.game.started: - cmd = msg.split() - if len(cmd) == 2: - cmd[1] = cmd[1].replace('foc', 'fistful_of_cards') - if cmd[1] not in ses.game.available_expansions: - ses.game.available_expansions.append(cmd[1]) - ses.game.notify_room() - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) - elif '/setcharacter' in msg: - import bang.characters as characters - cmd = msg.split() - if len(cmd) >= 2: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and changed character'}) - chs = characters.all_characters(ses.game.expansions) - ses.character = [c for c in chs if c.name == ' '.join(cmd[1:])][0] - ses.real_character = ses.character - ses.notify_self() - elif '/setevent' in msg and ses.game and ses.game.deck: #add event before the position /setevent (position) 0 (name) Peyote - cmd = msg.split() - if len(cmd) >= 3: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and changed event'}) - import bang.expansions.fistful_of_cards.card_events as ce - import bang.expansions.high_noon.card_events as ceh - chs = [] - chs.extend(ce.get_all_events()) - chs.append(ce.get_endgame_card()) - chs.extend(ceh.get_all_events()) - chs.append(ceh.get_endgame_card()) - ses.game.deck.event_cards.insert(int(cmd[1]), [c for c in chs if c!=None and c.name == ' '.join(cmd[2:])][0]) - ses.game.notify_event_card() - elif '/removecard' in msg: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and removed a card'}) - cmd = msg.split() - if len(cmd) == 2: - if int(cmd[1]) < len(ses.hand): - ses.hand.pop(int(cmd[1])) + commands = msg.split(';') + for msg in commands: + if '/addbot' in msg and not ses.game.started: + if len(msg.split()) > 1: + # for _ in range(int(msg.split()[1])): + # ses.game.add_player(Player(f'AI_{random.randint(0,1000)}', 'bot', sio, bot=True)) + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'Only 1 bot at the time'}) else: - ses.equipment.pop(int(cmd[1])-len(ses.hand)) + bot = Player(f'AI_{random.randint(0,10)}', 'bot', sio, bot=True) + while any([p for p in ses.game.players if p.name == bot.name]): + bot = Player(f'AI_{random.randint(0,10)}', 'bot', sio, bot=True) + ses.game.add_player(bot) + bot.bot_spin() + return + elif '/removebot' in msg and not ses.game.started: + if any([p.is_bot for p in ses.game.players]): + [p for p in ses.game.players if p.is_bot][-1].disconnect() + return + elif '/togglecomp' in msg and ses.game: + ses.game.toggle_competitive() + return + if '/debug' in msg: + cmd = msg.split() + if len(cmd) == 2 and 'DEPLOY_KEY' in os.environ and cmd[1] == os.environ['DEPLOY_KEY']: # solo chi ha la deploy key può attivare la modalità debug + ses.game.debug = not ses.game.debug + ses.game.notify_room() + elif ses == ses.game.players[0]: # solo l'owner può attivare la modalità debug + ses.game.debug = not ses.game.debug + ses.game.notify_room() + if ses.game.debug: + sio.emit('chat_message', room=sid, data={'color': f'red','text':f'debug mode is now active, only the owner of the room can disable it with /debug'}) + return + if not ses.game.debug: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'debug mode is not active, only the owner of the room can enable it with /debug'}) + elif '/set_chars' in msg and not ses.game.started: + cmd = msg.split() + if len(cmd) == 2 and int(cmd[1]) > 0: + ses.game.characters_to_distribute = int(cmd[1]) + elif '/suicide' in msg and ses.game.started and ses.lives > 0: + ses.lives = 0 ses.notify_self() - elif '/getcard' in msg: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and got a card'}) - import bang.cards as cs - cmd = msg.split() - if len(cmd) >= 2: - cards = cs.get_starting_deck(ses.game.expansions) - card_names = ' '.join(cmd[1:]).split(',') - for cn in card_names: - ses.hand.append([c for c in cards if c.name == cn][0]) + elif '/nextevent' in msg and ses.game.started: + ses.game.deck.flip_event() + elif '/notify' in msg and ses.game.started: + cmd = msg.split() + if len(cmd) >= 3: + if cmd[1] in ses.game.players_map: + ses.game.get_player_named(cmd[1]).notify_card(ses, { + 'name': ' '.join(cmd[2:]), + 'icon': '🚨', + 'suit': 4, + 'number': ' '.join(cmd[2:]) + }) + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/show_cards' in msg and ses.game.started: + cmd = msg.split() + if len(cmd) == 2: + if cmd[1] in ses.game.players_map: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and is looking at {cmd[1]} hand'}) + for c in ses.game.get_player_named(cmd[1]).hand: + ses.notify_card(ses, c) + eventlet.sleep(0.3) + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/ddc' in msg and ses.game.started: # debug destroy cards usage: [/ddc *] [/ddc username] + cmd = msg.split() + if len(cmd) == 2: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode destroyed {cmd[1]} cards'}) + if cmd[1] == "*": + for p in ses.game.players_map: + ses.game.get_player_named(p).hand = [] + ses.game.get_player_named(p).equipment = [] + ses.game.get_player_named(p).notify_self() + elif cmd[1] in ses.game.players_map: + ses.game.get_player_named(cmd[1]).hand = [] + ses.game.get_player_named(cmd[1]).equipment = [] + ses.game.get_player_named(cmd[1]).notify_self() + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/dsh' in msg and ses.game.started: #debug set health usage [/dsh * hp] [/dsh username hp] + cmd = msg.split() + if len(cmd) == 3: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and is changing {cmd[1]} health'}) + if cmd[1] == "*": + for p in ses.game.players_map: + ses.game.get_player_named(p).lives = int(cmd[2]) + ses.game.get_player_named(p).notify_self() + elif cmd[1] in ses.game.players_map: + ses.game.get_player_named(cmd[1]).lives = int(cmd[2]) + ses.game.get_player_named(cmd[1]).notify_self() + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/togglebot' in msg and ses.game: + ses.game.toggle_disconnect_bot() + elif '/cancelgame' in msg and ses.game.started: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} stopped the current game'}) + ses.game.reset() + elif '/startgame' in msg and not ses.game.started: + ses.game.start_game() + elif '/setbotspeed' in msg: + ses.game.bot_speed = float(msg.split()[1]) + elif '/addex' in msg and not ses.game.started: + cmd = msg.split() + if len(cmd) == 2: + cmd[1] = cmd[1].replace('foc', 'fistful_of_cards') + if cmd[1] not in ses.game.available_expansions: + ses.game.available_expansions.append(cmd[1]) + ses.game.notify_room() + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/setcharacter' in msg: + import bang.characters as characters + cmd = msg.split() + if len(cmd) >= 2: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and changed character'}) + chs = characters.all_characters(ses.game.expansions) + ses.character = [c for c in chs if c.name == ' '.join(cmd[1:])][0] + ses.real_character = ses.character ses.notify_self() - elif '/getnuggets' in msg: - sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and got nuggets'}) - import bang.cards as cs - cmd = msg.split() - if len(cmd) == 2: - ses.gold_nuggets += int(cmd[1]) - ses.notify_self() - elif '/gameinfo' in msg: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.game.__dict__}'}) - elif '/meinfo' in msg: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.__dict__}'}) - elif '/mebot' in msg: - ses.is_bot = not ses.is_bot - ses.bot_spin() - elif '/arcadekick' in msg and ses.game.started: - if len([p for p in ses.game.players if p.pending_action != PendingAction.WAIT]) == 0: - sio.emit('chat_message', room=ses.game.name, data={'color': f'','text':f'KICKING THE ARCADE CABINET'}) - ses.game.next_turn() - else: - sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} COMMAND NOT FOUND'}) + elif '/setevent' in msg and ses.game and ses.game.deck: #add event before the position /setevent (position) 0 (name) Peyote + cmd = msg.split() + if len(cmd) >= 3: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and changed event'}) + import bang.expansions.fistful_of_cards.card_events as ce + import bang.expansions.high_noon.card_events as ceh + chs = [] + chs.extend(ce.get_all_events()) + chs.append(ce.get_endgame_card()) + chs.extend(ceh.get_all_events()) + chs.append(ceh.get_endgame_card()) + ses.game.deck.event_cards.insert(int(cmd[1]), [c for c in chs if c!=None and c.name == ' '.join(cmd[2:])][0]) + ses.game.notify_event_card() + elif '/removecard' in msg: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and removed a card'}) + cmd = msg.split() + if len(cmd) == 2: + if int(cmd[1]) < len(ses.hand): + ses.hand.pop(int(cmd[1])) + else: + ses.equipment.pop(int(cmd[1])-len(ses.hand)) + ses.notify_self() + elif '/getcard' in msg: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and got a card'}) + import bang.cards as cs + cmd = msg.split() + if len(cmd) >= 2: + cards = cs.get_starting_deck(ses.game.expansions) + card_names = ' '.join(cmd[1:]).split(',') + for cn in card_names: + ses.hand.append([c for c in cards if c.name == cn][0]) + ses.notify_self() + elif '/getnuggets' in msg: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and got nuggets'}) + import bang.cards as cs + cmd = msg.split() + if len(cmd) == 2: + ses.gold_nuggets += int(cmd[1]) + ses.notify_self() + elif '/gameinfo' in msg: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.game.__dict__}'}) + elif '/meinfo' in msg: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.__dict__}'}) + elif '/mebot' in msg: + ses.is_bot = not ses.is_bot + if (ses.is_bot): + ses.was_player = True + ses.bot_spin() + elif '/arcadekick' in msg and ses.game.started: + if len([p for p in ses.game.players if p.pending_action != PendingAction.WAIT]) == 0: + sio.emit('chat_message', room=ses.game.name, data={'color': f'','text':f'KICKING THE ARCADE CABINET'}) + ses.game.next_turn() + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} COMMAND NOT FOUND'}) else: color = sid.encode('utf-8').hex()[-3:] sio.emit('chat_message', room=ses.game.name, data={'color': f'#{color}','text':f'[{ses.name}]: {msg}'}) diff --git a/backend/bang/game.py b/backend/bang/game.py index a93c195..d8f958b 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -53,9 +53,12 @@ class Game: self.players.extend(self.spectators) self.spectators = [] for bot in [p for p in self.players if p.is_bot]: - bot.game = None + if bot.was_player: + bot.is_bot = False + else: + bot.game = None self.players = [p for p in self.players if not p.is_bot] - print(f'{self.name}: ' + self.players) + print(f'{self.name}: players: {self.players}') self.started = False self.is_handling_death = False self.waiting_for = 0 @@ -645,7 +648,7 @@ class Game: if self.deck == None or len(self.deck.event_cards) == 0: return False return isinstance(self.deck.event_cards[0], ev) - def get_visible_players(self, player: pl.Player): + def get_visible_players(self, player: pl.Player): # returns a dictionary because we need to add the distance pls = self.get_alive_players() if len(pls) == 0 or player not in pls: return [] i = pls.index(player) diff --git a/backend/bang/players.py b/backend/bang/players.py index ae83626..146d584 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -79,6 +79,7 @@ class Player: self.bang_used = 0 self.gold_nuggets = 0 self.gold_rush_equipment = [] + self.was_player = False def join_game(self, game): self.game = game @@ -236,13 +237,18 @@ class Player: self.draw('') elif self.pending_action == PendingAction.PLAY: non_blocked_cards = [card for card in self.hand if (not self.game.check_event(ceh.Manette) or card.suit == self.committed_suit_manette)] - equippables = [c for c in non_blocked_cards if (c.is_equipment or c.usable_next_turn) and not isinstance(c, cs.Prigione) and not any([type(c) == type(x) for x in self.equipment])] - misc = [c for c in non_blocked_cards if (isinstance(c, cs.WellsFargo) or isinstance(c, cs.Indiani) or isinstance(c, cs.Gatling) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives and not self.game.check_event(ceh.IlReverendo)) or (c.need_with and len(self.hand) > 1 and not c.need_target and not (isinstance(c, csd.Whisky) and self.lives == self.max_lives))) - and not (not c.can_be_used_now and self.game.check_event(ce.IlGiudice))] - need_target = [c for c in non_blocked_cards if c.need_target and c.can_be_used_now and not (c.need_with and len(self.hand) < 2) and not ( - (self.game.check_event(ceh.Sermone) or self.has_played_bang and not (any([isinstance(c, cs.Volcanic) for c in self.equipment]) and type(c) == type(cs.Bang) - ) and not self.game.check_event(ce.Lazo))) and not ( isinstance(c, cs.Prigione) and self.game.check_event(ce.IlGiudice))] + equippables = [c for c in non_blocked_cards if (c.is_equipment or c.usable_next_turn) and not isinstance(c, cs.Prigione) and not any([type(c) == type(x) and not (c.is_weapon and c.must_be_used) for x in self.equipment])] + misc = [c for c in non_blocked_cards if not c.need_target and (isinstance(c, cs.WellsFargo) or isinstance(c, cs.Indiani) or isinstance(c, cs.Gatling) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or ((isinstance(c, cs.Birra) and self.lives < self.max_lives or c.must_be_used) and not self.game.check_event(ceh.IlReverendo)) or (c.need_with and len(self.hand) > 1 and not (isinstance(c, csd.Whisky) and self.lives == self.max_lives))) + and not (not c.can_be_used_now and self.game.check_event(ce.IlGiudice)) and not c.is_equipment] + need_target = [c for c in non_blocked_cards if c.need_target and c.can_be_used_now and not (c.need_with and len(self.hand) < 2) and not (type(c) == type(cs.Bang) and (self.game.check_event(ceh.Sermone) or (self.has_played_bang and (not any([isinstance(c, cs.Volcanic) for c in self.equipment]) or self.game.check_event(ce.Lazo))))) and not (isinstance(c, cs.Prigione) and self.game.check_event(ce.IlGiudice)) or isinstance(c, cs.Duello) or isinstance(c, cs.CatBalou) or isinstance(c, csd.Pugno)] green_cards = [c for c in self.equipment if not self.game.check_event(ce.Lazo) and not isinstance(c, cs.Mancato) and c.usable_next_turn and c.can_be_used_now] + if self.game.debug: + print(f'hand: {self.hand}') + print(f'non_blocked: {non_blocked_cards}') + print(f'equippables: {equippables}') + print(f'misc: {misc}') + print(f'need_target: {need_target}') + print(f'green_cards: {green_cards}') if self.gold_nuggets > 0 and any([c.number <= self.gold_nuggets for c in self.game.deck.shop_cards]): for i in range(len(self.game.deck.shop_cards)): if self.game.deck.shop_cards[i].number <= self.gold_nuggets: @@ -254,14 +260,14 @@ class Player: return elif len(misc) > 0: for c in misc: - if c.need_with and self.play_card(self.hand.index(c), _with=sample([j for j in range(len(self.hand)) if j != self.hand.index(c)], 1)[0]): + if c.need_with and len(self.hand) > 1 and self.play_card(self.hand.index(c), _with=sample([j for j in range(len(self.hand)) if j != self.hand.index(c)], 1)[0]): return elif self.play_card(self.hand.index(c)): return elif len(need_target) > 0: for c in need_target: _range = self.get_sight() if c.name == 'Bang!' or c.name == "Pepperbox" else c.range - others = [p for p in self.game.get_visible_players(self) if _range >= p['dist'] and not (isinstance(self.role, r.Vice) and p['is_sheriff']) and p['lives'] > 0 and not ((isinstance(c, cs.CatBalou) or isinstance(c, cs.Panico)) and p['cards'] == 0) and not (p['is_sheriff'] and isinstance(c, cs.Prigione))] + others = [p for p in self.game.get_visible_players(self) if _range >= p['dist'] and not (isinstance(self.role, r.Vice) and p['is_sheriff'] and not c.must_be_used) and p['lives'] > 0 and not ((isinstance(c, cs.CatBalou) or isinstance(c, cs.Panico)) and p['cards'] == 0) and not (p['is_sheriff'] and isinstance(c, cs.Prigione))] if len(others) == 0 or c not in self.hand: continue target = others[randrange(0, len(others))] @@ -270,7 +276,7 @@ class Player: if not c.need_with: if self.play_card(self.hand.index(c), against=target['name']): return - else: + elif len(self.hand) > 1: if self.play_card(self.hand.index(c), against=target['name'], _with=sample([j for j in range(len(self.hand)) if j != self.hand.index(c)], 1)[0]): return elif len(green_cards) > 0: @@ -1170,6 +1176,29 @@ class Player: self.game.deck.fill_gold_rush_shop() self.notify_self() + def check_can_end_turn(self): + must_be_used_cards = [c for c in self.hand if c.must_be_used] + if self.game.check_event(ce.LeggeDelWest) and len(must_be_used_cards) > 0: + card = must_be_used_cards[0] + print(f'Legge del west card: {card.name}') + print(self.has_played_bang and not (any([isinstance(c, cs.Volcanic) for c in self.equipment]) and type(card) == type(cs.Bang))) + if card.suit == cs.Suit.DIAMONDS and card.need_target and len([p for p in self.game.get_alive_players() if p != self and (not p.character.check(self.game, chd.ApacheKid) and not any([isinstance(c, grc.Calumet) for c in p.gold_rush_equipment]))]) == 0: + return True + elif (isinstance(card, cs.Bang) or (isinstance(card, cs.Mancato) and self.character.check(self.game, chars.CalamityJanet))) and self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment]) or len([p for p in self.game.get_visible_players(self) if self.get_sight() >= p['dist']]) == 0: + return True + elif isinstance(card, cs.Mancato) or (card.need_with and len(self.hand) < 2): + return True + elif isinstance(card, cs.Panico) and len([p for p in self.game.get_visible_players(self) if 1 >= p['dist']]) == 0 and len(self.equipment) == 0: + return True + elif isinstance(card, csd.Pugno) and len([p for p in self.game.get_visible_players(self) if 1 >= p['dist']]) == 0: + return True + elif isinstance(card, cs.Prigione) and len([p for p in self.game.get_visible_players(self) if not p['is_sheriff']]) == 0: + return True + elif not card.is_weapon and len([c for c in self.equipment if c.name == card.name]) > 0: + return True + return False + return True + def end_turn(self, forced=False): print(f"{self.name} wants to end his turn") if not self.is_my_turn and not forced: @@ -1178,8 +1207,9 @@ class Player: if maxcards == self.lives and len([c for c in self.gold_rush_equipment if isinstance(c, grc.Cinturone)]) > 0: maxcards = 8 if len(self.hand) > maxcards and not forced: - print( - f"{self.name}: I have to many cards in my hand and I can't end the turn") + print(f"{self.name}: I have to many cards in my hand and I can't end the turn") + elif not self.check_can_end_turn(): + print(f"{self.name}: I must play the legge del west card") elif self.pending_action == PendingAction.PLAY or forced: if not forced and self.game.check_event(ce.Vendetta) and self.can_play_vendetta: picked: cs.Card = self.game.deck.pick_and_scrap()