Browse Source

added harlot and fixed some minor bugs

master
jcao219 14 years ago
parent
commit
93710f6c37
  1. 74
      vars.py
  2. 2
      wolfbot.py
  3. 102
      wolfgame.py

74
vars.py

@ -3,16 +3,18 @@ MINIMUM_WAIT = 0 # debug, change to 60 for normal
EXTRA_WAIT = 20 EXTRA_WAIT = 20
MAXIMUM_WAITED = 2 # limit for amount of !wait's MAXIMUM_WAITED = 2 # limit for amount of !wait's
MAX_SHOTS = 2 MAX_SHOTS = 2
NIGHT_TIME_LIMIT = 90 NIGHT_TIME_LIMIT = 0
DAY_TIME_LIMIT = 137 DAY_TIME_LIMIT = 0
####################################################################################### GAME_MODES = {}
# ROLE INDEX: PLAYERS SEER WOLF CURSED DRUNK HARLOT TRAITOR GUNNER #
ROLES_GUIDE = { 4 : ( 1 , 1 , 0 , 0 , 0 , 0 , 0 ), # ############################################################################################
6 : ( 1 , 1 , 1 , 1 , 0 , 0 , 0 ), # # ROLE INDEX: PLAYERS SEER WOLF CURSED DRUNK HARLOT TRAITOR GUNNER CROW #
8 : ( 1 , 2 , 1 , 1 , 1 , 0 , 0 ), # ROLES_GUIDE = { 4 : ( 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0), #
10 : ( 1 , 2 , 1 , 1 , 1 , 1 , 1 )} # 6 : ( 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0), #
####################################################################################### 8 : ( 1 , 2 , 1 , 1 , 1 , 0 , 0 , 0), #
10 : ( 1 , 2 , 1 , 1 , 1 , 1 , 1 , 0)} #
############################################################################################
ROLE_INDICES = {0 : "seer", ROLE_INDICES = {0 : "seer",
1 : "wolf", 1 : "wolf",
@ -20,7 +22,8 @@ ROLE_INDICES = {0 : "seer",
3 : "village drunk", 3 : "village drunk",
4 : "harlot", 4 : "harlot",
5 : "traitor", 5 : "traitor",
6 : "gunner"} 6 : "gunner",
7 : "werecrow"}
@ -57,4 +60,53 @@ get_role = lambda plyr: list_players_and_roles()[plyr]
def del_player(pname): def del_player(pname):
prole = get_role(pname) prole = get_role(pname)
ROLES[prole].remove(pname) ROLES[prole].remove(pname)
class InvalidModeException(object): pass
def game_mode(name):
def decor(c):
GAME_MODES[name] = c
return c
return decor
CHANGEABLE_ROLES = { "seer" : 0,
"wolf" : 1,
"drunk" : 3,
"harlot" : 4,
"traitor" : 5,
"gunner" : 6,
"werecrow" : 7 }
# !game roles wolves:1 seers:0
# TODO: implement game modes
@game_mode("roles")
class ChangedRolesMode(object):
ROLES_GUIDE = ROLES_GUIDE.copy()
def __init__(self, arg):
pairs = arg.split(" ")
if len(parts) == 1:
raise InvalidModeException("Invalid syntax for !game roles.")
for pair in pairs:
change = pair.split(":")
if len(change) != 2:
raise InvalidModeException("Invalid syntax for !game roles.")
role, num = change
try:
num = int(num)
except ValueError:
raise InvalidModeException("A bad value was used in !game roles.")
for x in self.ROLES_GUIDE.keys():
lx = list(x)
try:
lx[CHANGEABLE_ROLES[role.lower()]] = num
except KeyError:
raise InvalidModeException('"{0}" is not a changeable role.'.format(role))
self.ROLES_GUIDE[x] = tuple(lx)
pl = list_players()
if len(pl) < sum(self.ROLES_GUIDE[4]):
raise InvalidModeException("Too few players for such these custom roles.")

2
wolfbot.py

@ -34,7 +34,7 @@ class WolfBotHandler(DefaultCommandHandler):
logging.debug('unhandled command %s(%s)' % (cmd, args)) logging.debug('unhandled command %s(%s)' % (cmd, args))
def main(): def main():
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.INFO, filename="log.txt")
cli = IRCClient(WolfBotHandler, host=botconfig.HOST, port=botconfig.PORT, nickname=botconfig.NICK, cli = IRCClient(WolfBotHandler, host=botconfig.HOST, port=botconfig.PORT, nickname=botconfig.NICK,
connect_cb=wolfgame.connect_callback) connect_cb=wolfgame.connect_callback)

102
wolfgame.py

@ -6,6 +6,7 @@ from datetime import datetime, timedelta
import threading import threading
import random import random
import copy import copy
from time import sleep
COMMANDS = {} COMMANDS = {}
PM_COMMANDS = {} PM_COMMANDS = {}
@ -62,6 +63,8 @@ def reset(cli):
@cmd("!bye", admin_only=True) @cmd("!bye", admin_only=True)
def forced_exit(cli, nick, *rest): # Admin Only def forced_exit(cli, nick, *rest): # Admin Only
reset(cli) reset(cli)
print("Quitting in 7 seconds.")
time.sleep(7)
cli.quit("Forced quit from admin") cli.quit("Forced quit from admin")
raise SystemExit raise SystemExit
@ -296,9 +299,9 @@ def chk_win(cli):
nitemin, nitesec = vars.NIGHT_TIMEDELTA.seconds // 60, vars.NIGHT_TIMEDELTA.seconds % 60 nitemin, nitesec = vars.NIGHT_TIMEDELTA.seconds // 60, vars.NIGHT_TIMEDELTA.seconds % 60
total = vars.DAY_TIMEDELTA + vars.NIGHT_TIMEDELTA total = vars.DAY_TIMEDELTA + vars.NIGHT_TIMEDELTA
tmin, tsec = total.seconds // 60, total.seconds % 60 tmin, tsec = total.seconds // 60, total.seconds % 60
cli.msg(chan, ("Game lasted \u0002{0:0<2}:{1:0<2}\u0002. " + cli.msg(chan, ("Game lasted \u0002{0:0>2}:{1:0>2}\u0002. " +
"\u0002{2:0<2}:{3:0<2}\u0002 was day. " + "\u0002{2:0>2}:{3:0>2}\u0002 was day. " +
"\u0002{4:0<2}:{5:0<2}\u0002 was night. ").format(tmin, tsec, "\u0002{4:0>2}:{5:0>2}\u0002 was night. ").format(tmin, tsec,
daymin, daysec, daymin, daysec,
nitemin, nitesec)) nitemin, nitesec))
@ -389,27 +392,42 @@ def transition_day(cli):
vars.NIGHT_TIMEDELTA += td vars.NIGHT_TIMEDELTA += td
min, sec = td.seconds // 60, td.seconds % 60 min, sec = td.seconds // 60, td.seconds % 60
message = ("Night lasted \u0002{0:0>2}:{1:0>2}\u0002. It is now daytime. "+ message = [("Night lasted \u0002{0:0>2}:{1:0>2}\u0002. It is now daytime. "+
"The villagers awake, thankful for surviving the night, "+ "The villagers awake, thankful for surviving the night, "+
"and search the village... ").format(min, sec) "and search the village... ").format(min, sec)]
dead = [] dead = []
if not vars.VICTIM: if not vars.VICTIM:
message += random.choice(vars.NO_VICTIMS_MESSAGES) message.append(random.choice(vars.NO_VICTIMS_MESSAGES) +
message += " All villagers, however, have survived." " All villagers, however, have survived.")
cli.msg(chan, message); elif vars.VICTIM in vars.ROLES["harlot"]: # Attacked harlot, yay no deaths
# TODO: check if visited is harlot if vars.HVISITED.get(vars.VICTIM):
else: message.append("The wolves' selected victim was a harlot, "+
message += ("The dead body of \u0002{0}\u0002, a "+ "but she wasn't home.")
"\u0002{1}\u0002, is found. Those remaining mourn his/her "+ if vars.VICTIM and (vars.VICTIM not in vars.ROLES["harlot"] or # not a harlot
"death.").format(vars.VICTIM, vars.get_role(vars.VICTIM)) not vars.HVISITED.get(vars.VICTIM)): # harlot stayed home
message.append(("The dead body of \u0002{0}\u0002, a "+
"\u0002{1}\u0002, is found. Those remaining mourn his/her "+
"death.").format(vars.VICTIM, vars.get_role(vars.VICTIM)))
dead.append(vars.VICTIM) dead.append(vars.VICTIM)
cli.msg(chan, message) if vars.VICTIM in vars.HVISITED.values(): # victim was visited by some harlot
for hlt in vars.HVISITED.keys():
if vars.HVISITED[hlt] == vars.VICTIM:
message.append(("\u0002{0}\u0002, a harlot, made the unfortunate mistake of "+
"visiting the victim's house last night and is "+
"now dead.").format(hlt))
dead.append(hlt)
# TODO: check if harlot also died # TODO: check if harlot also died
for harlot in vars.ROLES["harlot"]:
if vars.HVISITED.get(harlot) in vars.ROLES["wolf"]:
message.append(("\u0002{0}\u0002, a harlot, made the unfortunate mistake of "+
"visiting a wolf's house last night and is "+
"now dead.").format(harlot))
dead.append(harlot)
for deadperson in dead: for deadperson in dead:
if not del_player(cli, deadperson, True): if not del_player(cli, deadperson, True):
return return
cli.msg(chan, "\n".join(message))
cli.msg(chan, ("The villagers must now vote for whom to lynch. "+ cli.msg(chan, ("The villagers must now vote for whom to lynch. "+
'Use "!lynch <nick>" to cast your vote. 3 votes '+ 'Use "!lynch <nick>" to cast your vote. 3 votes '+
'are required to lynch.')) 'are required to lynch.'))
@ -422,6 +440,7 @@ def transition_day(cli):
def chk_nightdone(cli): def chk_nightdone(cli):
if (len(vars.SEEN) == len(vars.ROLES["seer"]) and if (len(vars.SEEN) == len(vars.ROLES["seer"]) and
len(vars.HVISITED.keys()) == len(vars.ROLES["harlot"]) and
vars.VICTIM and vars.PHASE == "night"): vars.VICTIM and vars.PHASE == "night"):
if vars.TIMERS[0]: if vars.TIMERS[0]:
vars.TIMERS[0].cancel() # cancel timer vars.TIMERS[0].cancel() # cancel timer
@ -462,6 +481,7 @@ def vote(cli, nick, chan, rest):
cli.notice(nick, "\u0002{0}\u0002 is currently not playing.".format(rest)) cli.notice(nick, "\u0002{0}\u0002 is currently not playing.".format(rest))
@checks @checks
@cmd("!retract") @cmd("!retract")
def retract(cli, nick, chan, rest): def retract(cli, nick, chan, rest):
@ -510,6 +530,42 @@ def kill(cli, nick, rest):
chk_nightdone(cli) chk_nightdone(cli)
@checks
@pmcmd("visit", "!visit")
def hvisit(cli, nick, rest):
if not vars.is_role(nick, "harlot"):
cli.msg(nick, "Only a harlot may use this command.")
return
if vars.PHASE != "night":
cli.msg(nick, "You may only visit someone at night.")
return
if vars.HVISITED.get(nick):
cli.msg(nick, ("You are already spending the night "+
"with \u0002{0}\u0002.").format(vars.HVISITED[nick]))
return
victim = rest.split(" ")[0].strip().lower()
if not victim:
cli.msg(nick, "Not enough parameters")
return
pl = [x.lower() for x in vars.list_players()]
if victim not in pl:
cli.msg(nick,"\u0002{0}\u0002 is currently not playing.".format(victim))
return
if nick.lower() == victim: # Staying home
vars.HVISITED[nick] = None
cli.msg(nick, "You have chosen to stay home for the night.")
else:
vars.HVISITED[nick] = vars.list_players()[pl.index(victim)]
cli.msg(nick, ("You are spending the night with \u0002{0}\u0002. "+
"Have a good time!").format(victim))
if vars.HVISITED[nick] not in vars.ROLES["wolf"]:
cli.msg(vars.HVISITED[nick], ("You are spending the night with \u0002{0}"+
"\u0002. Have a good time!").format(nick))
chk_nightdone(cli)
@checks @checks
@pmcmd("see", "!see") @pmcmd("see", "!see")
def see(cli, nick, rest): def see(cli, nick, rest):
@ -517,7 +573,7 @@ def see(cli, nick, rest):
cli.msg(nick, "Only a seer may use this command") cli.msg(nick, "Only a seer may use this command")
return return
if vars.PHASE != "night": if vars.PHASE != "night":
cli.msg(nick, "You may have visions at night.") cli.msg(nick, "You may only have visions at night.")
return return
if nick in vars.SEEN: if nick in vars.SEEN:
cli.msg(nick, "You may only have one vision per round.") cli.msg(nick, "You may only have one vision per round.")
@ -566,6 +622,7 @@ def transition_night(cli):
# Reset nighttime variables # Reset nighttime variables
vars.VICTIM = "" # nickname of kill victim vars.VICTIM = "" # nickname of kill victim
vars.SEEN = [] # list of seers that have had visions vars.SEEN = [] # list of seers that have had visions
vars.HVISITED = {}
vars.NIGHT_START_TIME = datetime.now() vars.NIGHT_START_TIME = datetime.now()
daydur_msg = "" daydur_msg = ""
@ -575,7 +632,7 @@ def transition_night(cli):
vars.DAY_START_TIME = None vars.DAY_START_TIME = None
vars.DAY_TIMEDELTA += td vars.DAY_TIMEDELTA += td
min, sec = td.seconds // 60, td.seconds % 60 min, sec = td.seconds // 60, td.seconds % 60
daydur_msg = "Day lasted \u0002{0:0>2}:{1:0>2}. ".format(min,sec) daydur_msg = "Day lasted \u0002{0:0>2}:{1:0>2}\u0002. ".format(min,sec)
chan = botconfig.CHANNEL chan = botconfig.CHANNEL
@ -608,6 +665,15 @@ def transition_night(cli):
'Use "see <nick>" to see the role of a player.')) 'Use "see <nick>" to see the role of a player.'))
cli.msg(seer, "Players: "+", ".join(pl)) cli.msg(seer, "Players: "+", ".join(pl))
for harlot in vars.ROLES["harlot"]:
pl = ps[:]
pl.remove(harlot)
cli.msg(harlot, ('You are a \u0002harlot\u0002. '+
'You may spend the night with one person per round. '+
'If you visit a victim of a wolf, or visit a wolf, '+
'you will die. Use !visit to visit a player.'))
cli.msg(harlot, "Players: "+", ".join(pl))
for d in vars.ROLES["village drunk"]: for d in vars.ROLES["village drunk"]:
cli.msg(d, 'You have been drinking too much! You are the \u0002village drunk\u0002.') cli.msg(d, 'You have been drinking too much! You are the \u0002village drunk\u0002.')

Loading…
Cancel
Save