1
0
Fork 0
mirror of synced 2024-06-02 10:44:32 +12:00

Fix up shiritori

This commit is contained in:
Dan Hess 2021-03-25 16:52:53 -08:00
parent aebc5dcadb
commit c03e228063

View file

@ -8,13 +8,11 @@ class Games(commands.Cog):
def __init__(self): def __init__(self):
self.running_games = collections.defaultdict(dict) self.running_games = collections.defaultdict(dict)
@commands.guild_only()
@commands.is_owner()
@commands.command(aliases=["word_chain", "しりとり", "シリトリ"]) @commands.command(aliases=["word_chain", "しりとり", "シリトリ"])
@commands.max_concurrency(1, per=commands.BucketType.channel) @commands.max_concurrency(1, per=commands.BucketType.channel)
async def shiritori(self, ctx, *, start_word): async def shiritori(self, ctx, *, word):
""" """
Starts a game of Shiritori, in which the last letter of the last word given Starts or play on a game of Shiritori, in which the last letter of the last word given
has to be the first letter of the next word given. For example, if the word given is has to be the first letter of the next word given. For example, if the word given is
apple, then the next word can be elephant because apple ends in e and elephant begins in e apple, then the next word can be elephant because apple ends in e and elephant begins in e
@ -23,6 +21,18 @@ class Games(commands.Cog):
The word used cannot be a previously given word The word used cannot be a previously given word
""" """
game = self.running_games["shiritori"].get(ctx.channel.id) game = self.running_games["shiritori"].get(ctx.channel.id)
# Ensure only one game is happening at once
if game is not None:
if ctx.author not in game["players"]:
game["players"].append(ctx.author)
else:
self.running_games["shiritori"][ctx.channel.id] = {
"players": [ctx.author],
"words_used": [],
"last_letters": [],
"last_author": ctx.author,
}
game = self.running_games["shiritori"].get(ctx.channel.id)
def grab_letter(readings, last=True): def grab_letter(readings, last=True):
readings = [reversed(word) if last else iter(word) for word in readings] readings = [reversed(word) if last else iter(word) for word in readings]
@ -33,84 +43,50 @@ class Games(commands.Cog):
for char in reading: for char in reading:
if char.isalpha(): if char.isalpha():
letters.append(char) letters.append(char)
break
def check(message): return letters
# Ensure it's in the same channel
if message.channel != ctx.channel:
return False
# Ensure we aren't listening to a bot (like ourselves for example)
elif message.author.bot:
return False
# The last person who gave a message cannot be the next one as well
elif last_author is not None and message.author == last_author:
return False
# If no game is running then how did this even happen!?
elif game is None:
return False
# If the author is not a player
elif message.author not in game["players"]:
return False
# Otherwise we good
else:
return True
# Setup the info needed for the game # Don't allow last author to guess again
message = ctx.message if game["words_used"] and ctx.author == game["last_author"]:
message.content = start_word return await ctx.send("You guessed last, someone else's turn")
last_letters = None is_noun, readings = await utils.readings_for_word(word)
words_used = []
# Ensure only one game is happening at once
if game is not None:
if ctx.author not in game["players"]:
game["players"].append(ctx.author)
await ctx.message.add_reaction("")
else:
await ctx.message.add_reaction("")
else:
self.running_games["shiritori"][ctx.channel.id] = {"players": []}
await ctx.send(
f"Shiritori game started! First word is `{start_word}`, any responses after this"
"count towards the game"
)
while True:
is_noun, readings = await utils.readings_for_word(message.content)
# Only nouns can be used # Only nouns can be used
if not is_noun: if not is_noun:
break self.running_games["shiritori"][ctx.channel.id] = None
return await ctx.send(
f"Game over! {ctx.author} loses, only nouns can be used"
)
# Grab the first letter of this new word and check it # Grab the first letter of this new word and check it
first_letters = grab_letter(readings, last=False) first_letters = grab_letter(readings, last=False)
last_letters = grab_letter(readings, last=False)
# Include extra check for if this is the first word # Include extra check for if this is the first word
if words_used: if game["words_used"]:
# Check if there's a match between first and last letters # Check if there's a match between first and last letters
if not any(char in first_letters for char in last_letters): if not any(char in first_letters for char in game["last_letters"]):
break self.running_games["shiritori"][ctx.channel.id] = None
# Now set the "last" information, to start checking if it's correct return await ctx.send(
last_words = readings f"Game over! {ctx.author} loses, first letter of {word} did not match last letter used"
last_letters = grab_letter(last_words) )
last_author = message.author
# Extra check for the japanese version, ん cannot be used # ん cannot be used
if any(char in last_letters for char in ("", "")): if any(char in last_letters for char in ("", "")):
break self.running_games["shiritori"][ctx.channel.id] = None
# Cannot reuuse words; though make sure this doesn't get caught on the very first usage return await ctx.send(
if any(word in words_used for word in last_words) and len(words_used) >= 1: f"Game over! {ctx.author} loses, last letter cannot be ん"
break )
# Cannot reuuse words
if word in game["words_used"]:
self.running_games["shiritori"][ctx.channel.id] = None
return await ctx.send(
f"Game over! {ctx.author} loses, {word} has already been used"
)
# If we're here, then the last letter used was valid # If we're here, then the last letter used was valid, save stuff
words_used.extend(last_words) game["words_used"].append(word)
await message.add_reaction("") game["last_letters"] = last_letters
message = await ctx.bot.wait_for("message", check=check) game["last_author"] = ctx.author
await ctx.message.add_reaction("")
# If we're here, game over, someone messed up
self.running_games["shiritori"][ctx.channel.id] = False
await message.add_reaction("")
if any(char in last_letters for char in ("", "")):
await ctx.send("Wrong! ん cannot be used as the last kana!")
else:
await ctx.send(f"Wrong! {message.author.mention} is a loser!")
def setup(bot): def setup(bot):