From 9bdc8fdf8c9db049202a9732e4743cf46d80b9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Mon, 6 May 2019 19:37:29 +0300 Subject: [PATCH] Remove cards from removed deck, add !origins --- botcmd.py | 8 +++-- gameloop.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 4 deletions(-) diff --git a/botcmd.py b/botcmd.py index 0931837..90ab05f 100644 --- a/botcmd.py +++ b/botcmd.py @@ -256,6 +256,10 @@ def parse_command(message, nick, irc): if args(0) is not None: send_event((events.cards, nick)) + elif c == '!origins': + if args(0) is not None: + send_event((events.origins, nick)) + elif c == '!help': arg = args([0, 1, 2]) if arg is not None: @@ -264,10 +268,10 @@ def parse_command(message, nick, irc): arg[0] = arg[0][1:] if len(arg) == 0: - send('!status !start !ready !unready !kill !join !leave !players !deck !limit !card !cards') + send('!status !start !ready !unready !kill !join !leave !players !deck !limit !card !cards !origins') elif len(arg) == 1: - if arg[0] in ('status', 'ready', 'unready', 'kill', 'join', 'leave', 'players', 'cards'): + if arg[0] in ('status', 'ready', 'unready', 'kill', 'join', 'leave', 'players', 'cards', 'origins'): send('Usage: !%s' % (arg[0])) elif arg[0] == 'start': send('Usage: !start [preset]') diff --git a/gameloop.py b/gameloop.py index 90dd7c0..335ecfb 100644 --- a/gameloop.py +++ b/gameloop.py @@ -8,7 +8,7 @@ import cardcast_api # TODO: keep track of where cards come from purge from hand when deck remove class events(enum.Enum): - quit, nick_change, status, start, ready, unready, kill, join, leave, players, deck_add, deck_add_random, deck_remove, deck_list, limit, card, cards = range(17) + quit, nick_change, status, start, ready, unready, kill, join, leave, players, deck_add, deck_add_random, deck_remove, deck_list, limit, card, cards, origins = range(18) class limit_types(enum.Enum): points, rounds = range(2) @@ -134,7 +134,16 @@ def game(send, notice, voice, devoice, get_event): return code def remove_deck(code): - nonlocal decks + nonlocal players, decks, round_call_card + + # Purge all the cards from the deck from the game + for player in players.values(): + for index, card in enumerate(player.hand): + if card is not None and card.deck.code == code: + player.hand[index] = None + + if round_call_card is not None and round_call_card.deck.code == code: + round_call_card = None del decks[code] @@ -181,6 +190,17 @@ def game(send, notice, voice, devoice, get_event): send('That was weird, got %s randomly but it was already added' % code) errwrapper('Failure adding deck: %s (%%s)' % code, add_deck, code) + def get_hand_origins(player): + hand_origins = [] + + for card in player.hand: + if card is None: + hand_origins.append('') + else: + hand_origins.append(card.deck.code) + + return ', '.join('%i: %s' % (index, i) for index, i in enumerate(hand_origins)) + def common_handler(event, args): nonlocal players, decks, limit @@ -245,6 +265,14 @@ def game(send, notice, voice, devoice, get_event): limit_type = {limit_types.rounds: 'rounds', limit_types.points: 'points'}[limit.type] send('Limit set to %i %s' % (limit.number, limit_type)) + elif event == events.origins: + nick, = args + + if nick in players: + origins = get_hand_origins(players[nick]) + if origins != '': + notice(nick, origins) + elif event == events.card or event == events.cards: # Ignore selecting and listing cards if it's not available pass @@ -613,6 +641,38 @@ def game(send, notice, voice, devoice, get_event): else: notice(nick, 'You can\'t choose now') + elif event == events.origins: + nick, = args + + if nick not in players: + notice(nick, 'call: %s' % round_call_card.deck.code) + + else: + notice(nick, 'call: %s, %s' % (round_call_card.deck.code, get_hand_origins(players[nick]))) + + elif event == events.deck_remove: + common_handler(event, args) + + # Did we lose our call card? + if round_call_card is None: + # Yes, restart round + return setup_round + + # Did it remove a card from someone voting this round? + for player in choosers: + if None in player.hand: + # Yes, restart round + return setup_round + + for player in card_choices: + # We are checking all cards here, not + # just the ones chosen. This is because + # a player may change their selection, + # in which case we might hit a None + if None in player.hand: + # Yes, restart round + return setup_round + else: r = common_handler(event, args) if r is not None: return r @@ -676,6 +736,35 @@ def game(send, notice, voice, devoice, get_event): else: notice(nick, '%i not in range' % choice) + elif event == events.origins: + nick, = args + + if nick not in players: + notice(nick, 'call: %s' % round_call_card.deck.code) + + else: + answers_origins = [] + for index, player in enumerate(choosers): + answer_origins = [player.hand[i].deck.code for i in card_choices[player]] + answers_origins.append('%i: %s' % (index, ', '.join(answer_origins))) + + notice(nick, 'call: %s; %s' % (round_call_card.deck.code, '; '.join(answers_origins))) + + elif event == events.deck_remove: + common_handler(event, args) + + # Did we lose our call card? + if round_call_card is None: + # Yes, restart round + return setup_round + + # Did it affect any response cards on this round? + for player in card_choices: + for index in card_choices[player]: + if player.hand[index] is None: + # Yes, restart round + return setup_round + else: r = common_handler(event, args) if r is not None: return r @@ -801,6 +890,9 @@ if __name__ == '__main__': elif t == 'cards': nick = input('nick> ') return (events.cards, nick) + elif t == 'origins': + nick = input('nick> ') + return (events.origins, nick) else: print('?')