Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 80 additions & 75 deletions modules/unobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,58 +64,58 @@
SCOREFILE = os.path.join(CONFIG_DIR, "unoscores.yml")

STRINGS = {
'ALREADY_STARTED': '\x0300,01Game already started by %s! Type ".join" to join!',
'GAME_STARTED': '\x0300,01IRC-UNO started by %s - Type ".join" to join!',
'GAME_STOPPED': '\x0300,01Game stopped.',
'CANT_STOP': '\x0300,01%s is the game owner, you can\'t stop it! To force stop the game, please wait %s seconds.',
'DEALING_IN': '\x0300,01Dealing %s into the game as player #%s!',
'JOINED': '\x0300,01Dealing %s into the game as player #%s!',
'ALREADY_JOINED': '\x0300,01Player, %s, is already in the game as player #%s!',
'ENOUGH': '\x0300,01There are enough players, type .deal to start!',
'NOT_STARTED': '\x0300,01Game not started, type .uno to start!',
'NOT_ENOUGH': '\x0300,01Not enough players to deal yet.',
'NEEDS_TO_DEAL': '\x0300,01%s needs to deal.',
'ALREADY_DEALT': '\x0300,01Already dealt.',
'ON_TURN': '\x0300,01It\'s the turn of %s',
'DONT_HAVE': '\x0300,01You don\'t have that card, %s',
'DOESNT_PLAY': '\x0300,01That card does not play, %s',
'UNO': '\x0300,01UNO! %s has ONE card left!',
'WIN': '\x0300,01We have a winner! %s!!!! This game took %s',
'DRAWN_ALREADY': '\x0300,01You\'ve already drawn, either .pass or .play!',
'DRAWS': '\x0300,01%s draws a card',
'DRAWN_CARD': '\x0300,01Drawn card: %s',
'DRAW_FIRST': '\x0300,01%s, you need to draw first!',
'PASSED': '\x0300,01%s passed!',
'NO_SCORES': '\x0300,01No scores yet',
'TOP_CARD': '\x0300,01It\'s the turn of %s | Top Card: %s',
'YOUR_CARDS': '\x0300,01Your cards: %s',
'NEXT_START': '\x0300,01Next: ',
'NEXT_PLAYER': '\x0300,01%s (%s cards)',
'D2': '\x0300,01%s draws two and is skipped!',
'CARDS': '\x0300,01Cards: %s',
'WD4': '\x0300,01%s draws four and is skipped!',
'WD40': '\x0300,01%s draws forty and is skipped!',
'SKIPPED': '\x0300,01%s is skipped!',
'REVERSED': '\x0300,01Order reversed!',
'GAINS': '\x0300,01%s gains %s points!',
'SCORE_ROW': '\x0300,01#%(rank)s %(nick)s (%(points)s points, won %(wins)s of %(games)s games, %(points_per_game)0.2f points per game, %(percent_wins)0.2f percent wins)',
'GAME_ALREADY_DEALT': '\x0300,01Game has already been dealt, please wait until game is over or stopped.',
'PLAYER_COLOR_ENABLED': '\x0300,01Hand card colors \x0309,01enabled\x0300,01! Format: <COLOR>/[<CARD>]. Example: R/[D2] is a red Draw Two. Type \'.uno-help\' for more help.',
'PLAYER_COLOR_DISABLED': '\x0300,01Hand card colors \x0304,01disabled\x0300,01.',
'DISABLED_PCE': '\x0300,01Hand card colors is \x0304,01disabled\x0300,01 for %s. To enable, \'.pce-on\'',
'ENABLED_PCE': '\x0300,01Hand card colors is \x0309,01enabled\x0300,01 for %s. To disable, \'.pce-off\'',
'PCE_CLEARED': '\x0300,01All players\' hand card color setting is reset by %s.',
'PLAYER_LEAVES': '\x0300,01Player %s has left the game.',
'OWNER_CHANGE': '\x0300,01Owner %s has left the game. New owner is %s.',
'STAT_TYPE_ERROR': '\x0300,01Supported rankings are %s.',
'FORCE_PLAY': '\x0300,01Forcing %s to play.',
'CANT_FORCE_PLAY': '\x0300,01You can\'t force %s to play yet; wait another %s seconds.',
'CANT_FORCE_LEAVE': '\x0300,01You can\'t force %s to leave the game yet; wait another %s seconds.',
'FORCE_BOT': '\x0300,01Forcing %s to enable autopilot.',
'CANT_FORCE_BOT': '\x0300,01You can\'t force %s to enable autopilot yet; wait another %s seconds.',
'PLAYS': '\x0300,01%s plays %s.',
'BOT_PLAY_ON': '\x0300,01%s has turned on autopilot.',
'BOT_PLAY_OFF': '\x0300,01%s has turned off autopilot.',
'ALREADY_STARTED': 'Game already started by %s! Type ".join" to join!',
'GAME_STARTED': 'IRC-UNO started by %s - Type ".join" to join!',
'GAME_STOPPED': 'Game stopped.',
'CANT_STOP': '%s is the game owner, you can\'t stop it! To force stop the game, please wait %s seconds.',
'DEALING_IN': 'Dealing %s into the game as player #%s!',
'JOINED': 'Dealing %s into the game as player #%s!',
'ALREADY_JOINED': 'Player, %s, is already in the game as player #%s!',
'ENOUGH': 'There are enough players, type .deal to start!',
'NOT_STARTED': 'Game not started, type .uno to start!',
'NOT_ENOUGH': 'Not enough players to deal yet.',
'NEEDS_TO_DEAL': '%s needs to deal.',
'ALREADY_DEALT': 'Already dealt.',
'ON_TURN': 'It\'s the turn of %s',
'DONT_HAVE': 'You don\'t have that card, %s',
'DOESNT_PLAY': 'That card does not play, %s',
'UNO': 'UNO! %s has ONE card left!',
'WIN': 'We have a winner! %s!!!! This game took %s',
'DRAWN_ALREADY': 'You\'ve already drawn, either .pass or .play!',
'DRAWS': '%s draws a card',
'DRAWN_CARD': 'Drawn card: %s',
'DRAW_FIRST': '%s, you need to draw first!',
'PASSED': '%s passed!',
'NO_SCORES': 'No scores yet',
'TOP_CARD': 'It\'s the turn of %s | Top Card: %s',
'YOUR_CARDS': 'Your cards: %s',
'NEXT_START': 'Next: ',
'NEXT_PLAYER': '%s (%s cards)',
'D2': '%s draws two and is skipped!',
'CARDS': 'Cards: %s',
'WD4': '%s draws four and is skipped!',
'WD40': '%s draws forty and is skipped!',
'SKIPPED': '%s is skipped!',
'REVERSED': 'Order reversed!',
'GAINS': '%s gains %s points!',
'SCORE_ROW': '#%(rank)s %(nick)s (%(points)s points, won %(wins)s of %(games)s games, %(points_per_game)0.2f points per game, %(percent_wins)0.2f percent wins)',
'GAME_ALREADY_DEALT': 'Game has already been dealt, please wait until game is over or stopped.',
'PLAYER_COLOR_ENABLED': 'Hand card colors \x0309,01enabled\x0f! Format: <COLOR>/[<CARD>]. Example: R/[D2] is a red Draw Two. Type \'.uno-help\' for more help.',
'PLAYER_COLOR_DISABLED': 'Hand card colors \x0304,01disabled\x0f.',
'DISABLED_PCE': 'Hand card colors is \x0304,01disabled\x0f for %s. To enable, \'.pce-on\'',
'ENABLED_PCE': 'Hand card colors is \x0309,01enabled\x0f for %s. To disable, \'.pce-off\'',
'PCE_CLEARED': 'All players\' hand card color setting is reset by %s.',
'PLAYER_LEAVES': 'Player %s has left the game.',
'OWNER_CHANGE': 'Owner %s has left the game. New owner is %s.',
'STAT_TYPE_ERROR': 'Supported rankings are %s.',
'FORCE_PLAY': 'Forcing %s to play.',
'CANT_FORCE_PLAY': 'You can\'t force %s to play yet; wait another %s seconds.',
'CANT_FORCE_LEAVE': 'You can\'t force %s to leave the game yet; wait another %s seconds.',
'FORCE_BOT': 'Forcing %s to enable autopilot.',
'CANT_FORCE_BOT': 'You can\'t force %s to enable autopilot yet; wait another %s seconds.',
'PLAYS': '%s plays %s.',
'BOT_PLAY_ON': '%s has turned on autopilot.',
'BOT_PLAY_OFF': '%s has turned off autopilot.',
}

def parse_old_scores(filename):
Expand Down Expand Up @@ -374,7 +374,7 @@ def _play_card(self, jenni, player, card):
the turn, or even the game, if someone won. Wild cards have their
color already set.
"""
jenni.msg(CHANNEL, STRINGS['PLAYS'] % (player, self.renderCards(player, [card], True)))
jenni.msg(CHANNEL, STRINGS['PLAYS'] % (player, self.renderCards([card], nick=player)))
self.cardPlayed(jenni, card)
if len(self.players[player]) == 1:
jenni.msg(CHANNEL, STRINGS['UNO'] % player)
Expand Down Expand Up @@ -471,7 +471,7 @@ def _draw(self, jenni, player):
card = self.getCard()
self.players[player].append(card)
self._activity()
jenni.notice(player, STRINGS['DRAWN_CARD'] % self.renderCards(player, [card], 0))
jenni.notice(player, STRINGS['DRAWN_CARD'] % self.renderCards([card], nick=player))

def draw(self, jenni, input):
player = input.nick.lower()
Expand Down Expand Up @@ -550,7 +550,7 @@ def getCard(self):
return ret

def showOnTurn(self, jenni):
jenni.msg(CHANNEL, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards(None, [self.topCard], 1)))
jenni.msg(CHANNEL, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards([self.topCard])))
self.showCards(jenni, self.playerOrder[self.currentPlayer])

def showCards(self, jenni, user):
Expand All @@ -568,36 +568,41 @@ def showCards(self, jenni, user):
if user not in self.players:
jenni.notice(user, msg)
else:
jenni.notice(user, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards(None, [self.topCard], 1)))
jenni.notice(user, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards([self.topCard])))
# Show up to 15 cards per message
cards = sorted(list(self.players[user]))
while cards:
jenni.notice(user, STRINGS['YOUR_CARDS'] % self.renderCards(user, cards[:15], 0))
jenni.notice(user, STRINGS['YOUR_CARDS'] % self.renderCards(cards[:15], nick=user))
cards = cards[15:]
jenni.notice(user, msg)

def renderCards(self, nick, cards, is_chan):
def renderCards(self, cards, nick=None):
irc_colors = {
'*': '\x0301,00',
'B': '\x0301,11',
'G': '\x0301,09',
'R': '\x0301,04',
'Y': '\x0301,08',
None: '\x0300,01',
None: '\x0f',
}
nickk = nick

if nick:
nickk = (nick).lower()
if self.players_pce.get(nick.lower(), False):
render_style = 'pce'
else:
render_style = 'normal'
else:
render_style = 'channel'

rendered_cards = []
for color, face in sorted(cards):
# Might consider this format: "%s[%s%s]" % (irc_colors[color], color, face))
if not is_chan:
if self.players_pce.get(nickk, 0):
rendered = '%s%s/[%s]%s ' % (irc_colors[color], color, face, irc_colors[None])
else:
rendered = '%s[%s]' % (irc_colors[color], face)
else:
if render_style == 'channel':
rendered = '%s(%s) [%s]' % (irc_colors[color], color, face)
elif render_style == 'normal':
rendered = '%s[%s]' % (irc_colors[color], face)
elif render_style == 'pce':
rendered = '%s%s/[%s]%s ' % (irc_colors[color], color, face, irc_colors[None])
rendered_cards.append(rendered)
rendered_cards.append(irc_colors[None])
return ''.join(rendered_cards)
Expand All @@ -618,16 +623,16 @@ def cardPlayed(self, jenni, card):
color, face = card
if face == 'D2':
jenni.msg(CHANNEL, STRINGS['D2'] % target_player)
z = [self.getCard(), self.getCard()]
jenni.notice(target_player, STRINGS['CARDS'] % self.renderCards(target_player, z, 0))
self.players[target_player].extend (z)
cards = [self.getCard(), self.getCard()]
jenni.notice(target_player, STRINGS['CARDS'] % self.renderCards(cards, nick=target_player))
self.players[target_player].extend (cards)
self.incPlayer()
elif face in ['WD4', 'WD40']:
num = int(face[2:])
jenni.msg(CHANNEL, STRINGS['WD%s' % num] % target_player)
z = [self.getCard() for _ in range(num)]
jenni.notice(target_player, STRINGS['CARDS'] % self.renderCards(target_player, z, 0))
self.players[target_player].extend(z)
cards = [self.getCard() for _ in range(num)]
jenni.notice(target_player, STRINGS['CARDS'] % self.renderCards(cards, nick=target_player))
self.players[target_player].extend(cards)
self.incPlayer()
elif face == 'S':
jenni.msg(CHANNEL, STRINGS['SKIPPED'] % target_player)
Expand Down Expand Up @@ -681,7 +686,7 @@ def saveScores(self, players, winner, score, time):
def showTopCard_demand(self, jenni):
if not self.game_on or not self.deck:
return
jenni.say(STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards(None, [self.topCard], 1)))
jenni.say(STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards([self.topCard])))

def leave(self, jenni, input):
nickk = (input.nick).lower()
Expand Down Expand Up @@ -724,7 +729,7 @@ def remove_player(self, jenni, nick):
jenni.msg(CHANNEL, STRINGS['OWNER_CHANGE'] % (nick, self.playerOrder[0]))

if self.dealt:
jenni.msg(CHANNEL, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards(None, [self.topCard], 1)))
jenni.msg(CHANNEL, STRINGS['TOP_CARD'] % (self.playerOrder[self.currentPlayer], self.renderCards([self.topCard])))

if poke_bots:
self._play_bots(jenni)
Expand Down