def setGame(self, game: PapGame) -> None: """ Update the database by adding this game or by updating the saved game with this one :param game: a PapGame object with new values """ self._gameCache[game.gameID] = game if self.hasGame(game.gameID, checkCache=False): self.db.makeRequest( # EXPLANATION: delete a game 'UPDATE games SET userIDs = ?, gameData = ?, live = ? WHERE guildID = ? AND gameID = ? AND gameType = ?', # data PapGame.serializeUsers(game.userIDs), PapGame.serializeGameData(game.gameData), game.live, # identification self.guildID, game.gameID, game.gameType) else: self.db.makeRequest( # EXPLANATION: insert a game with all their values 'INSERT INTO games (guildID, gameID, gameType, userIDs, gameData, live) VALUES (?, ?, ?, ?, ?, ?)', # identification self.guildID, game.gameID, game.gameType, # data PapGame.serializeUsers(game.userIDs), PapGame.serializeGameData(game.gameData), game.live) self.db.save()
def getLiveGameForUserForGametype( self, discordID: int, gameType: str, user: Optional[PapUser] = None) -> PapGame: """ Returns a list with all live games that this user is playing :param gameType: the type of the game, use "any" for any type :param discordID: the user to get the games from, put None if use use a PapUser in the user param :param user: ALTERNATIVE: a PapUser :return: list of games """ gameData = self.db.makeUniqueRequest( # EXPLANATION: select the game that is live, from this guild, is of the type gameType, # and include userID in userIDs 'SELECT * FROM games WHERE live = 1 AND guildID = ? AND gameType = ? AND userIDs LIKE ?', self.guildID, gameType, f'%{discordID}%', table='games') # if gameType != 'any' else self.db.makeRequest( # # EXPLANATION: select all games that are live, from this guild and include userID in userIDs # 'SELECT * FROM games WHERE live = 1 AND guildID = ? AND userIDs LIKE ?', # self.guildID, # f'%{discordID}%', # table='games' # ) returnGame = PapGame(**gameData) return returnGame
def getGamesForUser(self, discordID: int, gameType: str = 'any', user: Optional[PapUser] = None) -> List[PapGame]: """ Returns a list with all games that this user has played :param gameType: the type of the game, use "any" for any type :param discordID: the user to get the games from, put None if use use a PapUser in the user param :param user: ALTERNATIVE: a PapUser :return: list of games """ games = [] dbGames: list = self.db.makeRequest( # EXPLANATION: select all games that are from this guild, have the type ?, # and include userID in userIDs 'SELECT * FROM games WHERE guildID = ? AND gameType = ? AND userIDs LIKE ?', self.guildID, gameType, f'%{discordID}%', table='games' ) if gameType != 'any' else self.db.makeRequest( # EXPLANATION: select all games that are from this guild and include userID in userIDs 'SELECT * FROM games WHERE guildID = ? AND userIDs LIKE ?', self.guildID, f'%{discordID}%', table='games') for game in dbGames: if str(discordID) in game['userIDs']: game.pop('guildID') games.append(PapGame(**game)) return games
def parseData(self, data: PapGame): """ If data is passed the init is from this instead of passed args. :param data: :return: """ gameData = PapGame.deserializeGameData(data.gameData) gameID = data.gameID self.gameID = gameID self.player1 = TicTacToePlayer( gameData['player1ID'], Image.open(f'{os.getcwd()}/modules/tic_tac_toe/src/x.png'), 'x') if gameData['player2ID'] == 'AI': self.player2 = TicTacToeAI( 'AI', Image.open(f'{os.getcwd()}/modules/tic_tac_toe/src/o.png'), 'o') else: self.player2 = TicTacToePlayer( gameData['player2ID'], Image.open(f'{os.getcwd()}/modules/tic_tac_toe/src/o.png'), 'o') if gameData['currentTurn'] == gameData['player1ID']: self.turn = self.player1 else: self.turn = self.player2 # else: # self.turn = AI(Image.open(f"{os.getcwd()}\\modules\\tic_tac_toe\\src\\o.png"), "o") self.grid = gameData['grid']
def getGame(self, gameID: str) -> PapGame: """ Returns a PapGame object with the requested ID :param gameID: the ID to search for :return: the PapGame object """ if gameID not in self._gameCache.keys(): # EXPLANATION: select a game with gameID gameID and guildID of this guild gameData: Dict[str, Any] = self.db.makeRequest( 'SELECT * FROM games WHERE guildID = ? AND gameID = ?', self.guildID, gameID, table='games') self._gameCache[gameID] = PapGame(**gameData) return self._gameCache.get(gameID)
async def ttt(server: AbstractServer, msg: Message): try: gameID = gameUtils.getRandomGameID([msg.author.id, msg.mentions[0].id] if msg.mentions else [msg.author.id, 0]) player1 = msg.author player2 = None if not msg.mentions else msg.mentions[0] newGame = TicTacToe(player1=player1, player2=player2, data=None, gameID=gameID) if not msg.mentions: server.GetDatabase().initStatsForUserInGuild(msg.author.id, 'tic tac toe') live = 1 server.GetDatabase().setGame( PapGame( gameID=gameID, gameType='tic tac toe', userIDs=[msg.author.id, msg.mentions[0].id] if msg.mentions else [msg.author.id, 0], gameData=newGame.getData(), live=live ) ) tttContent = f'This game is between {msg.author.mention} and our AI' else: if msg.mentions: server.GetDatabase().make.GameRequest( discordID=msg.author.id, discordID2=msg.mentions[0].id, channelID=msg.channel.id, gameID=gameID, gametype='tic tac toe' ) tttContent = f'This game is between {msg.author.mention} and {msg.mentions[0].mention}.' \ ' Please wait until your opponent accept the game.' tttEmbed = embed( title='New tic tac toe Game.', content=tttContent, color=getColor(random=True) ) await msg.channel.send(embed=tttEmbed) except GameRequestAlreadyLive: await msg.channel.send('GameRequestAlreadyLive')
def getLiveGamesForGuild(self) -> List[PapGame]: """ Returns the list of current games in the guild. :return List of games """ return_list = [] game_list = self.db.makeRequest( 'SELECT * FROM games WHERE guildID = ? AND live = 1', self.guildID) if len(game_list) == 0: raise GameNotFound for game in game_list: return_list.append(PapGame(**game)) return return_list
async def onMessage(server: AbstractServer, msg: Message): database: AbstractGuild = server.GetDatabase() try: acceptObj: Dict[str, Any] = database.getGameRequest(msg.author.id) accepted: bool = None if (acceptObj['channelID'] == msg.channel.id) and ("accept" in msg.content): accepted = True database.delGameRequest(msg.author.id, accepted) elif (acceptObj['channelID'] == msg.channel.id) and ("deny" in msg.content): accepted = False database.delGameRequest(msg.author.id, accepted) if accepted: acceptedEmbed = utils.embed( title="Game accepted. Prepare", content= f"This game is between {msg.author.mention} and his opponent TODO: get actual names, ty", color=utils.getColor(RGB="0,255,0")) await msg.channel.send(embed=acceptedEmbed) game = database.getGamesForUser( msg.author.id, gameType=acceptObj['gameType'])[0] database.setGame( PapGame(gameID=game.gameID, gameType=game.gameType, userIDs=game.userIDs, gameData=game.gameData, live=True)) elif accepted is not None: deniedEmbed = utils.embed(title="Game denied.", content="This game is cancelled.", color=utils.getColor(RGB="255,0,0")) await msg.channel.send(embed=deniedEmbed) except GameRequestNotFound: pass
async def draw(server: AbstractServer, msg: Message): try: gameData: PapGame = server.GetDatabase().getLiveGameForUserForGametype( discordID=msg.author.id, gameType="tic tac toe" ) still_live = True resumeGame = TicTacToe(player1=None, player2=None, data=gameData, gameID=gameData.gameID) resumeGameID = gameData.gameID userIDs = gameData.userIDs if resumeGame.turn.user != msg.author.id: await msg.channel.send("Ehi bud it's not your turn yet") else: params = msg.content.split() pos = params[1] code = resumeGame.makeMove(pos) if code == 3: await msg.channel.send("That position is invalid, try again") elif code == 0: await msg.channel.send("The game is still going on") elif code == 1: await msg.channel.send(f"Congrats {msg.author.mention} you won") for userid in userIDs.split(','): if userid == msg.author.id: server.GetDatabase().saveStatsForUserInGuild( userID=str(userid), loss=True, gameType='tic tac toe') else: server.GetDatabase().saveStatsForUserInGuild( userID=str(userid), win=True, gameType='tic tac toe') still_live = False elif code == 10: await msg.channel.send("Sorry but you lost and our AI WON, ggs") server.GetDatabase().saveStatsForUserInGuild( userID=msg.author.id, loss=True, gameType='tic tac toe') still_live = False elif code == 100: await msg.channel.send("This is a tie") for userid in userIDs.split(','): server.GetDatabase().saveStatsForUserInGuild( userID=str(userid), tie=True, gameType='tic tac toe') still_live = False drawEmbed = embed( title="Tic Tac Toe", content="X: Player1 \tO: Player2", color=getColor(random=True) ) file = File( f'{os.getcwd()}/modules/tic_tac_toe/src/tictactoe_images/{resumeGameID}.png', filename='test.png' ) drawEmbed.set_image(url=f'attachment://test.png') # drawEmbed.add_field(name="game_status", value={'Still live' if still_live else 'Ended'}, inline=False) await msg.channel.send(file=file, embed=drawEmbed) updateGame = PapGame( gameData.gameID, [int(username) for username in (gameData.userIDs.replace(',', ' ').split(' '))], resumeGame.getData(), gameData.gameType, still_live ) server.GetDatabase().setGame( updateGame ) except GameNotFound: await msg.channel.send(f"There is no game for you bud.")