fix: Update initial button label to a space character to comply with Discord API requirements

This commit is contained in:
Slipstream 2025-05-19 17:33:52 -06:00
parent 5122053a4e
commit 294292b7bc
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD

View File

@ -5,8 +5,9 @@ from typing import Optional, List
# --- Tic Tac Toe (Player vs Player) ---
class TicTacToeButton(ui.Button['TicTacToeView']):
def __init__(self, x: int, y: int):
# Use a blank character for the initial label to avoid large buttons
super().__init__(style=discord.ButtonStyle.secondary, label='', row=y)
# Use a space character for the initial label to avoid large buttons
# Empty string ('') is not allowed as per Discord API requirements
super().__init__(style=discord.ButtonStyle.secondary, label=' ', row=y)
self.x = x
self.y = y
@ -117,7 +118,7 @@ class TicTacToeView(ui.View):
# --- Tic Tac Toe Bot Game ---
class BotTicTacToeButton(ui.Button['BotTicTacToeView']):
def __init__(self, x: int, y: int):
super().__init__(style=discord.ButtonStyle.secondary, label='', row=y)
super().__init__(style=discord.ButtonStyle.secondary, label=' ', row=y)
self.x = x
self.y = y
self.position = y * 3 + x # Convert to position index (0-8) for the TicTacToe engine
@ -125,12 +126,12 @@ class BotTicTacToeButton(ui.Button['BotTicTacToeView']):
async def callback(self, interaction: discord.Interaction):
assert self.view is not None
view: BotTicTacToeView = self.view
# Check if it's the player's turn
if interaction.user != view.player:
await interaction.response.send_message("This is not your game!", ephemeral=True)
return
# Try to make the move in the game engine
try:
view.game.play_turn(self.position)
@ -141,15 +142,15 @@ class BotTicTacToeButton(ui.Button['BotTicTacToeView']):
if view.game.is_game_over():
await view.end_game(interaction)
return
# Now it's the bot's turn - defer without thinking message
await interaction.response.defer()
import asyncio
await asyncio.sleep(1) # Brief pause to simulate bot "thinking"
# Bot makes its move
bot_move = view.game.play_turn() # AI will automatically choose its move
# Update the button for the bot's move
bot_y, bot_x = divmod(bot_move, 3)
for child in view.children:
@ -158,19 +159,19 @@ class BotTicTacToeButton(ui.Button['BotTicTacToeView']):
child.style = discord.ButtonStyle.danger
child.disabled = True
break
# Check if game is over after bot's move
if view.game.is_game_over():
await view.end_game(interaction)
return
# Update the game board for the next player's turn
await interaction.followup.edit_message(
message_id=view.message.id,
content=f"Tic Tac Toe: {view.player.mention} (X) vs Bot (O) - Difficulty: {view.game.ai_difficulty.capitalize()}\n\nYour turn!",
view=view
)
except ValueError as e:
await interaction.response.send_message(f"Error: {str(e)}", ephemeral=True)
@ -185,12 +186,12 @@ class BotTicTacToeView(ui.View):
for y in range(3):
for x in range(3):
self.add_item(BotTicTacToeButton(x, y))
async def disable_all_buttons(self):
for item in self.children:
if isinstance(item, ui.Button):
item.disabled = True
def format_board(self) -> str:
"""Format the game board into a string representation."""
board = self.game.get_board()
@ -202,10 +203,10 @@ class BotTicTacToeView(ui.View):
row = [cell.replace('X', '').replace('O', '') for cell in row]
rows.append(' '.join(row))
return '\n'.join(rows)
async def end_game(self, interaction: discord.Interaction):
await self.disable_all_buttons()
winner = self.game.get_winner()
if winner:
if winner == 'X': # Player wins
@ -214,10 +215,10 @@ class BotTicTacToeView(ui.View):
content = f"The bot ({self.game.ai_difficulty.capitalize()}) wins! Better luck next time."
else:
content = "It's a tie! 🤝"
# Convert the board to a visually appealing format
board_display = self.format_board()
# Update the message
try:
await interaction.followup.edit_message(
@ -232,7 +233,7 @@ class BotTicTacToeView(ui.View):
await self.message.edit(content=f"{content}\n\n{board_display}", view=self)
except: pass
self.stop()
async def on_timeout(self):
if self.message:
await self.disable_all_buttons()