From 0d381ddf4ded4b1c66b7276c95cdf8df7623001b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Mon, 29 Feb 2016 12:16:12 +0100 Subject: [PATCH] rules might be wonky but works --- bot.py | 117 +++++++++++++++++++++++++++++++++--------------- card.py | 17 ++----- game.py | 18 +++++--- game_manager.py | 11 ++++- player.py | 36 ++++++++++++--- 5 files changed, 138 insertions(+), 61 deletions(-) diff --git a/bot.py b/bot.py index ce598ff..75a8dcc 100644 --- a/bot.py +++ b/bot.py @@ -1,14 +1,14 @@ import logging -from telegram import Updater, InlineQueryResultPhoto, InlineQueryResultArticle +from telegram import Updater, InlineQueryResultPhoto, InlineQueryResultArticle, ParseMode from game_manager import GameManager import card as c from credentials import TOKEN logging.basicConfig( - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.DEBUG) + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.DEBUG) logger = logging.getLogger(__name__) gm = GameManager() @@ -34,7 +34,19 @@ def new_game(bot, update): def start(bot, update, args): if args: - gm.join_game(args[0], update.message.from_user) + game_id = args[0] + gm.join_game(game_id, update.message.from_user) + game = gm.gameid_game[game_id] + groupchat = gm.chatid_gameid[game_id] + bot.sendMessage(update.message.chat_id, text="Joined game!") + bot.sendMessage(groupchat, text=update.message.from_user.first_name + + " joined the game!") + + if game.current_player is game.current_player.next: + game.play_card(game.last_card) + bot.sendPhoto(groupchat, + photo=game.last_card.get_image_link(), + caption="First Card") else: bot.sendMessage(update.message.chat_id, text="Please invite me to a group and " @@ -45,70 +57,103 @@ def inline(bot, update): if update.inline_query: user_id = update.inline_query.from_user.id player = gm.userid_player[user_id] - + game = gm.userid_game[user_id] results = list() - playable = player.playable_cards() + playable = list() - if playable: - for card in playable: + if game.choosing_color: + for color in c.COLORS: results.append( - InlineQueryResultPhoto(str(card), - card.get_image_link(), - card.get_thumb_link(), - title="Play card", - description="") + InlineQueryResultArticle( + id=color, + title="Choose Color", + message_text=color, + description=color.upper() + ) ) + else: + playable = player.playable_cards() + if playable is False: results.append( - InlineQueryResultPhoto( - "hand", - c.IMAGE_PATTERN % 'thinking', - c.THUMB_PATTERN % 'thinking', - title="Other cards:", - description=', '.join([repr(card) for card in - list_subtract(player.cards, playable)]), + InlineQueryResultArticle( + "not_your_turn", + title="Not your turn", + description="Tap to see the current player", + message_text="Current player: " + + game.current_player.user.first_name ) ) - else: + elif playable: + for card in playable: + results.append( + InlineQueryResultArticle(str(card), + title="Play card", + message_text= + ('\xad' + 'Played card ' + repr(card)) + % card.get_image_link(), + thumb_url=card.get_thumb_link(), + description=repr(card), + parse_mode=ParseMode.HTML) + ) + elif not game.choosing_color: results.append( InlineQueryResultArticle( "draw", title="No suitable cards...", description="Draw!", - message_text='Drawing %d card(s)' % player.game.draw_counter + message_text='Drawing %d card(s)' + % (player.game.draw_counter or 1) ) ) - results.append( - InlineQueryResultArticle( - "hand", - title="Other cards:", - description=', '.join([repr(card) for card in - list_subtract(player.cards, playable)]), - message_text='Just checking cards' - ) + results.append( + InlineQueryResultArticle( + "hand", + title="Other cards:", + description=', '.join([repr(card) for card in + list_subtract(player.cards, playable)]), + message_text='Just checking cards' ) + ) [logger.info(str(result)) for result in results] bot.answerInlineQuery(update.inline_query.id, results, cache_time=0) else: - user_id = update.chosen_inline_result.from_user.id - game = gm.userid_game[user_id] - player = gm.userid_player[user_id] + user = update.chosen_inline_result.from_user + game = gm.userid_game[user.id] + player = gm.userid_player[user.id] result_id = update.chosen_inline_result.result_id + chat_id = gm.chatid_gameid[game] + logger.info("Selected result: " + result_id) - if result_id is 'hand': + if result_id == 'hand': pass - elif result_id is 'draw': - for n in range(game.draw_counter): + elif result_id == 'draw': + for n in range(game.draw_counter or 1): player.cards.append(game.deck.draw()) + game.draw_counter = 0 + elif result_id in c.COLORS: + game.choose_color(result_id) else: card = c.from_str(result_id) game.play_card(card) player.cards.remove(card) + if game.choosing_color: + bot.sendMessage(chat_id, text="Please choose a color") + elif len(player.cards) == 1: + bot.sendMessage(chat_id, text="Last Card!") + elif len(player.cards) == 0: + gm.leave_game(user) + bot.sendMessage(chat_id, text="Player won!") + + bot.sendMessage(chat_id, + text="Next player: " + + game.current_player.user.first_name) def error(bot, update, error): diff --git a/card.py b/card.py index 1b37ce1..c1b293e 100644 --- a/card.py +++ b/card.py @@ -51,18 +51,7 @@ class Card(object): return '%s_%s' % (self.color, self.value) def __repr__(self): - if self.special: - return self.special - ''' - if self.special is CHOOSE: - return "Colorchooser" - elif self.special is DRAW_FOUR: - return "Draw four" - ''' - else: - return self.color + " - " + self.value - - return str(self) + return ' '.join([s.capitalize() for s in str(self).split('_')]) def __eq__(self, other): return str(self) == str(other) @@ -75,8 +64,8 @@ class Card(object): def from_str(string): - if '_' in string: + if string not in SPECIALS: color, value = string.split('_') return Card(color, value) else: - return Card(None, None, string) \ No newline at end of file + return Card(None, None, string) diff --git a/game.py b/game.py index d0cf616..dd81843 100644 --- a/game.py +++ b/game.py @@ -1,3 +1,5 @@ +import logging + from deck import Deck from card import Card import card as c @@ -11,12 +13,13 @@ class Game(object): """ current_player = None reversed = False - draw_counter = 1 + draw_counter = 0 choosing_color = False def __init__(self): self.deck = Deck() self.last_card = self.deck.draw() + self.logger = logging.getLogger(__name__) def reverse(self): self.reversed = not self.reversed @@ -33,18 +36,23 @@ class Game(object): """ self.deck.dismiss(self.last_card) self.last_card = card - if card.value is c.SKIP: + + self.logger.info("Playing card " + repr(card)) + if card.value == c.SKIP: self.current_player = self.current_player.next.next - elif card.special is c.DRAW_FOUR: + elif card.special == c.DRAW_FOUR: self.draw_counter += 4 - elif card.value is c.DRAW_TWO: + self.logger.debug("Draw counter increased by 4") + elif card.value == c.DRAW_TWO: self.draw_counter += 2 - elif card.value is c.REVERSE: + self.logger.debug("Draw counter increased by 2") + elif card.value == c.REVERSE: self.reverse() if card.special not in (c.CHOOSE, c.DRAW_FOUR): self.current_player = self.current_player.next else: + self.logger.debug("Choosing Color...") self.choosing_color = True def choose_color(self, color): diff --git a/game_manager.py b/game_manager.py index 4dbead7..3a85586 100644 --- a/game_manager.py +++ b/game_manager.py @@ -13,7 +13,6 @@ class GameManager(object): self.gameid_game = dict() self.userid_game = dict() self.chatid_gameid = dict() - self.userid_user = dict() self.userid_player = dict() self.logger = logging.getLogger(__name__) @@ -24,6 +23,8 @@ class GameManager(object): self.logger.info("Creating new game with id " + game_id) self.gameid_game[game_id] = game self.chatid_gameid[chat_id] = game_id + self.chatid_gameid[game_id] = chat_id + self.chatid_gameid[game] = chat_id return LINK_PATTERN % (bot_name, game_id) @@ -33,3 +34,11 @@ class GameManager(object): player = Player(game, user) self.userid_player[user.id] = player self.userid_game[user.id] = game + + def leave_game(self, user): + player = self.userid_player[user.id] + + player.leave() + del self.userid_player[user.id] + del self.userid_game[user.id] + diff --git a/player.py b/player.py index 9939621..7519eb7 100644 --- a/player.py +++ b/player.py @@ -1,5 +1,7 @@ import logging +import card as c + class Player(object): @@ -28,6 +30,12 @@ class Player(object): for i in range(6): self.cards.append(self.game.deck.draw()) + def leave(self): + self.next.prev = self.prev + self.prev.next = self.next + self.next = None + self.prev = None + def __repr__(self): return repr(self.user) @@ -69,10 +77,28 @@ class Player(object): for card in self.cards: self.logger.debug("Checking card " + str(card)) - if (card.color is last.color or card.value is last.value or - card.special) and \ - not last.special and card not in playable: - self.logger.debug("Matching!") - playable.append(card) + if (card.color != last.color and card.value != last.value and + not card.special): + self.logger.debug("Card's color or value doesn't match") + continue + + if last.value == c.DRAW_TWO and not \ + (card.value == c.DRAW_TWO or + card.special == c.DRAW_FOUR or + not self.game.draw_counter): + self.logger.debug("Player has to draw and can't counter") + continue + + if last.special == c.DRAW_FOUR and self.game.draw_counter: + self.logger.debug("Player has to draw and can't counter") + continue + + if not last.color or card in playable: + self.logger.debug("Last card has no color or the card was " + "already added to the list") + continue + + self.logger.debug("Matching!") + playable.append(card) return playable