async def join_game_callback_handler(q: types.CallbackQuery, callback_data: dict): user_id = q.from_user.id if not database.controllers.Users.get_user(user_id): await bot.answer_callback_query(q.id, 'Для начала напишите боту комманду /start') return chat_id = int(callback_data['chat_id']) chat = database.controllers.Chats.get_chat(chat_id) max_players = chat.max_players game = Game(chat_id) queue = game.get_queue() players = await queue.get_players() players_count = len(players) msg_id = q.message.message_id if user_id in await queue.get_players(): await bot.answer_callback_query(q.id, 'Вы уже присоединились к игре') return await queue.add_player(user_id) if players_count + 1 == max_players: game.bot = bot await game.start() await bot.edit_message_text(f'Игра началась! Игроков: {max_players}', chat_id, msg_id) else: await bot.edit_message_text( f'<strong>{q.from_user.get_mention()}</strong> присоединился к игре\nИгроков присоединилось {players_count + 1}/{max_players}', chat_id, msg_id, reply_markup=InlineKeyboards.join_game_keyboard(chat_id))
async def start(self): queue = self.get_queue() deck = Deck(self.chat_id) trump_card = deck.get_trump_card() players = await queue.get_players() random.seed(int(str(self.chat_id) + str(int(time.time())))) rand_player = random.choice(players) struggle_player = await self._next_player(rand_player) for user_id in players: hand = deck.pop_cards(6) await self.__hand.add_cards(user_id, hand) text = f'Козырь - {str(trump_card)}' if user_id == rand_player: text = '<strong>Ваш ход</strong>\n\n' + text elif user_id == struggle_player: text = '<strong>Вы отбиваетесь</strong>\n\n' + text msg = await self.bot.send_message( user_id, text, reply_markup=InlineKeyboards.cards_keyboard( self.chat_id, hand)) await self.__players.set_player_message(user_id, msg.message_id) await self.__state.set_trump_suit(trump_card) await self.__state.set_trump_card(trump_card) await self.__state.set_turn(rand_player, 'move') await self.__state.set_struggle(struggle_player) await self.__state.set_struggled(1) await self.__state.set_next_toss(rand_player) await self.__deck.set_cards(deck.cards)
async def start_game_command_handler(msg: types.Message): chat_id = msg.chat.id if await Game.init_queue(chat_id, msg.from_user.id): await msg.reply( 'Выберите количество участников', reply_markup=InlineKeyboards.init_q(chat_id)) else: await msg.reply('Набор уже идет')
async def edit_messages(self, trigger_player: int, trigger_text: str, trigger_keyboard_function, additional_condition: bool = True) -> None: players = await self.__players.get_players() trump_card = await self.__state.get_trump_card() for player in players: text = f'Козырь - {str(trump_card)}\nКарт в колоде - {len(await self.__deck.get_cards())}' keyboard = InlineKeyboards.cards_keyboard( self.chat_id, await self.__hand.get_cards(player)) message_id = await self.__players.get_player_message(player) if player == trigger_player and additional_condition: keyboard = trigger_keyboard_function(keyboard, self.chat_id) text = trigger_text + text try: await self.bot.edit_message_text(text, player, message_id, reply_markup=keyboard) except exceptions.MessageNotModified: pass
async def players_start_callback_handler(q: types.CallbackQuery, callback_data: dict): chat_id = int(callback_data['chat_id']) game = Game(chat_id) players = await game.get_queue().get_players() if q.from_user.id != players[0]: await bot.answer_callback_query(q.id, 'Начинать игру может только создатель партии') return await bot.edit_message_text(f'{q.from_user.get_mention()} создает игру!\nИгроков 1/{database.Chats.get_chat(chat_id).max_players}', chat_id, q.message.message_id, reply_markup=InlineKeyboards.join_game_keyboard(chat_id))
async def players_count_callback_handler(q: types.CallbackQuery, callback_data: dict): chat_id = int(callback_data['chat_id']) game = Game(chat_id) players = await game.get_queue().get_players() if q.from_user.id != players[0]: await bot.answer_callback_query(q.id, 'Изменять количество участников может только создатель партии') return count = int(callback_data['count']) count = count + 1 if count < 4 else 2 database.Chats.set_max_players(chat_id, count) await bot.edit_message_text('Выберите количество участников', chat_id, q.message.message_id, reply_markup=InlineKeyboards.init_q(chat_id, count))
async def end_turn(self) -> None: struggle = await self.__state.get_struggle() struggled = await self.__state.get_struggled() table = await self.__table.get_cards() deck = await self.__deck.get_cards() players = [ *[ player for player in await self.__players.get_players() if player != struggle ], struggle ] players_len = len(players) if struggled == 0: await self.__hand.add_cards(struggle, table) next_struggle = await self._next_player(struggle, 1) next_move = await self._next_player(struggle) else: next_struggle = await self._next_player(struggle) next_move = struggle for player in players: hand = await self.__hand.get_cards(player) hand_len = len(hand) if len(deck) > 0: if hand_len < 6: add_len = 6 - hand_len if add_len < len(deck): await self.__hand.add_cards( player, [deck.pop(0) for _ in range(add_len)]) else: await self.bot.send_message( self.chat_id, 'Карты в колоде закончились') await self.__hand.add_cards(player, deck) deck = [] else: max_players = database.Chats.get_chat(self.chat_id).max_players if hand_len == 0: message_id = await self.__players.get_player_message(player ) private_text = '' chat_text = f'{database.Users.get_user(player).username} ' if players_len == max_players: private_text = 'Вы выиграли' chat_text += 'выигрывает' else: private_text = 'Вы не выиграли, но и не проиграли' chat_text += 'выбывает' await self.bot.send_message(self.chat_id, chat_text) await self.bot.edit_message_text(private_text, player, message_id) players_len -= 1 if players_len == 1: await self.__players.delete_player(player) await self.end() return elif player == struggle: next_struggle = await self._next_player(struggle, 1) next_move = await self._next_player(struggle) await self.__players.delete_player(player) else: await self.__players.delete_player(player) if struggled == 0: await self.__hand.add_cards(struggle, table) next_struggle = await self._next_player( struggle, 1) next_move = await self._next_player(struggle) else: next_struggle = await self._next_player(struggle) next_move = struggle await self.__deck.set_cards(deck) players = await self.__players.get_players() for player in players: text = f'Козырь - {str(await self.__state.get_trump_card())}\nКарт в колоде - {len(deck)}' message_id = await self.__players.get_player_message(player) if player == next_move: text = '<strong>Ваш ход</strong>\n\n' + text elif player == next_struggle: text = '<strong>Вы отбиваетесь</strong>\n\n' + text try: await self.bot.edit_message_text( text, player, message_id, reply_markup=InlineKeyboards.cards_keyboard( self.chat_id, await self.__hand.get_cards(player))) except exceptions.MessageNotModified: pass await self.__table.clear() await self.__state.clear_tossed() await self.__state.set_struggle(next_struggle) await self.__state.set_struggled(1) await self.__state.set_next_toss(next_move) await self.__state.set_turn(next_move, 'move')
async def turn(self, turn_type: str, card_id: str, q: types.CallbackQuery) -> None: user_id, turn = await self.get_turn() user_id = int(user_id) card_id = int(card_id) username = database.controllers.Users.get_user(user_id).username trump_suit = await self.__state.get_trump_suit() trump_card = await self.__state.get_trump_card() card = Card(id=card_id) if card_id else None if turn_type == 'card': if turn == b'move': struggle = await self.__state.get_struggle() await self.__table.add_card(Card(id=card_id)) await self.__hand.delete_card(user_id, card) await self.edit_messages( struggle, f'Отбейте {str(card)}\n\n', InlineKeyboards.pass_struggle_keyboard) struggle_username = database.controllers.Users.get_user( struggle).username await self.bot.send_message( self.chat_id, f'Игрок @{username} сходил {str(Card(id=card_id))}.\nИгрок {struggle_username} отбивается' ) await self.__state.set_turn(struggle, 'struggle') elif turn == b'struggle': table = await self.__table.get_cards() struggle_card = table[0] if card.beat(struggle_card, trump_suit): table.append(card) await self.__table.add_card(card) await self.__hand.delete_card(user_id, card) hand = await self.__hand.get_cards(user_id) if len(hand) == 0: await self.bot.send_message( self.chat_id, f'Игрок {username} отбивается {str(card)}. Ход окончен.' ) await self.end_turn() return toss = await self.__state.get_next_toss() await self.edit_messages( toss, 'Подкинуть? Карты на столе\n' + ' '.join([str(i) for i in table]) + '\n\n', InlineKeyboards.pass_toss_keyboard) toss_username = database.controllers.Users.get_user( toss).username await self.bot.send_message( self.chat_id, f'Игрок @{username} отбил {str(card)}.\nИгрок @{toss_username} подкидывает' ) await self.__state.set_turn(toss, 'toss') else: await self.bot.answer_callback_query( q.id, 'Невозможно отбить этой картой') elif turn == b'toss': table = await self.__table.get_cards() if Card(id=card_id).name_id in [i.name_id for i in table]: await self.__table.add_card(card) await self.__hand.delete_card(user_id, card) struggle = await self.__state.get_struggle() struggled = await self.__state.get_struggled() await self.edit_messages( struggle, f'Отбейте{str(Card(id=card_id))}\n\nКарты на столе\n' + ' '.join([str(i) for i in table]) + '\n\n', InlineKeyboards.pass_struggle_keyboard, struggled == 1) text = f'Игрок @{username} подкинул {str(Card(id=card_id))}' if struggled == 1: struggle_username = database.controllers.Users.get_user( struggle).username text += f'\n@{struggle_username} отбивается' await self.__state.clear_tossed() await self.__state.set_turn(struggle, 'struggle') else: next_toss = await self.__state.get_next_toss() message_id = await self.__players.get_player_message( next_toss) try: table.append(card) cards = await self.__hand.get_cards(next_toss) keyboard = InlineKeyboards.cards_keyboard( self.chat_id, cards) await self.bot.edit_message_text( 'Подкинуть? Карты на столе\n' + ' '.join([str(i) for i in table]) + '\n\n', next_toss, message_id, reply_markup=InlineKeyboards. pass_toss_keyboard(keyboard, self.chat_id)) except exceptions.MessageNotModified: pass await self.__state.set_turn(next_toss, 'toss') await self.bot.send_message(self.chat_id, text) else: await self.bot.answer_callback_query( q.id, 'Невозможно подкинуть эту карту') elif turn_type == 'pass_toss': username = database.controllers.Users.get_user(user_id).username await self.bot.send_message( self.chat_id, f'Игрок @{username} решил не подкидывать') cur_toss = await self.__state.get_next_toss() set_next_toss = await self._set_next_toss() if cur_toss == await self.__state.get_next_toss(): await self.end_turn() return await self.__state.add_tossed(user_id) if set_next_toss: toss = await self.__state.get_next_toss() table = await self.__table.get_cards() await self.edit_messages( toss, f'Подкинуть? Карты на столе\n' + ' '.join([str(i) for i in table]) + '\n\n', InlineKeyboards.pass_toss_keyboard) await self.__state.set_turn(toss, 'toss') else: await self.end_turn() elif turn_type == 'pass_struggle': await self.__state.set_struggled(0) toss = await self.__state.get_next_toss() table = await self.__table.get_cards() await self.edit_messages( toss, f'Подкинуть? Карты на столе\n' + ' '.join([str(i) for i in table]) + '\n\n', InlineKeyboards.pass_toss_keyboard) await self.bot.send_message( self.chat_id, f'Игрок @{username} решил взять карты') await self.__state.set_turn(toss, 'toss')