forked from Pycord-Development/pycord
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from discord.ext import commands | ||
|
||
import discord | ||
|
||
|
||
class Bot(commands.Bot): | ||
def __init__(self): | ||
super().__init__(command_prefix=commands.when_mentioned_or('$')) | ||
|
||
async def on_ready(self): | ||
print(f'Logged in as {self.user} (ID: {self.user.id})') | ||
print('------') | ||
|
||
|
||
# Define a simple View that gives us a confirmation menu | ||
class Confirm(discord.ui.View): | ||
def __init__(self): | ||
super().__init__() | ||
self.value = None | ||
|
||
# When the confirm button is pressed, set the inner value to `True` and | ||
# stop the View from listening to more input. | ||
# We also send the user an ephemeral message that we're confirming their choice. | ||
@discord.ui.button(label='Confirm', style=discord.ButtonStyle.green) | ||
async def confirm(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
await interaction.response.send_message('Confirming', ephemeral=True) | ||
self.value = True | ||
self.stop() | ||
|
||
# This one is similar to the confirmation button except sets the inner value to `False` | ||
@discord.ui.button(label='Cancel', style=discord.ButtonStyle.grey) | ||
async def cancel(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
await interaction.response.send_message('Cancelling', ephemeral=True) | ||
self.value = False | ||
self.stop() | ||
|
||
|
||
bot = Bot() | ||
|
||
|
||
@bot.command() | ||
async def ask(ctx: commands.Context): | ||
"""Asks the user a question to confirm something.""" | ||
# We create the view and assign it to a variable so we can wait for it later. | ||
view = Confirm() | ||
await ctx.send('Do you want to continue?', view=view) | ||
# Wait for the View to stop listening for input... | ||
await view.wait() | ||
if view.value is None: | ||
print('Timed out...') | ||
elif view.value: | ||
print('Confirmed...') | ||
else: | ||
print('Cancelled...') | ||
|
||
|
||
bot.run('token') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from discord.ext import commands | ||
|
||
import discord | ||
|
||
|
||
class CounterBot(commands.Bot): | ||
def __init__(self): | ||
super().__init__(command_prefix=commands.when_mentioned_or('$')) | ||
|
||
async def on_ready(self): | ||
print(f'Logged in as {self.user} (ID: {self.user.id})') | ||
print('------') | ||
|
||
|
||
# Define a simple View that gives us a counter button | ||
class Counter(discord.ui.View): | ||
|
||
# Define the actual button | ||
# When pressed, this increments the number displayed until it hits 5. | ||
# When it hits 5, the counter button is disabled and it turns green. | ||
# note: The name of the function does not matter to the library | ||
@discord.ui.button(label='0', style=discord.ButtonStyle.red) | ||
async def count(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
number = int(button.label) if button.label else 0 | ||
if number + 1 >= 5: | ||
button.style = discord.ButtonStyle.green | ||
button.disabled = True | ||
button.label = str(number + 1) | ||
|
||
# Make sure to update the message with our updated selves | ||
await interaction.response.edit_message(view=self) | ||
|
||
|
||
bot = CounterBot() | ||
|
||
|
||
@bot.command() | ||
async def counter(ctx: commands.Context): | ||
"""Starts a counter for pressing.""" | ||
await ctx.send('Press!', view=Counter()) | ||
|
||
|
||
bot.run('token') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from discord.ext import commands | ||
|
||
import discord | ||
|
||
class EphemeralCounterBot(commands.Bot): | ||
def __init__(self): | ||
super().__init__(command_prefix=commands.when_mentioned_or('$')) | ||
|
||
async def on_ready(self): | ||
print(f'Logged in as {self.user} (ID: {self.user.id})') | ||
print('------') | ||
|
||
# Define a simple View that gives us a counter button | ||
class Counter(discord.ui.View): | ||
|
||
# Define the actual button | ||
# When pressed, this increments the number displayed until it hits 5. | ||
# When it hits 5, the counter button is disabled and it turns green. | ||
# note: The name of the function does not matter to the library | ||
@discord.ui.button(label='0', style=discord.ButtonStyle.red) | ||
async def count(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
number = int(button.label) if button.label else 0 | ||
if number + 1 >= 5: | ||
button.style = discord.ButtonStyle.green | ||
button.disabled = True | ||
button.label = str(number + 1) | ||
|
||
# Make sure to update the message with our updated selves | ||
await interaction.response.edit_message(view=self) | ||
|
||
# Define a View that will give us our own personal counter button | ||
class EphemeralCounter(discord.ui.View): | ||
# When this button is pressed, it will respond with a Counter view that will | ||
# give the button presser their own personal button they can press 5 times. | ||
@discord.ui.button(label='Click', style=discord.ButtonStyle.blurple) | ||
async def receive(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
# ephemeral=True makes the message hidden from everyone except the button presser | ||
await interaction.response.send_message('Enjoy!', view=Counter(), ephemeral=True) | ||
|
||
bot = EphemeralCounterBot() | ||
|
||
@bot.command() | ||
async def counter(ctx: commands.Context): | ||
"""Starts a counter for pressing.""" | ||
await ctx.send('Press!', view=EphemeralCounter()) | ||
|
||
bot.run('token') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from discord.ext import commands | ||
import discord | ||
|
||
|
||
class PersistentViewBot(commands.Bot): | ||
def __init__(self): | ||
super().__init__(command_prefix=commands.when_mentioned_or('$')) | ||
|
||
async def on_ready(self): | ||
print(f'Logged in as {self.user} (ID: {self.user.id})') | ||
print('------') | ||
|
||
|
||
# Define a simple View that persists between bot restarts | ||
# In order a view to persist between restarts it needs to meet the following conditions: | ||
# 1) The timeout of the View has to be set to None | ||
# 2) Every item in the View has to have a custom_id set | ||
# It is recommended that the custom_id be sufficiently unique to | ||
# prevent conflicts with other buttons the bot sends. | ||
# For this example the custom_id is prefixed with the name of the bot. | ||
# Note that custom_ids can only be up to 100 characters long. | ||
class PersistentView(discord.ui.View): | ||
def __init__(self): | ||
super().__init__(timeout=None) | ||
|
||
@discord.ui.button(label='Green', style=discord.ButtonStyle.green, custom_id='persistent_view:green') | ||
async def green(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
await interaction.response.send_message('This is green.', ephemeral=True) | ||
|
||
@discord.ui.button(label='Red', style=discord.ButtonStyle.red, custom_id='persistent_view:red') | ||
async def red(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
await interaction.response.send_message('This is red.', ephemeral=True) | ||
|
||
@discord.ui.button(label='Grey', style=discord.ButtonStyle.grey, custom_id='persistent_view:grey') | ||
async def grey(self, button: discord.ui.Button, interaction: discord.Interaction): | ||
await interaction.response.send_message('This is grey.', ephemeral=True) | ||
|
||
|
||
bot = PersistentViewBot() | ||
|
||
# Register the persistent view for listening | ||
# Note that this does not send the view to any message. | ||
# In order to do this you need to first send a message with the View, which is shown below. | ||
# If you have the message_id you can also pass it as a keyword argument, but for this example | ||
# we don't have one. | ||
bot.add_view(PersistentView()) | ||
|
||
|
||
@bot.command() | ||
@commands.is_owner() | ||
async def prepare(ctx: commands.Context): | ||
"""Starts a persistent view.""" | ||
# In order for a persistent view to be listened to, it needs to be sent to an actual message. | ||
# Call this method once just to store it somewhere. | ||
# In a more complicated program you might fetch the message_id from a database for use later. | ||
# However this is outside of the scope of this simple example. | ||
await ctx.send("What's your favourite colour?", view=PersistentView()) | ||
|
||
|
||
bot.run('token') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
from typing import List | ||
from discord.ext import commands | ||
import discord | ||
|
||
# Defines a custom button that contains the logic of the game. | ||
# The ['TicTacToe'] bit is for type hinting purposes to tell your IDE or linter | ||
# what the type of `self.view` is. It is not required. | ||
class TicTacToeButton(discord.ui.Button['TicTacToe']): | ||
def __init__(self, x: int, y: int): | ||
# A label is required, but we don't need one so a zero-width space is used | ||
# The row parameter tells the View which row to place the button under. | ||
# A View can only contain up to 5 rows -- each row can only have 5 buttons. | ||
# Since a Tic Tac Toe grid is 3x3 that means we have 3 rows and 3 columns. | ||
super().__init__(style=discord.ButtonStyle.secondary, label='\u200b', row=y) | ||
self.x = x | ||
self.y = y | ||
|
||
# This function is called whenever this particular button is pressed | ||
# This is part of the "meat" of the game logic | ||
async def callback(self, interaction: discord.Interaction): | ||
assert self.view is not None | ||
view: TicTacToe = self.view | ||
state = view.board[self.y][self.x] | ||
if state in (view.X, view.O): | ||
return | ||
|
||
if view.current_player == view.X: | ||
self.style = discord.ButtonStyle.danger | ||
self.label = 'X' | ||
self.disabled = True | ||
view.board[self.y][self.x] = view.X | ||
view.current_player = view.O | ||
content = "It is now O's turn" | ||
else: | ||
self.style = discord.ButtonStyle.success | ||
self.label = 'O' | ||
self.disabled = True | ||
view.board[self.y][self.x] = view.O | ||
view.current_player = view.X | ||
content = "It is now X's turn" | ||
|
||
winner = view.check_board_winner() | ||
if winner is not None: | ||
if winner == view.X: | ||
content = 'X won!' | ||
elif winner == view.O: | ||
content = 'O won!' | ||
else: | ||
content = "It's a tie!" | ||
|
||
for child in view.children: | ||
child.disabled = True | ||
|
||
view.stop() | ||
|
||
await interaction.response.edit_message(content=content, view=view) | ||
|
||
|
||
# This is our actual board View | ||
class TicTacToe(discord.ui.View): | ||
# This tells the IDE or linter that all our children will be TicTacToeButtons | ||
# This is not required | ||
children: List[TicTacToeButton] | ||
X = -1 | ||
O = 1 | ||
Tie = 2 | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.current_player = self.X | ||
self.board = [ | ||
[0, 0, 0], | ||
[0, 0, 0], | ||
[0, 0, 0], | ||
] | ||
|
||
# Our board is made up of 3 by 3 TicTacToeButtons | ||
# The TicTacToeButton maintains the callbacks and helps steer | ||
# the actual game. | ||
for x in range(3): | ||
for y in range(3): | ||
self.add_item(TicTacToeButton(x, y)) | ||
|
||
# This method checks for the board winner -- it is used by the TicTacToeButton | ||
def check_board_winner(self): | ||
for across in self.board: | ||
value = sum(across) | ||
if value == 3: | ||
return self.O | ||
elif value == -3: | ||
return self.X | ||
|
||
# Check vertical | ||
for line in range(3): | ||
value = self.board[0][line] + self.board[1][line] + self.board[2][line] | ||
if value == 3: | ||
return self.O | ||
elif value == -3: | ||
return self.X | ||
|
||
# Check diagonals | ||
diag = self.board[0][2] + self.board[1][1] + self.board[2][0] | ||
if diag == 3: | ||
return self.O | ||
elif diag == -3: | ||
return self.X | ||
|
||
diag = self.board[0][0] + self.board[1][1] + self.board[2][2] | ||
if diag == 3: | ||
return self.O | ||
elif diag == -3: | ||
return self.X | ||
|
||
# If we're here, we need to check if a tie was made | ||
if all(i != 0 for row in self.board for i in row): | ||
return self.Tie | ||
|
||
return None | ||
|
||
|
||
class TicTacToeBot(commands.Bot): | ||
def __init__(self): | ||
super().__init__(command_prefix=commands.when_mentioned_or('$')) | ||
|
||
async def on_ready(self): | ||
print(f'Logged in as {self.user} (ID: {self.user.id})') | ||
print('------') | ||
|
||
|
||
bot = TicTacToeBot() | ||
|
||
|
||
@bot.command() | ||
async def tic(ctx: commands.Context): | ||
"""Starts a tic-tac-toe game with yourself.""" | ||
await ctx.send('Tic Tac Toe: X goes first', view=TicTacToe()) | ||
|
||
|
||
bot.run('token') |