Skip to content

Instantly share code, notes, and snippets.

@crazygmr101
Last active June 8, 2020 00:37
Show Gist options
  • Select an option

  • Save crazygmr101/72080be3445c5c6dd8c474c17ac1d8c5 to your computer and use it in GitHub Desktop.

Select an option

Save crazygmr101/72080be3445c5c6dd8c474c17ac1d8c5 to your computer and use it in GitHub Desktop.
# asking for a yes/no user confirmation for deleting something
# NOTE: if the user cancels, this function returns None, *NOT* the user's response
await ctx.send("Type yes to delete the file and no to cancel")
confirmation = _input(ctx, str, cancel_str="no", ch=lambda x: x.lower() in ("yes", "no"),
err="Input yes or no", del_err=60, del_response=True)
# this will return None or "yes"
if not confirmation:
# the user canceled, so _input returned None
# do stuff here
@commands.command()
async def rps(self, ctx: commands.Context):
"""
Play rock-paper-scissors with the bot
"""
def point(a: str, b: str):
a, b = a[0], b[0]
return {
"rr": 0,
"pp": 0,
"ss": 0,
"rp": 1,
"pr": -1,
"sp": -1,
"ps": 1,
"sr": 1,
"rs": -1
}[a + b]
conv = {
"r": "Rock",
"p": "Paper",
"s": "Scissors"
}
win = ["You got a point!", "It's a tie!", "I got a point!"]
final = ["You win!", "It's a tie!", "I win."]
if not await _check_channel(ctx): return
await ctx.send("How many rounds? 1-10")
rounds = await self._input(ctx, int, "cancel", lambda x: 0 < x <= 10)
user = 0
comp = 0
for i in range(0, rounds):
await ctx.send(f"Round {i + 1} - You: {user} | Me: {comp}\n"
f"Input R P or S")
#
# _input is used here, getting a str, and making sure the first letter is either r, p, or s
#
choice = (await self._input(ctx, str, "cancel", lambda x: x[0].lower() in ["r", "p", "s"]))[0]
if not choice: break
compch = random.choice(["r", "p", "s"])
dev = point(choice, compch)
if dev == 1: comp += 1
if dev == -1: user += 1
await ctx.send(f"{win[dev + 1]} I got {conv[compch]}, and you got {conv[choice]}")
await ctx.send(f"Game over\n{final[1 if comp == user else 2 if comp > user else 0]} - You: {user} | Me: {comp}")
@commands.command(aliases=["ttt"])
@commands.max_concurrency(1, commands.BucketType.channel)
async def tictactoe(self, ctx: commands.Context):
if ctx.channel.id in self.locked:
raise commands.MaxConcurrencyReached(1, commands.BucketType.channel)
self.locked.append(ctx.channel.id)
board = [[0] * 3 for _ in range(3)]
_ne = _num_emoji
def _c(x: int) -> Tuple[int, int]:
return (x - 1) // 3, (x - 1) % 3
def _xo(num, neg=False):
return [":x:", None, ":o:"][num + 1] if not neg else \
[":regional_indicator_x:", None, ":regional_indicator_o:"][num + 1]
def _get_board():
s = "_ _\n"
for i in range(1, 10):
row, col = _c(i)
cur = board[row][col]
s += (_xo(cur) if cur else _ne(i))
if col == 2: s += "\n"
return s
def _status():
wins = [
[4, 5, 6],
[1, 2, 3],
[7, 8, 9],
[8, 5, 2],
[9, 6, 3],
[7, 5, 3],
[9, 5, 1],
[7, 4, 1]
]
for i in [-1, 1]:
for row in wins:
if all([board[_c(j)[0]][_c(j)[1]] == i for j in row]):
return i, row
for row in board:
for col in row:
if col == 0:
return 0, []
return 2, []
def _make_next():
# make winning move
for i in range(1, 10):
orig = board[_c(i)[0]][_c(i)[1]]
if orig != 0:
continue
board[_c(i)[0]][_c(i)[1]] = -1
if _status()[0] == -1:
board[_c(i)[0]][_c(i)[1]] = -1
return
board[_c(i)[0]][_c(i)[1]] = orig
# block player's winning move
for i in range(1, 10):
orig = board[_c(i)[0]][_c(i)[1]]
if orig != 0:
continue
board[_c(i)[0]][_c(i)[1]] = 1
if _status()[0] == 1:
board[_c(i)[0]][_c(i)[1]] = -1
return
board[_c(i)[0]][_c(i)[1]] = orig
# pick a random square
sq = random.choice(list(filter(lambda i: board[_c(i)[0]][_c(i)[1]] == 0, list(range(0, 9)))))
board[_c(sq)[0]][_c(sq)[1]] = -1
comp = (random.random() > 0.5)
msg = await ctx.send(embed=discord.Embed(title="Type 1-9",
description=_get_board()))
while True:
if not comp:
await msg.edit(embed=discord.Embed(title=f"Your turn!",
description=_get_board(), colour=discord.Colour.blue()))
#
# input is used here
# we're asking for an `int`
# the check in this case, is that 0<x<10 (the response is 1-9 inclusive)
# and that the square on the board is open
# the user's response here is deleted so the tic tac toe board doesnt move up in the chat
#
sq = await self._input(ctx, int, ch=lambda x: (0 < x < 10) and board[_c(x)[0]][_c(x)[1]] == 0,
del_response=True)
board[_c(sq)[0]][_c(sq)[1]] = 1
if _status()[0] != 0: break
else:
await msg.edit(embed=discord.Embed(title=f"My turn!",
description=_get_board(), colour=discord.Colour.gold()))
async with ctx.typing():
await asyncio.sleep(1)
_make_next()
if _status()[0] != 0: break
comp = not comp
winner, win = _status()
s = "_ _\n"
for i in range(1, 10):
row, col = _c(i)
cur = board[row][col]
s += (_xo(cur, neg=(i in win)) if cur else ":black_large_square:")
if col == 2: s += "\n"
if winner == 1:
title = "You win!"
color = discord.Colour.green()
elif winner == -1:
title = "You Lose ):"
color = discord.Colour.red()
else:
title = "It's a tie"
color = discord.Colour.purple()
await msg.edit(embed=discord.Embed(title=title,
description=s, colour=color))
del self.locked[self.locked.index(ctx.channel.id)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment