def test_get_cards_string_player_multiple(self): player = Mock() player.is_dealer = False player.turn_over = False card = Card(10) # Heart Queen card2 = Card(6) # Heart eight card3 = Card(22) # Diamond Jack player.cards = [card, card2, card3] self.assertEqual("♥ Queen • ♥ 8 • ♦ Jack", get_cards_string(player, "en")) self.assertEqual("♥ Dame • ♥ 8 • ♦ Bube", get_cards_string(player, "de"))
def test_get_cards_string_dealer(self): player = Mock() player.is_dealer = True player.turn_over = False card = Card(12) # Heart Ace card2 = Card(6) # Heart eight player.cards = [card, card2] self.assertEqual("♥ Ace • [❔]", get_cards_string(player, "en")) self.assertEqual("♥ Ass • [❔]", get_cards_string(player, "de")) player.cards = [card2, card] self.assertEqual("♥ 8 • [❔]", get_cards_string(player, "en")) self.assertEqual("♥ 8 • [❔]", get_cards_string(player, "de"))
def test_get_cards_string_player(self): player = Mock() player.is_dealer = False player.turn_over = False card = Card(11) # Heart King card2 = Card(6) # Heart eight player.cards = [card, card2] self.assertEqual("♥ King • ♥ 8", get_cards_string(player, "en")) self.assertEqual("♥ König • ♥ 8", get_cards_string(player, "de")) # Changing the turn_over value shouldn't have any effect player.turn_over = True self.assertEqual("♥ King • ♥ 8", get_cards_string(player, "en")) self.assertEqual("♥ König • ♥ 8", get_cards_string(player, "de"))
def create_game(update, context): """Create a new game instance for the chat of the user""" user = update.effective_user chat = update.effective_chat lang_id = Database().get_lang_id(chat.id) translator = Translator(lang_id=lang_id) # Create either a singleplayer or multiplayer game if chat.type == "private": game_type = BlackJackGame.Type.SINGLEPLAYER elif chat.type == "group" or chat.type == "supergroup": game_type = BlackJackGame.Type.MULTIPLAYER_GROUP else: logger.error("Chat type '{}' not supported!".format(chat.type)) return game = BlackJackGame(gametype=game_type) game.add_player(user_id=user.id, first_name=user.first_name) GameStore().add_game(chat.id, game) # TODO currently the game starts instantly - this should change with multiplayer rooms if game.type == BlackJackGame.Type.SINGLEPLAYER: update.effective_message.reply_text(translator("game_starts_now").format("", get_cards_string(game.dealer, lang_id))) players_turn(update, context) else: text = translator("mp_request_join").format(game.get_player_list()) update.effective_message.reply_text(text=text, reply_markup=get_join_keyboard(game.id, lang_id))
def next_player(update, context): chat = update.effective_chat user = update.effective_user lang_id = Database().get_lang_id(chat.id) translator = Translator(lang_id=lang_id) game = GameStore().get_game(chat.id) try: if user.id != game.get_current_player().user_id: update.callback_query.answer(translator("mp_not_your_turn_callback").format(user.first_name)) return remove_inline_keyboard(update, context) game.next_player() except NoPlayersLeftException: # TODO merge messages update.effective_message.reply_text(translator("dealers_cards_are").format(game.dealer.cardvalue, get_cards_string(game.dealer, lang_id)), parse_mode=ParseMode.HTML) evaluation_string = generate_evaluation_string(game, lang_id) newgame_button = InlineKeyboardButton(text=translator("inline_keyboard_newgame"), callback_data="newgame") keyboard = InlineKeyboardMarkup(inline_keyboard=[[newgame_button]]) update.effective_message.reply_text(evaluation_string, reply_markup=keyboard) game.stop(-1) return players_turn(update, context)
def players_turn(update, context): """Execute a player's turn""" chat = update.effective_chat game = GameStore().get_game(chat.id) player = game.get_current_player() user_mention = html_mention(user_id=player.user_id, first_name=player.first_name) lang_id = Database().get_lang_id(chat.id) translator = Translator(lang_id=lang_id) logger.info("Player's turn: {}".format(player)) player_cards = get_cards_string(player, lang_id) # Check if player already has 21 or a BlackJack before their move. If so, automatically jump to the next player. # We need reply_text here, because we must send a new message (this is the first message for the player)! if player.has_blackjack(): text = (translator("your_cards_are") + "\n\n" + translator("got_blackjack")).format(user_mention, player.cardvalue, player_cards) update.effective_message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None) next_player(update, context) elif player.cardvalue == 21: text = (translator("your_cards_are") + "\n\n" + translator("got_21")).format(user_mention, player.cardvalue, player_cards) update.effective_message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None) next_player(update, context) else: text = translator("your_cards_are").format(user_mention, player.cardvalue, player_cards) update.effective_message.reply_text(text=text, parse_mode=ParseMode.HTML, reply_markup=get_game_keyboard(game.id, lang_id))
def hit_callback(update, context): """ CallbackQueryHandler callback for the 'hit' inline button. Draws a card for you. """ user = update.effective_user chat = update.effective_chat lang_id = Database().get_lang_id(chat.id) translator = Translator(lang_id=lang_id) game = GameStore().get_game(chat.id) if not is_button_affiliated(update, context, game, lang_id): return player = game.get_current_player() user_mention = html_mention(user_id=player.user_id, first_name=player.first_name) try: if user.id != player.user_id: update.callback_query.answer(translator("mp_not_your_turn_callback").format(user.first_name)) return game.draw_card() player_cards = get_cards_string(player, lang_id) text = translator("your_cards_are").format(user_mention, player.cardvalue, player_cards) update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=get_game_keyboard(game.id, lang_id)) except errors.PlayerBustedException: player_cards = get_cards_string(player, lang_id) text = (translator("your_cards_are") + "\n\n" + translator("you_busted")).format(user_mention, player.cardvalue, player_cards) update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None) next_player(update, context) except errors.PlayerGot21Exception: player_cards = get_cards_string(player, lang_id) if player.has_blackjack(): text = (translator("your_cards_are") + "\n\n" + translator("got_blackjack")).format(user_mention, player.cardvalue, player_cards) update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None) next_player(update, context) elif player.cardvalue == 21: text = (translator("your_cards_are") + "\n\n" + translator("got_21")).format(user_mention, player.cardvalue, player_cards) update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None) next_player(update, context)
def start_callback(update, context): """Starts a game that has been created already""" user = update.effective_user chat = update.effective_chat lang_id = Database().get_lang_id(chat.id) translator = Translator(lang_id=lang_id) try: game = GameStore().get_game(update.effective_chat.id) if not is_button_affiliated(update, context, game, lang_id): return except NoActiveGameException: update.callback_query.answer(translator("mp_no_created_game_callback")) remove_inline_keyboard(update, context) return try: game.start(user.id) update.callback_query.answer(translator("mp_starting_game_callback")) except errors.GameAlreadyRunningException: update.callback_query.answer( translator("mp_game_already_begun_callback")) return except errors.NotEnoughPlayersException: update.callback_query.answer( translator("mp_not_enough_players_callback")) return except errors.InsufficientPermissionsException: update.callback_query.answer( translator("mp_only_creator_start_callback").format( user.first_name)) return if game.type != BlackJackGame.Type.SINGLEPLAYER: players_are = translator("mp_players_are") for player in game.players: players_are += "👤{}\n".format(player.first_name) players_are += "\n" else: players_are = "" update.effective_message.edit_text( translator("game_starts_now").format( players_are, get_cards_string(game.dealer, lang_id))) players_turn(update, context)