Represent played cards as Card objectes instead of as indices into hand

This commit is contained in:
Juhani Krekelä 2019-05-21 18:23:38 +03:00
parent dff760e0f4
commit 0913abee3b
1 changed files with 31 additions and 41 deletions

View File

@ -85,7 +85,7 @@ class Rando:
self.hand = [i for i in self.hand if i is not None] self.hand = [i for i in self.hand if i is not None]
def play(self, num_blanks): def play(self, num_blanks):
return list(range(num_blanks)) return self.hand[:num_blanks]
class Error: pass class Error: pass
@ -476,6 +476,7 @@ def game(send, notice, voice, devoice, get_event):
send('%s started a game, !join to join!' % nick) send('%s started a game, !join to join!' % nick)
decks['foo'] = Deck(code = 'foo', name = 'foo', author = 'foo', call_count = 0, response_count = 0, calls = [['foo $', 'bar']], responses = ['bees?'] * 20)#debg
start_game(rest) start_game(rest)
return game_setup return game_setup
@ -812,9 +813,10 @@ def game(send, notice, voice, devoice, get_event):
def combine_cards(call, responses, dereference_responses = True): def combine_cards(call, responses, dereference_responses = True):
# This function is really messy, in part due to the format used # This function is really messy, in part due to the format used
# #
# `call` is a list of strings, and here I'll refer to each of # `call` is a Card object, with `call.text` being a list of
# them as "part". This division into parts indicates the # strings, and here I'll refer to each of those strings as
# locations of the blanks. For example: # "part". This division into parts indicates the locations of
# the blanks. For example:
# #
# Foo bar? _. # Foo bar? _.
# #
@ -822,7 +824,7 @@ def game(send, notice, voice, devoice, get_event):
# #
# ['Foo bar? ', '.'] # ['Foo bar? ', '.']
# #
# So far good, take a part from `call`, then one response # So far good, take a part from `call.text`, then one response
# (assuming we still have one remaining) and repeat. # (assuming we still have one remaining) and repeat.
# #
# However, CardsAgainstIRC extended the simple system of blanks # However, CardsAgainstIRC extended the simple system of blanks
@ -838,11 +840,11 @@ def game(send, notice, voice, devoice, get_event):
# corresponding response when you add the call part. It'd give # corresponding response when you add the call part. It'd give
# this algorith: # this algorith:
# #
# 1. Go over call[index] and satisfy backrefrences # 1. Go over call.text[index] and satisfy backrefrences
# 1. Copy text verbatim until we hit a $<num> # 1. Copy text verbatim until we hit a $<num>
# 2. Add responses[num] # 2. Add responses[num].text
# 3. Repeat # 3. Repeat
# 2. Add response[index] # 2. Add response[index].text
# 3. Repeat # 3. Repeat
# #
# This was how I first implemented it. However, dealing with # This was how I first implemented it. However, dealing with
@ -890,8 +892,8 @@ def game(send, notice, voice, devoice, get_event):
part_index = 0 part_index = 0
index = 0 index = 0
segment_start_index = 0 segment_start_index = 0
while part_index < len(call): while part_index < len(call.text):
call_part = call[part_index] call_part = call.text[part_index]
if index >= len(call_part): if index >= len(call_part):
# We've reached a blank or the end of the card # We've reached a blank or the end of the card
@ -907,7 +909,7 @@ def game(send, notice, voice, devoice, get_event):
# Add response # Add response
r.append(to_formatting_state(formatting_state, no_formatting)) r.append(to_formatting_state(formatting_state, no_formatting))
r.append('[') r.append('[')
r.append(sanitize(responses[part_index], no_formatting)) r.append(sanitize(responses[part_index].text, no_formatting))
r.append(']') r.append(']')
r.append(to_formatting_state(no_formatting, formatting_state)) r.append(to_formatting_state(no_formatting, formatting_state))
@ -944,7 +946,7 @@ def game(send, notice, voice, devoice, get_event):
# Add the response this backreference refers to # Add the response this backreference refers to
r.append(to_formatting_state(formatting_state, no_formatting)) r.append(to_formatting_state(formatting_state, no_formatting))
r.append('[') r.append('[')
r.append(sanitize(responses[backreference_index], no_formatting)) r.append(sanitize(responses[backreference_index].text, no_formatting))
r.append(']') r.append(']')
r.append(to_formatting_state(no_formatting, formatting_state)) r.append(to_formatting_state(no_formatting, formatting_state))
@ -960,20 +962,16 @@ def game(send, notice, voice, devoice, get_event):
else: else:
# A backreference, but not a # A backreference, but not a
# valid one. Copy verbatim # valid one. Copy verbatim
r.append('$') pass
r.append(call_part[index])
else: else:
# Not a backreference # Not a backreference
r.append('$') pass
r.append(to_formatting_state(formatting_state, no_formatting)) r.append(to_formatting_state(formatting_state, no_formatting))
return ''.join(r) return ''.join(r)
def combine_played(call, player_bot, selected_cards):
return combine_cards(call.text, [player_bot.hand[i].text for i in selected_cards])
def top_of_round(): def top_of_round():
nonlocal players, bots, round_number, round_call_card, czar, card_choices nonlocal players, bots, round_number, round_call_card, czar, card_choices
@ -985,7 +983,7 @@ def game(send, notice, voice, devoice, get_event):
num_blanks = len(round_call_card.text) - 1 num_blanks = len(round_call_card.text) - 1
send('Round %i. %s is czar. %s choose your cards' % (round_number, czar.nick, ', '.join(i.nick for i in choosers))) send('Round %i. %s is czar. %s choose your cards' % (round_number, czar.nick, ', '.join(i.nick for i in choosers)))
send('[%s]' % combine_cards(round_call_card.text, ['_'] * num_blanks, dereference_responses = False)) send('[%s]' % combine_cards(round_call_card, [None] * num_blanks, dereference_responses = False))
# Have bots choose first # Have bots choose first
for bot in bots.values(): for bot in bots.values():
@ -1037,7 +1035,7 @@ def game(send, notice, voice, devoice, get_event):
selected_cards = [] selected_cards = []
for choice in choices: for choice in choices:
if 0 <= choice < len(player.hand): if 0 <= choice < len(player.hand):
if choice not in selected_cards: if player.hand[choice] not in selected_cards:
selected_cards.append(choice) selected_cards.append(choice)
else: else:
notice(nick, 'Can\'t play the same card twice') notice(nick, 'Can\'t play the same card twice')
@ -1050,10 +1048,12 @@ def game(send, notice, voice, devoice, get_event):
# Failed to use some choice # Failed to use some choice
continue continue
selected_cards = [player.hand[i] for i in selected_cards]
card_choices[player] = selected_cards card_choices[player] = selected_cards
if player in choosers: if player in choosers:
choosers.remove(player) choosers.remove(player)
notice(nick, combine_played(round_call_card, player, selected_cards)) notice(nick, combine_cards(round_call_card, selected_cards))
elif event == events.cards: elif event == events.cards:
nick, = args nick, = args
@ -1138,7 +1138,7 @@ def game(send, notice, voice, devoice, get_event):
# Display the cards # Display the cards
choosers = random.sample(card_choices.keys(), k = len(card_choices)) choosers = random.sample(card_choices.keys(), k = len(card_choices))
for index, player_bot in enumerate(choosers): for index, player_bot in enumerate(choosers):
send('%i: %s' % (index, combine_played(round_call_card, player_bot, card_choices[player_bot]))) send('%i: %s' % (index, combine_cards(round_call_card, card_choices[player_bot])))
while True: while True:
if len(players) < 2: if len(players) < 2:
@ -1183,7 +1183,7 @@ def game(send, notice, voice, devoice, get_event):
else: else:
czar = None czar = None
send('The winner is %s with: %s' % (player_bot.nick, combine_played(round_call_card, player_bot, card_choices[player_bot]))) send('The winner is %s with: %s' % (player_bot.nick, combine_cards(round_call_card, card_choices[player_bot])))
break break
@ -1216,7 +1216,7 @@ def game(send, notice, voice, devoice, get_event):
else: else:
answers_origins = [] answers_origins = []
for index, player_bot in enumerate(choosers): for index, player_bot in enumerate(choosers):
answer_origins = [player_bot.hand[i].deck.code for i in card_choices[player_bot]] answer_origins = [i.deck.code for i in card_choices[player_bot]]
answers_origins.append('%i: %s' % (index, ', '.join(answer_origins))) answers_origins.append('%i: %s' % (index, ', '.join(answer_origins)))
notice(nick, 'call: %s; %s' % (round_call_card.deck.code, '; '.join(answers_origins))) notice(nick, 'call: %s; %s' % (round_call_card.deck.code, '; '.join(answers_origins)))
@ -1233,13 +1233,7 @@ def game(send, notice, voice, devoice, get_event):
for index in range(len(player.hand)): for index in range(len(player.hand)):
player.hand[index] = None player.hand[index] = None
if player in card_choices: notice(nick, 'New hand will be dealt next round')
send('Lost a card played this round, restarting round')
return setup_round
else:
notice(nick, 'New hand will be dealt next round')
elif event == events.deck_remove: elif event == events.deck_remove:
common_handler(event, args) common_handler(event, args)
@ -1250,14 +1244,6 @@ def game(send, notice, voice, devoice, get_event):
send('Lost the black card, restarting round') send('Lost the black card, restarting round')
return setup_round return setup_round
# Did it affect any response cards on this round?
for player_bot in card_choices:
for index in card_choices[player_bot]:
if player_bot.hand[index] is None:
# Yes, restart round
send('Lost a card played this round, restarting round')
return setup_round
else: else:
r = common_handler(event, args) r = common_handler(event, args)
if r is not None: return r if r is not None: return r
@ -1286,8 +1272,12 @@ def game(send, notice, voice, devoice, get_event):
# Remove the cards that were played this round from hands # Remove the cards that were played this round from hands
for player_bot in card_choices: for player_bot in card_choices:
for index in card_choices[player_bot]: played = card_choices[player_bot]
player_bot.hand[index] = None for card in card_choices[player_bot]:
for index, hand_card in enumerate(player_bot.hand):
if hand_card is card:
player_bot.hand[index] = None
break
# Increase the number of the round and clear the call card # Increase the number of the round and clear the call card
# These are not done in setup_round() since we might want to # These are not done in setup_round() since we might want to