mirror of
https://github.com/oddluck/limnoria-plugins.git
synced 2025-04-25 12:31:07 -05:00
1307 lines
49 KiB
Python
1307 lines
49 KiB
Python
###
|
|
# Copyright (c) SpiderDave
|
|
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright notice,
|
|
# this list of conditions, and the following disclaimer.
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions, and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# * Neither the name of the author of this software nor the name of
|
|
# contributors to this software may be used to endorse or promote products
|
|
# derived from this software without specific prior written consent.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
###
|
|
|
|
import re
|
|
import random
|
|
|
|
import supybot.conf as conf
|
|
import supybot.utils as utils
|
|
from supybot.commands import *
|
|
import supybot.ircmsgs as ircmsgs
|
|
import supybot.ircutils as ircutils
|
|
import supybot.callbacks as callbacks
|
|
import time
|
|
import os, errno
|
|
import pickle
|
|
|
|
try:
|
|
from supybot.i18n import PluginInternationalization
|
|
|
|
_ = PluginInternationalization("UNO")
|
|
except ImportError:
|
|
# Placeholder that allows to run the plugin on a bot
|
|
# without the i18n module
|
|
_ = lambda x: x
|
|
|
|
|
|
class UNO(callbacks.Plugin):
|
|
"""
|
|
UNO!
|
|
"""
|
|
|
|
threaded = True
|
|
|
|
game = [{}, {}, {}, {}, {}]
|
|
|
|
channeloptions = {}
|
|
channeloptions["allow_game"] = False
|
|
channeloptions["debug"] = False
|
|
channeloptions["use_queue"] = True
|
|
channeloptions["nplayers"] = 10
|
|
channeloptions["maxbots"] = 9
|
|
channeloptions["use_colors"] = True
|
|
channeloptions["use_notice"] = True
|
|
|
|
lastgame = time.time()
|
|
|
|
def make_sure_path_exists(path):
|
|
try:
|
|
os.makedirs(path)
|
|
except OSError as exception:
|
|
if exception.errno != errno.EEXIST:
|
|
raise
|
|
|
|
make_sure_path_exists(r"%s%suno" % (conf.supybot.directories.data(), os.sep))
|
|
dataPath = r"%s%suno%s" % (conf.supybot.directories.data(), os.sep, os.sep)
|
|
prefixChar = conf.supybot.reply.whenAddressedBy.chars()[0]
|
|
|
|
def start(self, irc, msg, args, text):
|
|
"""
|
|
Start a new game of UNO. For the rules of the game, use the "uno rules" command.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
if self.channeloptions["allow_game"] == False:
|
|
irc.reply("Error: allow_game=False")
|
|
return
|
|
|
|
def get(group):
|
|
v = group.getSpecific(channel=msg.args[0])
|
|
return v()
|
|
|
|
try:
|
|
prefixChar = get(conf.supybot.reply.whenAddressedBy.chars)[0]
|
|
except:
|
|
prefixChar = ""
|
|
|
|
# may want to add a game variant later
|
|
if text:
|
|
gametype = text.lower().strip()
|
|
if gametype.replace(" ", "") == "globalthermalnuclearwar":
|
|
irc.reply("Curious game. The only winning move is not to play.")
|
|
return
|
|
if gametype not in ["uno"]:
|
|
irc.reply("Error: Invald game type %s." % gametype)
|
|
return
|
|
else:
|
|
gametype = "uno"
|
|
nick = msg.nick
|
|
table = self._gettablefromnick(nick)
|
|
if table != None:
|
|
gametype = self.game[table].get("type").capitalize()
|
|
irc.reply("Error: You are already in a game of %s." % gametype)
|
|
return
|
|
|
|
table = self._getopentable()
|
|
if table == None:
|
|
irc.reply("Sorry, all the game tables are in use at the moment.")
|
|
return
|
|
|
|
self._cleanup(table)
|
|
self.game[table]["channel"] = msg.args[0]
|
|
self.game[table]["type"] = gametype
|
|
|
|
if gametype == "uno":
|
|
self.game[table]["players"][nick] = {}
|
|
# self.game[table]['nplayers']=int(self.channeloptions[gametype+'_nplayers'])
|
|
self.game[table]["nplayers"] = int(self.channeloptions["nplayers"])
|
|
irc.reply(
|
|
"%s has started a new game of %s at table %s. For the rules of the"
|
|
' game, type "%suno rules". To accept this challenge, join with "%suno'
|
|
' join". To add a cpu player, type "%suno join cpu".'
|
|
% (
|
|
nick,
|
|
gametype.capitalize(),
|
|
table + 1,
|
|
prefixChar,
|
|
prefixChar,
|
|
prefixChar,
|
|
),
|
|
prefixNick=False,
|
|
)
|
|
self.game[table]["phase"] = "join"
|
|
|
|
start = wrap(start, ["public", optional("something")])
|
|
|
|
def begin(self, irc, msg, args):
|
|
"""
|
|
Begin the UNO game.
|
|
"""
|
|
self._uno_begin(irc, msg.nick)
|
|
|
|
begin = wrap(begin)
|
|
|
|
def _uno_begin(self, irc, nick):
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
irc.reply("Error: You are not playing a game at any of the tables.")
|
|
return
|
|
if self.game[table]["type"] != "uno":
|
|
irc.reply("Error: Not an UNO game.")
|
|
return
|
|
if self.game[table]["phase"] != "join":
|
|
irc.reply("Error: You can't use this command right now.")
|
|
return
|
|
nplayers = list(self.game[table]["players"].keys())
|
|
if len(nplayers) < 2:
|
|
irc.reply("Error: You need at least two players for UNO.")
|
|
return
|
|
# start things for real
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self.game[table]["players"][n]["hand"] = []
|
|
# each player draws 7 initial cards
|
|
for i in range(0, 7):
|
|
card = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][n]["hand"].append(card)
|
|
self.game[table]["phase"] = "running"
|
|
irc.reply(
|
|
"Game started! Check your notices and follow the instructions.",
|
|
prefixNick=False,
|
|
to=self.game[table]["channel"],
|
|
)
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, n)
|
|
self._uno_do_cpu(irc, table)
|
|
|
|
def _uno_do_cpu(self, irc, table):
|
|
while 1:
|
|
if self.game[table].get("phase") != "running":
|
|
return
|
|
if self.game[table].get("type") != "uno":
|
|
return
|
|
turnplayer = list(self.game[table]["players"].keys())[
|
|
self.game[table]["turn"]
|
|
]
|
|
if self.game[table]["players"][turnplayer].get("cpu"):
|
|
self._uno_cpu_play(irc, table)
|
|
else:
|
|
return
|
|
|
|
def _uno_tell_status(self, irc, nick):
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
irc.reply("Error: You are not playing UNO at any of the tables.")
|
|
return
|
|
channel = self.game[table]["channel"]
|
|
|
|
def get(group):
|
|
v = group.getSpecific(channel=channel)
|
|
return v()
|
|
|
|
try:
|
|
prefixChar = get(conf.supybot.reply.whenAddressedBy.chars)[0]
|
|
except:
|
|
prefixChar = ""
|
|
|
|
opponents = [p for p in list(self.game[table]["players"].keys()) if p != nick]
|
|
opponent = opponents[0]
|
|
opponent_cards = [
|
|
"%s has %s cards" % (n, len(self.game[table]["players"][n]["hand"]))
|
|
for n in list(self.game[table]["players"].keys())
|
|
if n != nick
|
|
]
|
|
opponent_cards = ", ".join(opponent_cards)
|
|
topcard = self.game[table]["discard"][-1]
|
|
if "Wild" in topcard:
|
|
topcard = "%s (%s)" % (topcard, self.game[table].get("wildcolor"))
|
|
yourhand = self.game[table]["players"][nick]["hand"]
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
opponent_ncards = len(self.game[table]["players"][opponent]["hand"])
|
|
turnplayer = list(self.game[table]["players"].keys())[self.game[table]["turn"]]
|
|
if turnplayer == nick:
|
|
if self.game[table]["players"][turnplayer].get("cpu"):
|
|
# We'll skip notice in the channel since the cpu player will
|
|
# take their turn quickly, and no need to announce it.
|
|
pass
|
|
else:
|
|
if self.channeloptions["use_colors"] == True:
|
|
if "Red" in topcard:
|
|
topcardcolor = ircutils.mircColor(topcard, "red", "black")
|
|
elif "Blue" in topcard:
|
|
topcardcolor = ircutils.mircColor(
|
|
topcard, "light blue", "black"
|
|
)
|
|
elif "Green" in topcard:
|
|
topcardcolor = ircutils.mircColor(
|
|
topcard, "light green", "black"
|
|
)
|
|
else:
|
|
topcardcolor = ircutils.mircColor(topcard, "yellow", "black")
|
|
txt = "It is %s's turn. The top card is %s." % (nick, topcardcolor)
|
|
txt = txt.replace("s's", "s'")
|
|
irc.reply(txt, to=channel)
|
|
turnplayer = "your"
|
|
yourhandcolor = []
|
|
for i in range(len(yourhand)):
|
|
if "Red" in yourhand[i]:
|
|
yourhandcolor.append(
|
|
ircutils.mircColor(yourhand[i], "red", "black")
|
|
)
|
|
elif "Green" in yourhand[i]:
|
|
yourhandcolor.append(
|
|
ircutils.mircColor(yourhand[i], "light green", "black")
|
|
)
|
|
elif "Blue" in yourhand[i]:
|
|
yourhandcolor.append(
|
|
ircutils.mircColor(yourhand[i], "light blue", "black")
|
|
)
|
|
elif "Yellow" in yourhand[i]:
|
|
yourhandcolor.append(
|
|
ircutils.mircColor(yourhand[i], "yellow", "black")
|
|
)
|
|
else:
|
|
yourhandcolor.append(
|
|
ircutils.mircColor(yourhand[i], None, "black")
|
|
)
|
|
yourhandcolor = utils.str.commaAndify(yourhandcolor)
|
|
txt = (
|
|
"It is your turn. The top card is %s. You have %s cards (%s)."
|
|
' %s. To play a card, use the "%suno play" command.'
|
|
% (
|
|
topcardcolor,
|
|
ncards,
|
|
yourhandcolor,
|
|
opponent_cards,
|
|
prefixChar,
|
|
)
|
|
)
|
|
if self.channeloptions["use_notice"] == True:
|
|
self.reply(irc, txt, to=nick, notice=True, private=True)
|
|
else:
|
|
self.reply(irc, txt, to=nick, notice=False, private=True)
|
|
else:
|
|
yourhand = utils.str.commaAndify(yourhand)
|
|
txt = "It is %s's turn. The top card is %s." % (nick, topcard)
|
|
txt = txt.replace("s's", "s'")
|
|
irc.reply(txt, to=channel)
|
|
turnplayer = "your"
|
|
txt = (
|
|
"It is your turn. The top card is %s. You have %s cards (%s)."
|
|
' %s. To play a card, use the "%suno play" command.'
|
|
% (topcard, ncards, yourhand, opponent_cards, prefixChar)
|
|
)
|
|
if self.channeloptions["use_notice"] == True:
|
|
self.reply(irc, txt, to=nick, notice=True, private=True)
|
|
else:
|
|
self.reply(irc, txt, to=nick, notice=False, private=True)
|
|
else:
|
|
pass
|
|
|
|
def _uno_is_valid_play(self, table, card, discard, wildcolor):
|
|
if card == "Wild":
|
|
# Wild is always a valid play for now
|
|
return True
|
|
if card == "Wild Draw 4":
|
|
turnplayer = list(self.game[table]["players"].keys())[
|
|
self.game[table]["turn"]
|
|
]
|
|
if "Wild" not in discard:
|
|
discardcolor = discard.split(" ", 1)[0]
|
|
else:
|
|
discardcolor = wildcolor
|
|
for c in self.game[table]["players"][turnplayer]["hand"]:
|
|
if discardcolor in c:
|
|
return False
|
|
return True
|
|
|
|
unocolors = ["Blue", "Green", "Red", "Yellow"]
|
|
for color in unocolors:
|
|
if color in card:
|
|
if "Wild" in discard:
|
|
# Wild or Wild Draw 4
|
|
if color == self.game[table].get("wildcolor"):
|
|
return True
|
|
else:
|
|
return False
|
|
if color in discard:
|
|
# Color matches
|
|
return True
|
|
if card.split(" ", 1)[1] == discard.split(" ", 1)[1]:
|
|
# Number or word matches
|
|
return True
|
|
return False
|
|
|
|
def _uno_draw_card(self, table, player):
|
|
if len(self.game[table]["deck"]) > 1:
|
|
card = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][player]["hand"].append(card)
|
|
else:
|
|
card = self.game[table]["deck"].pop(0)
|
|
self.game[table]["players"][player]["hand"].append(card)
|
|
if len(self.game[table]["deck"]) == 0:
|
|
self.game[table]["deck"] = self.game[table]["discard"]
|
|
self.game[table]["discard"] = []
|
|
random.shuffle(self.game[table]["deck"])
|
|
topcard = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["discard"].append(topcard)
|
|
return card
|
|
|
|
def tellstatus(self, irc, msg, args):
|
|
"""
|
|
Tell current UNO status
|
|
"""
|
|
self._uno_tell_status(irc, msg.nick)
|
|
|
|
tellstatus = wrap(tellstatus)
|
|
|
|
def rules(self, irc, msg, args, text):
|
|
"""
|
|
Display rules for uno. Start a game of uno with the "uno start" command.
|
|
"""
|
|
if text:
|
|
gametype = text.lower().strip()
|
|
else:
|
|
gametype = "uno"
|
|
if gametype == "uno":
|
|
irc.reply("Rules for UNO: http://www.wonkavator.com/uno/unorules.html")
|
|
else:
|
|
irc.reply("Unknown game type.")
|
|
|
|
rules = wrap(rules, [additional("text")])
|
|
|
|
def join(self, irc, msg, args, table, fakenick):
|
|
"""[<table>]
|
|
Join a game of UNO previously started with the "uno start" command.
|
|
Specify <table> if there is more than one game to join in that channel.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
if self.channeloptions["allow_game"] == False:
|
|
irc.reply("Error: allow_game=False")
|
|
return
|
|
|
|
def get(group):
|
|
v = group.getSpecific(channel=msg.args[0])
|
|
return v()
|
|
|
|
try:
|
|
prefixChar = get(conf.supybot.reply.whenAddressedBy.chars)[0]
|
|
except:
|
|
prefixChar = ""
|
|
|
|
nick = msg.nick
|
|
if table != None:
|
|
table -= 1 # make tables zero based
|
|
tables = self._getcurrenttables()
|
|
if not tables:
|
|
# no games running
|
|
irc.reply("Error: There are no games to join.")
|
|
return
|
|
if table != None and table not in tables:
|
|
# given table doesn't have a game going
|
|
if table not in list(range(len(self.game))):
|
|
irc.reply("Error: That table doesn't exist")
|
|
return
|
|
irc.reply("Error: There is no game at that table")
|
|
return
|
|
tables = [t for t in tables if self.game[t]["channel"] == msg.args[0]]
|
|
if table != None:
|
|
if table not in tables:
|
|
irc.reply("Error: That table is in another channel.")
|
|
return
|
|
tables = [table] # success!
|
|
if len(tables) == 0:
|
|
irc.reply("Error: There are no games to join in this channel.")
|
|
return
|
|
elif len(tables) == 1:
|
|
table = tables[0]
|
|
else:
|
|
messagetxt = (
|
|
"Please specify which table you'd like to play at (uno join <table>)."
|
|
" Current tables are: "
|
|
)
|
|
for t in tables:
|
|
messagetxt += "Table %s (%s), " % (
|
|
t + 1,
|
|
" ".join(list(self.game[t]["players"].keys())),
|
|
)
|
|
messagetxt = messagetxt.rsplit(", ", 1)[0] + "."
|
|
irc.reply(messagetxt)
|
|
return
|
|
isfake = False
|
|
iscpu = False
|
|
if ((self.channeloptions["debug"]) and fakenick) or (
|
|
fakenick and fakenick.lower() == "cpu"
|
|
):
|
|
nick = fakenick
|
|
isfake = True
|
|
if fakenick.lower() == "cpu":
|
|
iscpu = True
|
|
if self.game[table]["phase"] == "join":
|
|
if nick in list(self.game[table]["players"].keys()):
|
|
irc.reply("Error: you have already joined.")
|
|
return
|
|
if self.game[table]["type"] == "uno":
|
|
self._init_uno(table)
|
|
if iscpu == True:
|
|
nick = self._uno_make_cpu(table)
|
|
else:
|
|
self.game[table]["players"][nick] = {}
|
|
if isfake == True:
|
|
self.game[table]["players"][nick]["fake"] = True
|
|
|
|
if (
|
|
len(list(self.game[table]["players"].keys()))
|
|
< self.game[table]["nplayers"]
|
|
):
|
|
irc.reply(
|
|
"%s has joined the %s game at table %s. Use %suno begin to"
|
|
" begin the game."
|
|
% (nick, self.game[table]["type"], table + 1, prefixChar),
|
|
prefixNick=False,
|
|
to=self.game[table]["channel"],
|
|
)
|
|
return
|
|
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self.game[table]["players"][n]["hand"] = []
|
|
# each player draws 7 initial cards
|
|
for i in range(0, 7):
|
|
card = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][n]["hand"].append(card)
|
|
irc.reply(
|
|
"Game started! Check your notices and follow the instructions.",
|
|
prefixNick=False,
|
|
to=self.game[table]["channel"],
|
|
)
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, n)
|
|
self.game[table]["phase"] = "running"
|
|
else:
|
|
if self.game[table]["phase"] == "running":
|
|
irc.reply("Error: Game already running.")
|
|
return
|
|
elif self.game[table]["phase"] == "":
|
|
irc.reply(
|
|
'Error: You need to create a game with the "uno start" command'
|
|
" first."
|
|
)
|
|
return
|
|
else:
|
|
# don't know when this would happen, but whatever
|
|
irc.reply("Error: not join phase.")
|
|
return
|
|
|
|
join = wrap(join, ["public", optional("int"), optional("something")])
|
|
|
|
def leave(self, irc, msg, args, fakenick):
|
|
"""
|
|
Leave a game of UNO.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
if self.channeloptions["allow_game"] == False:
|
|
irc.reply("Error: allow_game=False")
|
|
return
|
|
|
|
nick = msg.nick
|
|
if self.channeloptions["debug"] and fakenick:
|
|
nick = fakenick
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
irc.reply("Error: You are not playing a game at any of the tables.")
|
|
return
|
|
|
|
if self.game[table].get("type") == "uno":
|
|
self._leavegame(irc, msg, nick)
|
|
self._uno_do_cpu(irc, table) # only works if game type is uno
|
|
return
|
|
|
|
leave = wrap(leave, ["public", optional("something")])
|
|
|
|
def _leavegame(self, irc, msg, nick):
|
|
"""
|
|
Leave a game of UNO.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
if self.channeloptions["allow_game"] == False:
|
|
irc.reply("Error: allow_game=False")
|
|
return
|
|
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
return
|
|
|
|
channel = self.game[table]["channel"]
|
|
|
|
# leaving a game when you're the only player
|
|
if len(self.game[table]["players"]) == 1:
|
|
irc.reply("There are no more players; The game is over.", to=channel)
|
|
self.game[table]["phase"] = "gameover"
|
|
self._cleanup(table)
|
|
return
|
|
|
|
# check if it's only bot players left
|
|
Human = False
|
|
for n in list(self.game[table]["players"].keys()):
|
|
if not self.game[table]["players"][n].get("cpu"):
|
|
if n != nick:
|
|
Human = True
|
|
|
|
if not Human:
|
|
irc.reply("There are no more human players; the game is over.", to=channel)
|
|
self.game[table]["phase"] = "gameover"
|
|
self._cleanup(table)
|
|
return
|
|
|
|
# ---- replace with cpu ----
|
|
oldnick = nick
|
|
nick = self._uno_make_cpu(table)
|
|
del self.game[table]["players"][
|
|
nick
|
|
] # remove new cpu player (we just want the nick)
|
|
|
|
self.game[table]["players"][nick] = self.game[table]["players"][oldnick]
|
|
del self.game[table]["players"][oldnick]
|
|
self.game[table]["players"][nick]["fake"] = True
|
|
self.game[table]["players"][nick]["cpu"] = True
|
|
|
|
irc.reply(
|
|
"%s has been replaced by %s." % (oldnick, nick),
|
|
prefixNick=False,
|
|
to=self.game[table]["channel"],
|
|
)
|
|
return
|
|
|
|
def _init_uno(self, table):
|
|
self.game[table]["deck"] = []
|
|
self.game[table]["discard"] = []
|
|
self.game[table]["wildcolor"] = "Red"
|
|
self.game[table]["turn"] = 0
|
|
self.game[table]["direction"] = 1
|
|
unocolors = ["Blue", "Green", "Red", "Yellow"]
|
|
for unocolor in unocolors:
|
|
for i in range(10):
|
|
self.game[table]["deck"].append("%s %s" % (unocolor, i))
|
|
for i in range(1, 10):
|
|
self.game[table]["deck"].append("%s %s" % (unocolor, i))
|
|
for i in range(0, 2):
|
|
self.game[table]["deck"].append("%s Draw Two" % unocolor)
|
|
self.game[table]["deck"].append("%s Reverse" % unocolor)
|
|
self.game[table]["deck"].append("%s Skip" % unocolor)
|
|
for i in range(0, 4):
|
|
self.game[table]["deck"].append("Wild")
|
|
self.game[table]["deck"].append("Wild Draw 4")
|
|
self.unodeck = [card for card in self.game[table]["deck"]]
|
|
random.shuffle(self.game[table]["deck"])
|
|
card = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["discard"].append(card)
|
|
|
|
def _uno_make_cpu(self, table):
|
|
nicklist = [
|
|
"Snarl",
|
|
"Slag",
|
|
"Sludge",
|
|
"Swoop",
|
|
"Grimlock",
|
|
"Data",
|
|
"Lore",
|
|
"B-4",
|
|
"Marvin",
|
|
"Deep Thought",
|
|
"Gort",
|
|
"C-3PO",
|
|
"R2-D2",
|
|
"Daryl",
|
|
"Bishop",
|
|
"Johnny 5",
|
|
"Bender",
|
|
"Flexo",
|
|
"Dorothy",
|
|
"Robot B-9",
|
|
"K-9",
|
|
"Vicki",
|
|
"Buffybot",
|
|
"Lyla",
|
|
"Robo",
|
|
"Cyrax",
|
|
"Sektor",
|
|
]
|
|
nicklist = [
|
|
n for n in nicklist if n not in list(self.game[table]["players"].keys())
|
|
]
|
|
nick = random.choice(nicklist)
|
|
# assumes nick isn't taken atm
|
|
self.game[table]["players"][nick] = {}
|
|
self.game[table]["players"][nick]["fake"] = True
|
|
self.game[table]["players"][nick]["cpu"] = True
|
|
return nick
|
|
|
|
def _uno_cpu_play(self, irc, table):
|
|
channel = self.game[table]["channel"]
|
|
|
|
Human = False
|
|
for n in list(self.game[table]["players"].keys()):
|
|
if not self.game[table]["players"][n].get("cpu"):
|
|
Human = True
|
|
|
|
if not Human:
|
|
irc.reply("There are no more human players; the game is over.", to=channel)
|
|
self.game[table]["phase"] = "gameover"
|
|
self._cleanup(table)
|
|
return
|
|
|
|
nick = list(self.game[table]["players"].keys())[self.game[table]["turn"]]
|
|
discard = self.game[table]["discard"][-1]
|
|
wildcolor = self.game[table].get("wildcolor")
|
|
novalid = True
|
|
for c in self.game[table]["players"][nick]["hand"]:
|
|
if self._uno_is_valid_play(table, c, discard, wildcolor) == True:
|
|
novalid = False
|
|
if novalid == True:
|
|
# draw a card
|
|
card = self._uno_draw_card(table, nick)
|
|
self.game[table]["players"][nick]["hasdrawn"] = True
|
|
|
|
if self._uno_is_valid_play(table, card, discard, wildcolor) == True:
|
|
# always play the card if possible
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
irc.reply(
|
|
"%s draws a card, and plays it; It's a %s (%s cards left in hand)."
|
|
% (nick, card, ncards),
|
|
to=channel,
|
|
)
|
|
self.game[table]["players"][nick]["hand"].remove(card)
|
|
self.game[table]["discard"].append(card)
|
|
else:
|
|
# Can't play a card, end turn
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
irc.reply(
|
|
"%s draws a card (%s cards in hand)." % (nick, ncards),
|
|
to=self.game[table]["channel"],
|
|
)
|
|
card = ""
|
|
else:
|
|
# pick a random card
|
|
playablecards = [
|
|
c
|
|
for c in self.game[table]["players"][nick]["hand"]
|
|
if self._uno_is_valid_play(table, c, discard, wildcolor) == True
|
|
or "Wild" in c
|
|
]
|
|
card = random.choice(playablecards)
|
|
if card == "Wild" or card == "Wild Draw 4":
|
|
# Just do dumb blind color choice
|
|
unocolors = ["Blue", "Green", "Red", "Yellow"]
|
|
self.game[table]["wildcolor"] = random.choice(unocolors)
|
|
self.game[table]["players"][nick]["hand"].remove(card)
|
|
self.game[table]["discard"].append(card)
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
if "Wild" in card:
|
|
card = "%s (%s)" % (card, self.game[table]["wildcolor"])
|
|
if self.channeloptions["use_colors"] == True:
|
|
if "Red" in card:
|
|
cardcolor = ircutils.mircColor(card, "red", "black")
|
|
elif "Blue" in card:
|
|
cardcolor = ircutils.mircColor(card, "light blue", "black")
|
|
elif "Green" in card:
|
|
cardcolor = ircutils.mircColor(card, "light green", "black")
|
|
else:
|
|
cardcolor = ircutils.mircColor(card, "yellow", "black")
|
|
irc.reply(
|
|
"%s played %s (%s cards left in hand)." % (nick, cardcolor, ncards),
|
|
to=channel,
|
|
)
|
|
else:
|
|
irc.reply(
|
|
"%s played %s (%s cards left in hand)." % (nick, card, ncards),
|
|
to=channel,
|
|
)
|
|
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
if ncards == 0:
|
|
irc.reply(
|
|
"The game is over. " + ircutils.bold("%s wins!" % nick), to=channel
|
|
)
|
|
self.game[table]["phase"] = "gameover"
|
|
self._cleanup(table)
|
|
return
|
|
|
|
if "Reverse" in card:
|
|
self.game[table]["direction"] *= -1
|
|
|
|
nplayers = len(list(self.game[table]["players"].keys()))
|
|
turn = self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
if "Draw Two" in card or "Draw 4" in card:
|
|
ndrawcards = 2
|
|
if "Draw 4" in card:
|
|
ndrawcards = 4
|
|
drawplayer = list(self.game[table]["players"].keys())[
|
|
self.game[table]["turn"]
|
|
]
|
|
for n in range(ndrawcards):
|
|
c = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][drawplayer]["hand"].append(c)
|
|
ncards = len(self.game[table]["players"][drawplayer]["hand"])
|
|
irc.reply(
|
|
"%s draws %s cards (%s cards in hand)."
|
|
% (drawplayer, ndrawcards, ncards),
|
|
to=channel,
|
|
)
|
|
|
|
# Skip turn
|
|
if (
|
|
"Skip" in card
|
|
or "Draw Two" in card
|
|
or "Draw 4" in card
|
|
or ("Reverse" in card and nplayers == 2)
|
|
):
|
|
turn = self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, n)
|
|
return
|
|
|
|
def play(self, irc, msg, args, text):
|
|
"""<card>
|
|
Play a <card> for the UNO game. Examples: "uno play red 0", "uno play wild blue", "uno play draw", "uno play done"
|
|
"""
|
|
|
|
nick = msg.nick
|
|
|
|
def get(group):
|
|
v = group.getSpecific(channel=msg.args[0])
|
|
return v()
|
|
|
|
try:
|
|
prefixChar = get(conf.supybot.reply.whenAddressedBy.chars)[0]
|
|
except:
|
|
prefixChar = ""
|
|
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
irc.reply("Error: You are not playing a game at any of the tables.")
|
|
return
|
|
channel = self.game[table]["channel"]
|
|
if (
|
|
self.channeloptions["debug"]
|
|
and text.rsplit(" ", 1)[-1] in self.game[table]["players"]
|
|
):
|
|
fakenick = [
|
|
p
|
|
for p in self.game[table]["players"]
|
|
if p.lower() == text.rsplit(" ", 1)[-1].lower()
|
|
]
|
|
if len(fakenick) == 0:
|
|
fakenick = None
|
|
else:
|
|
fakenick = fakenick[0]
|
|
nick = fakenick
|
|
text = text.rsplit(" ", 1)[:-1][0]
|
|
|
|
if self.game[table]["phase"] == "running":
|
|
nplayers = len(list(self.game[table]["players"].keys()))
|
|
if nick not in self.game[table]["players"]:
|
|
irc.reply("Error: You're not playing this game.")
|
|
return
|
|
opponent = [p for p in self.game[table]["players"] if p != nick][0]
|
|
|
|
turnplayer = list(self.game[table]["players"].keys())[
|
|
self.game[table]["turn"]
|
|
]
|
|
if nick != turnplayer:
|
|
# Note: it will prefix nick in notice -- need to fix that
|
|
irc.reply("%s: It is %s's turn." % (nick, turnplayer), prefixNick=False)
|
|
return
|
|
|
|
text = text.strip()
|
|
|
|
discard = self.game[table]["discard"][-1]
|
|
wildcolor = self.game[table].get("wildcolor")
|
|
novalid = True
|
|
|
|
for c in self.game[table]["players"][nick]["hand"]:
|
|
if self._uno_is_valid_play(table, c, discard, wildcolor) == True:
|
|
novalid = False
|
|
|
|
if text.lower() == "draw":
|
|
if self.game[table]["players"][nick].get("hasdrawn") == True:
|
|
irc.reply("You have already drawn a card.")
|
|
return
|
|
if novalid == False:
|
|
irc.reply("You can't draw because you have a card you can play")
|
|
return
|
|
else:
|
|
# Draw a card
|
|
c = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][nick]["hand"].append(c)
|
|
if self._uno_is_valid_play(table, c, discard, wildcolor) == True:
|
|
self.reply(
|
|
irc,
|
|
"You draw a %s from the draw pile. You can choose not to"
|
|
' play this card using "%suno play done"'
|
|
% (c, prefixChar),
|
|
to=nick,
|
|
notice=True,
|
|
private=True,
|
|
)
|
|
self.game[table]["players"][nick]["hasdrawn"] = True
|
|
return
|
|
# card=c
|
|
else:
|
|
# Can't play a card, end turn
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
self.reply(
|
|
irc,
|
|
"You draw a %s from the draw pile. You have no cards to"
|
|
" play, and your turn is over."
|
|
% c,
|
|
to=nick,
|
|
notice=True,
|
|
private=True,
|
|
)
|
|
irc.reply(
|
|
"%s draws a card (%s cards in hand)." % (nick, ncards),
|
|
to=self.game[table]["channel"],
|
|
)
|
|
|
|
turn = (
|
|
self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
)
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, n)
|
|
self._uno_do_cpu(irc, table)
|
|
return
|
|
|
|
if text.lower() == "done":
|
|
if self.game[table]["players"][nick].get("hasdrawn") != True:
|
|
self.reply(
|
|
irc,
|
|
"You can't finish your turn without playing or drawing a card.",
|
|
to=nick,
|
|
notice=True,
|
|
private=True,
|
|
)
|
|
return
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
irc.reply(
|
|
"%s draws a card (%s cards in hand)." % (nick, ncards),
|
|
to=self.game[table]["channel"],
|
|
)
|
|
self.game[table]["players"][nick]["hasdrawn"] = False
|
|
|
|
turn = self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
for nn in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, nn)
|
|
self._uno_do_cpu(irc, table)
|
|
return
|
|
|
|
card = text
|
|
|
|
card = [card for card in self.unodeck if card.lower() == text.lower()]
|
|
validwild = [
|
|
"Wild Blue",
|
|
"Wild Green",
|
|
"Wild Red",
|
|
"Wild Yellow",
|
|
"Wild Draw 4 Blue",
|
|
"Wild Draw 4 Green",
|
|
"Wild Draw 4 Red",
|
|
"Wild Draw 4 Yellow",
|
|
]
|
|
if len(card) == 0:
|
|
card = [c for c in validwild if c.lower() == text.lower()]
|
|
if len(card) != 0:
|
|
card = card[0].rsplit(" ", 1)
|
|
newcolor = card[1]
|
|
card = [card[0]]
|
|
else:
|
|
if card[0] == "Wild" or card[0] == "Wild Draw 4":
|
|
irc.reply("You must specify a color when playing a Wild card.")
|
|
return
|
|
|
|
if len(card) == 0:
|
|
irc.reply("That is not a valid card.")
|
|
return
|
|
else:
|
|
card = card[0]
|
|
|
|
hand = self.game[table]["players"][nick]["hand"]
|
|
if card not in hand:
|
|
irc.reply("That card is not in your hand.")
|
|
return
|
|
|
|
# check for illegal move
|
|
if self._uno_is_valid_play(table, card, discard, wildcolor) == False:
|
|
irc.reply("You can't play that card.")
|
|
return
|
|
|
|
# play the card
|
|
self.game[table]["players"][nick]["hand"].remove(card)
|
|
self.game[table]["discard"].append(card)
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
if "Wild" in card:
|
|
self.game[table]["wildcolor"] = newcolor
|
|
card = "%s (%s)" % (card, self.game[table]["wildcolor"])
|
|
if self.channeloptions["use_colors"] == True:
|
|
if "Red" in card:
|
|
cardcolor = ircutils.mircColor(card, "red", "black")
|
|
elif "Blue" in card:
|
|
cardcolor = ircutils.mircColor(card, "light blue", "black")
|
|
elif "Green" in card:
|
|
cardcolor = ircutils.mircColor(card, "light green", "black")
|
|
else:
|
|
cardcolor = ircutils.mircColor(card, "yellow", "black")
|
|
if self.game[table]["players"][nick].get("hasdrawn") == True:
|
|
irc.reply(
|
|
"%s draws a card, and plays it; It's a %s (%s cards left in"
|
|
" hand)."
|
|
% (nick, cardcolor, ncards),
|
|
to=channel,
|
|
)
|
|
self.game[table]["players"][nick]["hasdrawn"] = False
|
|
else:
|
|
irc.reply(
|
|
"%s played %s (%s cards left in hand)."
|
|
% (nick, cardcolor, ncards),
|
|
to=channel,
|
|
)
|
|
else:
|
|
if self.game[table]["players"][nick].get("hasdrawn") == True:
|
|
irc.reply(
|
|
"%s draws a card, and plays it; It's a %s (%s cards left in"
|
|
" hand)."
|
|
% (nick, card, ncards),
|
|
to=channel,
|
|
)
|
|
self.game[table]["players"][nick]["hasdrawn"] = False
|
|
else:
|
|
irc.reply(
|
|
"%s played %s (%s cards left in hand)." % (nick, card, ncards),
|
|
to=channel,
|
|
)
|
|
|
|
ncards = len(self.game[table]["players"][nick]["hand"])
|
|
if ncards == 0:
|
|
irc.reply(
|
|
"The game is over. " + ircutils.bold("%s wins!" % nick), to=channel
|
|
)
|
|
self.game[table]["phase"] = "gameover"
|
|
self._cleanup(table)
|
|
return
|
|
|
|
if "Reverse" in card:
|
|
self.game[table]["direction"] *= -1
|
|
|
|
turn = self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
if "Draw Two" in card or "Draw 4" in card:
|
|
ndrawcards = 2
|
|
if "Draw 4" in card:
|
|
ndrawcards = 4
|
|
drawplayer = list(self.game[table]["players"].keys())[
|
|
self.game[table]["turn"]
|
|
]
|
|
for n in range(ndrawcards):
|
|
c = self.game[table]["deck"].pop(
|
|
random.randint(0, len(self.game[table]["deck"]) - 1)
|
|
)
|
|
self.game[table]["players"][drawplayer]["hand"].append(c)
|
|
ncards = len(self.game[table]["players"][drawplayer]["hand"])
|
|
irc.reply(
|
|
"%s draws %s cards (%s cards in hand)."
|
|
% (drawplayer, ndrawcards, ncards),
|
|
to=channel,
|
|
)
|
|
|
|
# Skip turn
|
|
if (
|
|
"Skip" in card
|
|
or "Draw Two" in card
|
|
or "Draw 4" in card
|
|
or ("Reverse" in card and nplayers == 2)
|
|
):
|
|
turn = self.game[table]["turn"] + 1 * self.game[table]["direction"]
|
|
if turn > nplayers - 1:
|
|
turn = 0
|
|
if turn < 0:
|
|
turn = nplayers - 1
|
|
self.game[table]["turn"] = turn
|
|
|
|
for n in list(self.game[table]["players"].keys()):
|
|
self._uno_tell_status(irc, n)
|
|
self._uno_do_cpu(irc, table)
|
|
else:
|
|
irc.reply("Error: game not running")
|
|
|
|
play = wrap(play, ["text"])
|
|
|
|
def setoption(self, irc, msg, args, channel, text, value):
|
|
"""<option> <value>
|
|
Changes an option for UNO game. You can view the
|
|
options for the current channel with the "uno showoptions" command.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
if value.lower() == "true":
|
|
value = True
|
|
elif value.lower() == "false":
|
|
value = False
|
|
elif value.lower() == "unset":
|
|
if text in self.channeloptions:
|
|
irc.reply("Set %s %s-->(unset)" % (text, self.channeloptions[text]))
|
|
del self.channeloptions[text]
|
|
try:
|
|
self._write_options(irc)
|
|
except:
|
|
irc.reply("Failed to write options to file. :(")
|
|
else:
|
|
irc.reply("%s was already unset." % text)
|
|
return
|
|
if text in self.channeloptions:
|
|
irc.reply("Set %s %s-->%s" % (text, self.channeloptions[text], value))
|
|
self.channeloptions[text] = value
|
|
else:
|
|
irc.reply("Set %s (unset)-->%s" % (text, value))
|
|
self.channeloptions[text] = value
|
|
try:
|
|
self._write_options(irc)
|
|
except:
|
|
irc.reply("Failed to write options to file. :(")
|
|
|
|
setoption = wrap(
|
|
setoption, [("checkChannelCapability", "op"), "something", "something"]
|
|
)
|
|
|
|
def showoptions(self, irc, msg, args):
|
|
"""
|
|
Shows options for UNO game for the current channel.
|
|
"""
|
|
try:
|
|
self._read_options(irc)
|
|
except:
|
|
pass
|
|
txt = ", ".join(
|
|
[
|
|
"=".join([str(i) for i in item])
|
|
for item in list(self.channeloptions.items())
|
|
]
|
|
)
|
|
irc.reply(txt)
|
|
|
|
showoptions = wrap(showoptions)
|
|
|
|
def _cleanup(self, table):
|
|
self.game[table] = {}
|
|
self.game[table]["players"] = {}
|
|
self.game[table]["phase"] = ""
|
|
|
|
def _getopentable(self):
|
|
openslot = [i for i in range(len(self.game)) if not self.game[i].get("phase")]
|
|
if len(openslot) == 0:
|
|
return None
|
|
else:
|
|
return openslot[0]
|
|
|
|
def _getcurrenttables(self):
|
|
slot = [i for i in range(len(self.game)) if self.game[i].get("phase")]
|
|
return slot
|
|
|
|
def _gettablefromnick(self, n):
|
|
tables = self._getcurrenttables()
|
|
if not tables:
|
|
return None
|
|
for table in tables:
|
|
if n.lower() in [
|
|
x.lower() for x in list(self.game[table]["players"].keys())
|
|
]:
|
|
return table
|
|
return None
|
|
|
|
def _read_options(self, irc):
|
|
network = irc.network.replace(" ", "_")
|
|
channel = irc.msg.args[0]
|
|
# irc.reply('test: %s.%s.options' % (irc.network, irc.msg.args[0] ))
|
|
|
|
f = "%s%s.%s.options" % (self.dataPath, network, channel)
|
|
if os.path.isfile(f):
|
|
inputfile = open(f, "rb")
|
|
self.channeloptions = pickle.load(inputfile)
|
|
inputfile.close()
|
|
else:
|
|
# Use defaults
|
|
channeloptions = {}
|
|
channeloptions["allow_game"] = False
|
|
channeloptions["debug"] = False
|
|
channeloptions["use_queue"] = True
|
|
channeloptions["nplayers"] = 10
|
|
channeloptions["maxbots"] = 9
|
|
channeloptions["use_colors"] = True
|
|
channeloptions["use_notice"] = True
|
|
return
|
|
|
|
def _write_options(self, irc):
|
|
network = irc.network.replace(" ", "_")
|
|
channel = irc.msg.args[0]
|
|
outputfile = open("%s%s.%s.options" % (self.dataPath, network, channel), "wb")
|
|
pickle.dump(self.channeloptions, outputfile)
|
|
outputfile.close()
|
|
|
|
def doNick(self, irc, msg):
|
|
oldNick = msg.nick
|
|
newNick = msg.args[0]
|
|
table = self._gettablefromnick(oldNick)
|
|
if table == None:
|
|
return
|
|
self.game[table]["players"][newNick] = self.game[table]["players"][oldNick]
|
|
del self.game[table]["players"][oldNick]
|
|
|
|
def doQuit(self, irc, msg):
|
|
nick = msg.nick
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
return
|
|
self._leavegame(irc, msg, nick)
|
|
self._uno_do_cpu(irc, table) # only works if game type is uno
|
|
|
|
def doPart(self, irc, msg):
|
|
# self.log.info('doPart debug: msg.args[0]=%s, msg.args[1]=%s, msg.command=%s, msg.nick=%s' % (msg.args[0], msg.args[1], msg.command, msg.nick))
|
|
nick = msg.nick
|
|
table = self._gettablefromnick(nick)
|
|
if table == None:
|
|
return
|
|
if msg.args[0] == self.game[table]["channel"]:
|
|
self._leavegame(irc, msg, nick)
|
|
self._uno_do_cpu(irc, table) # only works if game type is uno
|
|
|
|
def doKick(self, irc, msg):
|
|
(channel, nicks) = msg.args[:2]
|
|
nicks = nicks.split(",")
|
|
for nick in nicks:
|
|
table = self._gettablefromnick(nick)
|
|
if table != None:
|
|
self._leavegame(irc, msg, nick)
|
|
self._uno_do_cpu(irc, table) # only works if game type is uno
|
|
|
|
def _sendMsg(self, irc, msg):
|
|
if self.channeloptions["use_queue"]:
|
|
irc.queueMsg(msg)
|
|
else:
|
|
irc.sendMsg(msg)
|
|
irc.noReply()
|
|
|
|
def reply(
|
|
self,
|
|
irc,
|
|
text,
|
|
action=False,
|
|
notice=False,
|
|
private=False,
|
|
prefixNick=False,
|
|
to="",
|
|
fast=False,
|
|
):
|
|
table = self._gettablefromnick(to)
|
|
if table == None:
|
|
# hopefully it's a valid channel
|
|
pass
|
|
else:
|
|
if self.game[table]["players"][to].get("fake"):
|
|
if self.channeloptions["debug"]:
|
|
text = "(to %s): %s" % (to, text)
|
|
text = ircutils.mircColor(text, fg=14)
|
|
to = self.game[table]["channel"]
|
|
else:
|
|
# No need to show cpu actions anywhere if debug is false.
|
|
return
|
|
|
|
if action == True or fast == False:
|
|
irc.reply(
|
|
text,
|
|
action=action,
|
|
notice=notice,
|
|
private=private,
|
|
prefixNick=prefixNick,
|
|
to=to,
|
|
)
|
|
else:
|
|
if (prefixNick) and ("#" not in to):
|
|
text = "%s: %s" % (to, text)
|
|
m = ircmsgs.privmsg(to, text)
|
|
self._sendMsg(irc, m)
|
|
|
|
|
|
Class = UNO
|
|
|
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|