-
Notifications
You must be signed in to change notification settings - Fork 1
[Feature/Games] tic tac toe and higherlower and init #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
…and move towards release
…ipts to use .venv instead of venv
…be accessed if needed
…to refactor/dev-mvp random :qw :wq
…to refactor/dev-mvp
…to refactor/dev-mvp
…to refactor/dev-mvp
…many parameters. Also changed initialization of ticketBase in FeedbackCog, BugReportCog, and FeatureRequestCog (files that use TicketBase)
…to refactor/dev-mvp
…to refactor/dev-mvp
… old add_buttons. Future calls should use buttons: (True, WhatTheOldAddButtonsValueWasSetTo). Additionally refactored error handler cog
Reviewer's GuideImplements two new interactive game cogs—Tic Tac Toe and Higher/Lower—using Discord slash commands and message-based loops with timeouts to handle user input, game state, and result announcements. Sequence diagram for Tic Tac Toe game interactionsequenceDiagram
actor User1
participant Bot
actor User2
User1->>Bot: /tictactoe @User2
Bot->>User1: Validate opponent
Bot->>User1: Send initial board
loop Turns (max 9)
User1->>Bot: Send move (if turn)
User2->>Bot: Send move (if turn)
Bot->>User1: Update board, announce turn/result
Bot->>User2: Update board, announce turn/result
end
Bot->>User1: Announce win/draw/timeout
Bot->>User2: Announce win/draw/timeout
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/capy_app/frontend/cogs/games/tictactoe_cog.py:63` </location>
<code_context>
+ ephemeral=True,
+ )
+
+ def check(msg: discord.Message):
+ return (
+ msg.author == interaction.user
</code_context>
<issue_to_address>
**suggestion:** Message check function does not handle non-integer input gracefully.
Consider providing feedback to users when they send invalid input to enhance user experience.
</issue_to_address>
### Comment 2
<location> `src/capy_app/frontend/cogs/games/higherlower_cog.py:25-29` </location>
<code_context>
+ self, interaction: discord.Interaction, lower_bound: int, upper_bound: int
+ ):
+ """Higher/Lower guessing game."""
+ if lower_bound > upper_bound:
+ await interaction.response.send_message(
+ "❌ Lower bound must be <= upper bound", ephemeral=True
</code_context>
<issue_to_address>
**suggestion:** No check for negative or zero bounds.
Validate that both bounds are positive integers to prevent unexpected game behavior.
```suggestion
if lower_bound <= 0 or upper_bound <= 0:
await interaction.response.send_message(
"❌ Both bounds must be positive integers greater than zero.", ephemeral=True
)
return
if lower_bound > upper_bound:
await interaction.response.send_message(
"❌ Lower bound must be <= upper bound", ephemeral=True
)
return
```
</issue_to_address>
### Comment 3
<location> `src/capy_app/frontend/cogs/games/tictactoe_cog.py:20` </location>
<code_context>
+ name="tictactoe",
+ description="Play Tic Tac Toe against another user",
+ )
+ async def tictactoe(self, interaction: discord.Interaction, opponent: discord.User):
+ """Tic Tac Toe game between two players."""
+ if opponent == interaction.user:
</code_context>
<issue_to_address>
**issue (complexity):** Consider refactoring the game logic into a separate TicTacToeGame class to isolate board management and win/draw checks from Discord I/O.
```markdown
Extract the board‐management and win/draw logic into a separate `TicTacToeGame` class. This collapses your slash command to just “wiring” Discord I/O, and makes the logic fully testable.
– Create a new module `tic_tac_toe.py`:
```python
# tic_tac_toe.py
class TicTacToeGame:
WIN_COMBOS = [
(0,1,2),(3,4,5),(6,7,8), # rows
(0,3,6),(1,4,7),(2,5,8), # cols
(0,4,8),(2,4,6), # diags
]
def __init__(self, players):
self.players = players
self.symbols = ["❌","⭕"]
self.board = [" "] * 9
self.turn = 0
def render(self) -> str:
def cell(i):
return self.board[i] if self.board[i] != " " else f"{i+1}\N{COMBINING ENCLOSING KEYCAP}"
rows = [
f"{cell(0)} | {cell(1)} | {cell(2)}",
f"{cell(3)} | {cell(4)} | {cell(5)}",
f"{cell(6)} | {cell(7)} | {cell(8)}",
]
return "\n----+---+----\n".join(rows)
def make_move(self, pos: int) -> bool:
if 0 <= pos < 9 and self.board[pos] == " ":
self.board[pos] = self.symbols[self.turn]
return True
return False
def is_win(self) -> bool:
sym = self.symbols[self.turn]
return any(all(self.board[i] == sym for i in combo) for combo in self.WIN_COMBOS)
def is_draw(self) -> bool:
return all(cell != " " for cell in self.board)
def switch_turn(self):
self.turn ^= 1
@property
def current_player(self):
return self.players[self.turn]
@property
def current_symbol(self):
return self.symbols[self.turn]
```
– Simplify your slash command:
```python
# in your Cog
from .tic_tac_toe import TicTacToeGame
@app_commands.command(...)
async def tictactoe(self, interaction, opponent: discord.User):
if opponent == interaction.user:
return await interaction.response.send_message("❌ You cannot play yourself", ephemeral=True)
game = TicTacToeGame([interaction.user, opponent])
await interaction.response.send_message(
f"🎮 TicTacToe: {game.players[0].mention} vs {game.players[1].mention}\n"
f"{game.current_player.mention}, it's your turn!\n{game.render()}"
)
def check(msg):
return (
msg.author == game.current_player
and msg.channel == interaction.channel
and msg.content.isdigit()
)
for _ in range(9):
try:
msg = await self.bot.wait_for("message", check=check, timeout=60)
except asyncio.TimeoutError:
return await interaction.followup.send("⌛ Game timed out!")
move = int(msg.content) - 1
if not game.make_move(move):
await msg.reply("Invalid move, try again.")
continue
if game.is_win():
return await interaction.followup.send(f"{game.render()}\n✅ {game.current_player.mention} wins!")
if game.is_draw():
break
game.switch_turn()
await interaction.followup.send(
f"{game.render()}\n{game.current_player.mention}, it's your turn!"
)
await interaction.followup.send(f"{game.render()}\n🤝 It's a draw!")
```
Benefits:
- Slash command is now <50 lines, no inner functions.
- All game logic lives in one class for easy unit‐testing.
- Turn management, rendering, win/draw checks are clear and decoupled from Discord I/O.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| f"{players[turn].mention}, it's your turn!\n{render_board()}" | ||
| ) | ||
|
|
||
| def check(msg: discord.Message): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Message check function does not handle non-integer input gracefully.
Consider providing feedback to users when they send invalid input to enhance user experience.
…to refactor/dev-mvp
…id of the logic for major selection.
a4afdcc to
9c8b082
Compare
…awn promotion, and added move-making logic
Summary by Sourcery
Add two new interactive game commands to the Discord bot
New Features: