diff --git a/backend/__init__.py b/backend/__init__.py index 2837a7b..27b167c 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -121,10 +121,16 @@ def chat_message(sid, msg): ses: Player = sio.get_session(sid) sio.emit('chat_message', room=ses.game.name, data=f'[{ses.name}]: {msg}') if '/addbot' in msg and not ses.game.started: - ses.game.add_player(Player(f'AI_{random.randint(0,100)}', 'bot', sio, bot=True)) + if len(msg.split()) > 1: + for _ in range(int(msg.split()[1])): + ses.game.add_player(Player(f'AI_{random.randint(0,100)}', 'bot', sio, bot=True)) + else: + ses.game.add_player(Player(f'AI_{random.randint(0,100)}', 'bot', sio, bot=True)) 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() + elif '/suicide' in msg and ses.game.started: + ses.game.player_death(player=ses) @sio.event def start_game(sid): diff --git a/backend/bang/game.py b/backend/bang/game.py index 30b682c..32ea89f 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -246,7 +246,8 @@ class Game: if self.started: self.sio.emit('chat_message', room=self.name, data=f'_died_role|{player.name}|{player.role.name}') for p in self.players: - p.notify_self() + if not p.is_bot: + p.notify_self() self.players_map = {c.name: i for i, c in enumerate(self.players)} if self.started: print('Check win status') diff --git a/backend/bang/players.py b/backend/bang/players.py index 8b901b5..7436c1d 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -114,7 +114,6 @@ class Player: self.sio.emit('characters', room=self.sid, data=json.dumps( available, default=lambda o: o.__dict__)) else: - eventlet.sleep(uniform(1, 2)) self.set_character(available[randrange(0, len(available))].name) def notify_card(self, player, card): @@ -166,66 +165,93 @@ class Player: self.game.notify_all() else: self.game.notify_all() - if self.pending_action != PendingAction.WAIT: - eventlet.sleep(uniform(0.6, 1.5)) - else: - return - if self.pending_action == PendingAction.PICK: - self.pick() - elif self.pending_action == PendingAction.DRAW: - self.draw('') - elif self.pending_action == PendingAction.PLAY: - has_played = False - if len([c for c in self.hand if c.is_equipment or c.usable_next_turn]) > 0: - for i in range(len(self.hand)): - if self.hand[i].is_equipment or self.hand[i].usable_next_turn: - self.play_card(i) - has_played = True - break - if len([c for c in self.hand if c.need_target and not (self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment]))]) > 0: - for i in range(len(self.hand)): - if self.hand[i].need_target and not (self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment])): - if self.hand[i].need_with and len(self.hand) < 2: - continue - _range = self.get_sight() if self.hand[i].name == 'Bang!' or self.hand[i].name == "Pepperbox" else self.hand[i].range - others = [p for p in self.game.get_visible_players(self) if _range <= p['dist']] + self.bot_logic() + self.game.notify_all() + + def bot_logic(self): + if self.pending_action != PendingAction.WAIT: + eventlet.sleep(uniform(0.6, 1.5)) + else: + return + if self.pending_action == PendingAction.PICK: + self.pick() + elif self.pending_action == PendingAction.DRAW: + self.draw('') + elif self.pending_action == PendingAction.PLAY: + has_played = False + if len([c for c in self.hand if c.is_equipment or c.usable_next_turn]) > 0: + for i in range(len(self.hand)): + if self.hand[i].is_equipment or self.hand[i].usable_next_turn: + self.play_card(i) + has_played = True + break + elif any([isinstance(c, cs.WellsFargo) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or isinstance(c, cs.Birra) for c in self.hand]): + for i in range(len(self.hand)): + c = self.hand[i] + if isinstance(c, cs.WellsFargo) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives): + self.play_card(i) + has_played = True + break + elif len([c for c in self.hand if c.need_target and not (self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment]))]) > 0: + for i in range(len(self.hand)): + if self.hand[i].need_target and not (self.has_played_bang and not any([isinstance(c, cs.Volcanic) for c in self.equipment])): + if self.hand[i].need_with and len(self.hand) < 2: + continue + _range = self.get_sight() if self.hand[i].name == 'Bang!' or self.hand[i].name == "Pepperbox" else self.hand[i].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'])] + if len(others) == 0: + continue + target = others[randrange(0, len(others))] + if target['is_sheriff'] and isinstance(self.role, r.Renegade): + target = others[randrange(0, len(others))] + if not self.hand[i].need_with: + self.play_card(i, against=target['name']) + else: + self.play_card(i, against=target['name'], _with=sample([j for j in range(len(self.hand)) if j != i], 1)[0]) + has_played = True + break + elif any([not isinstance(c, cs.Mancato) and c.usable_next_turn and c.can_be_used_now for c in self.equipment]): + print('hmm', [not isinstance(c, cs.Mancato) and c.usable_next_turn and c.can_be_used_now for c in self.equipment]) + for i in range(len(self.equipment)): + c = self.equipment[i] + if not isinstance(c, cs.Mancato) and c.usable_next_turn and c.can_be_used_now: + if not c.need_target: + self.play_card(len(self.hand)+i) + else: + _range = self.get_sight() if c.name == "Pepperbox" else self.hand[i].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'])] if len(others) == 0: continue target = others[randrange(0, len(others))] - len_before = len(self.hand) - if not self.hand[i].need_with: - self.play_card(i, against=target['name']) - else: - self.play_card(i, against=target['name'], _with=sample([j for j in range(len(self.hand)) if j != i], 1)[0]) - has_played = True - break - if any([isinstance(c, cs.WellsFargo) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or isinstance(c, cs.Birra) for c in self.hand]): - for i in range(len(self.hand)): - c = self.hand[i] - if isinstance(c, cs.WellsFargo) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives): - self.play_card(i) - has_played = True - break - if not has_played and len(self.hand) > self.lives: - self.scrap(0) - else: - self.end_turn() - elif self.pending_action == PendingAction.RESPOND: - did_respond = False - for i in range(len(self.hand)): - if self.hand[i].name in self.expected_response: - self.respond(i) - did_respond = True + if target['is_sheriff'] and isinstance(self.role, r.Renegade): + target = others[randrange(0, len(others))] + self.play_card(len(self.hand)+i, against=target['name']) + has_played = True break - if not did_respond: - self.respond(-1) - elif self.pending_action == PendingAction.CHOOSE: - if not self.target_p: - self.choose(randrange(0, len(self.available_cards))) - else: - target = self.game.get_player_named(self.target_p) - self.choose(randrange(0, len(target.hand)+len(target.equipment))) - self.game.notify_all() + if not has_played and len(self.hand) > self.lives: + self.scrap(0) + else: + self.end_turn() + elif self.pending_action == PendingAction.RESPOND: + did_respond = False + for i in range(len(self.hand)): + if self.hand[i].name in self.expected_response: + self.respond(i) + did_respond = True + break + for i in range(len(self.equipment)): + if self.equipment[i].name in self.expected_response: + self.respond(len(self.hand)+i) + did_respond = True + break + if not did_respond: + self.respond(-1) + elif self.pending_action == PendingAction.CHOOSE: + if not self.target_p: + self.choose(randrange(0, len(self.available_cards))) + else: + target = self.game.get_player_named(self.target_p) + self.choose(randrange(0, len(target.hand)+len(target.equipment))) def play_turn(self): if self.lives == 0: