Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.55 KB | None | 0 0
  1. """Connect Four
  2. Written for Python 3.6 and discord.py 1.0.0a"""
  3.  
  4. import discord
  5. from discord.ext import commands
  6. from .utils import checks
  7.  
  8.  
  9. class Session:
  10. """Active Session of Connect Four"""
  11. def __init__(self, p1, p2, chan):
  12. self.p1 = p1 # These will be discord.Member objects of players
  13. self.p2 = p2 # `p1` being ctx.author and `p2 being the ping
  14. self.chan = chan
  15. self.board = [[0 for x in range(7)] for y in range(7)]
  16. self.turn = 0
  17. self.msg = None
  18. self.emojis = {
  19. "0": "⚪", # :white_circle:
  20. str(self.p1.id): "🔴", # :red_circle:
  21. str(self.p2.id): "🔵", # :large_blue_circle:
  22. }
  23.  
  24. @property
  25. def current_player(self):
  26. if self.turn % 2 == 1:
  27. return self.p1
  28. else:
  29. return self.p2
  30.  
  31. @property
  32. def current_player_chip(self):
  33. return self.emojis.get(str(self.current_player.id), "0")
  34.  
  35. def play(self, player, row):
  36. self.board[row][self.board[row][-1]] = player
  37. self.board[row][-1] += 1
  38. self.turn += 1
  39. return self.check()
  40.  
  41. @property
  42. def get_board(self):
  43. board = []
  44. for row in self.board:
  45. board.append([self.emojis[str(i)] for i in row[:-1]][::-1])
  46.  
  47. return board
  48.  
  49. def check(self):
  50. return False
  51.  
  52.  
  53. class ConnectFour:
  54. """Play a game of Connect Four"""
  55. def __init__(self, bot):
  56. self.bot = bot
  57. self.sessions = {}
  58.  
  59. def session(self, ctx):
  60. return self.sessions.get(ctx.channel.id, None)
  61.  
  62. async def invalid_session(self, ctx):
  63. await ctx.send("No active game in this channel.")
  64.  
  65. async def send_board(self, ctx, init=False, win=False):
  66. session = self.session(ctx)
  67. if session.msg is not None:
  68. try:
  69. await session.msg.delete()
  70. except Exception as e:
  71. await ctx.send(f"{type(e)}: {e}")
  72.  
  73. board = session.get_board
  74. parsed_board = "\n".join(["{}{}{}{}{}{}{}".format(*[board[y][x] for y in range(7)]) for x in range(6)])
  75.  
  76. turn = "New game" if init else f"Turn: {(session.turn + 2) // 2}"
  77.  
  78. em = discord.Embed(title=f"{session.p1.name} vs. {session.p2.name}",
  79. description=f"{turn}\n\n:one::two::three::four::five::six::seven:\n{parsed_board}",
  80. color=session.current_player.color)
  81.  
  82. if win:
  83. em.set_footer(text=f"{win.mention} wins!")
  84. self.sessions.pop(ctx.channel.id)
  85. await ctx.send(embed=em)
  86. else:
  87. em.set_footer(text=f"{session.current_player.name}'s turn: {session.current_player_chip}")
  88. session.msg = await ctx.send(embed=em)
  89.  
  90. @commands.group()
  91. async def c4(self, ctx):
  92. """Connect Four
  93.  
  94. The classic game of Connect Four.
  95. Use these commands to play a game
  96. of Connect Four with another user.
  97. You can have multiple concurrent
  98. games, one per channel."""
  99. if not ctx.invoked_subcommand:
  100. await self.bot.formatter.format_help_for(ctx, ctx.command)
  101.  
  102. @c4.command(name="start", aliases=["play"])
  103. async def _start(self, ctx, *, user: discord.Member=None):
  104. """Star a game of Connect Four
  105.  
  106. `[p]c4 start @user` will start a game
  107. with that user in the current channel."""
  108. # if user:
  109. # await ctx.send(f"Ping! Confirmed user: {user.name} (Currently not implemented)")
  110. if user:
  111. session = self.session(ctx)
  112. if session:
  113. await ctx.send("There is already an active game in this channel.")
  114. else:
  115. self.sessions[ctx.channel.id] = Session(ctx.author, user, ctx.channel)
  116. await self.send_board(ctx)
  117. else:
  118. await self.bot.formatter.format_help_for(ctx, ctx.command, "You need another player to start.")
  119.  
  120. @c4.command(name="quit", aliases=["end"])
  121. async def _quit(self, ctx):
  122. """Quits an active game of Connect Four
  123.  
  124. `[p]c4 quit` can be used by either player
  125. to quit their game in the channel."""
  126. session = self.sessions.get(ctx.channel.id, None)
  127. if session and ctx.author in [session.p1, session.p2]:
  128. self.sessions.pop(ctx.channel.id)
  129. await ctx.send("Game has ended.")
  130. else:
  131. await self.invalid_session(ctx)
  132.  
  133. @checks.sudo()
  134. @c4.command(name="kill", aliases=["killall"])
  135. async def _kill(self, ctx):
  136. """Aministrative kill command
  137.  
  138. This will kill all running games of
  139. Connect Four in all channels."""
  140. sessions = len(self.sessions.keys())
  141. self.sessions = {}
  142. await ctx.send(f"All running games have been terminated. (Total: {sessions})")
  143.  
  144. @c4.command(name="move")
  145. async def _move(self, ctx, row: int):
  146. """Make a Move
  147.  
  148. `[p]c4 move <row>` will place a chip
  149. in that row. Only the current player
  150. can use this command."""
  151. row -= 1
  152. session = self.session(ctx)
  153. if session:
  154. if ctx.author == session.current_player:
  155. if row in range(7):
  156. if session.board[row][-1] < 6:
  157. check = session.play(ctx.author.id, row)
  158. await self.send_board(ctx, win=check)
  159. else:
  160. await ctx.send("That row is full. Select another.")
  161. else:
  162. await ctx.send("Invalid row number. Select another.")
  163. else:
  164. await self.invalid_session(ctx)
  165.  
  166.  
  167. def setup(bot):
  168. bot.add_cog(ConnectFour(bot))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement