From 1748f0c57b746a4a31e7ed9ee12756d4820a6c60 Mon Sep 17 00:00:00 2001 From: Dragon Fire Date: Sat, 23 Jan 2021 21:58:26 -0500 Subject: [PATCH] Allow saving chess games --- commands/games-mp/chess-delete.js | 20 ++++++++++ commands/games-mp/chess.js | 61 +++++++++++++++++++++++++++++-- package.json | 2 +- 3 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 commands/games-mp/chess-delete.js diff --git a/commands/games-mp/chess-delete.js b/commands/games-mp/chess-delete.js new file mode 100644 index 00000000..25109f9b --- /dev/null +++ b/commands/games-mp/chess-delete.js @@ -0,0 +1,20 @@ +const Command = require('../../structures/Command'); + +module.exports = class ChessDeleteCommand extends Command { + constructor(client) { + super(client, { + name: 'chess-delete', + aliases: ['delete-chess', 'chess-del', 'del-chess'], + group: 'games-mp', + memberName: 'chess-delete', + description: 'Deletes your saved Chess game.' + }); + } + + async run(msg) { + const data = await this.client.redis.exists(`chess-${msg.author.id}`); + if (!data) return msg.reply('You do not have a saved Chess game.'); + await this.client.redis.del(`chess-${msg.author.id}`); + return msg.say('Your saved game has been deleted.'); + } +}; diff --git a/commands/games-mp/chess.js b/commands/games-mp/chess.js index f11b0186..79930521 100644 --- a/commands/games-mp/chess.js +++ b/commands/games-mp/chess.js @@ -59,13 +59,33 @@ module.exports = class ChessCommand extends Command { return msg.say('Looks like they declined...'); } } - const game = new jsChess.Game(); - let prevPieces = null; + const resumeGame = await this.client.redis.get(`chess-${msg.author.id}`); + let game; let whiteTime = 900000; let blackTime = 900000; + let whitePlayer = msg.author; + let blackPlayer = opponent; + if (resumeGame) { + await msg.reply('You have a saved game, do you want to resume it?'); + const verification = await verify(msg.channel, opponent); + if (verification) { + const data = JSON.parse(resumeGame); + game = new jsChess.Game(resumeGame.fen); + whiteTime = data.whiteTime; + blackTime = data.blackTime; + whitePlayer = data.playerColor === 'white' ? msg.author : opponent; + blackPlayer = data.playerColor === 'black' ? msg.author : opponent; + } else { + game = new jsChess.Game(); + } + } else { + game = new jsChess.Game(); + } + let prevPieces = null; + let saved = false; while (!game.exportJson().checkMate) { const gameState = game.exportJson(); - const user = gameState.turn === 'black' ? opponent : msg.author; + const user = gameState.turn === 'black' ? blackPlayer : whitePlayer; const time = gameState.turn === 'black' ? blackTime : whiteTime; if (user.bot) { prevPieces = Object.assign({}, game.exportJson().pieces); @@ -77,6 +97,7 @@ module.exports = class ChessCommand extends Command { } else { await msg.say(stripIndents` ${user}, what move do you want to make (ex. A1A2)? Type \`end\` to forfeit. + You can save your game by typing \`save\`. _You are ${gameState.check ? '**in check!**' : 'not in check.'}_ **Time Remaining: ${moment.duration(time).format()}** @@ -87,6 +108,7 @@ module.exports = class ChessCommand extends Command { if (![msg.author.id, opponent.id].includes(res.author.id)) return false; const choice = res.content.toUpperCase(); if (choice === 'END') return true; + if (choice === 'SAVE') return true; if (res.author.id !== user.id) return false; const move = choice.match(turnRegex); if (!move) return false; @@ -106,6 +128,21 @@ module.exports = class ChessCommand extends Command { return msg.say(`${user.id === msg.author.id ? opponent : msg.author} wins from timeout!`); } if (turn.first().content.toLowerCase() === 'end') break; + if (turn.first().content.toLowerCase() === 'save') { + const author = turn.first().author; + const alreadySaved = await this.client.redis.get(`chess-${author.id}`); + if (alreadySaved) { + await msg.say('You already have a saved game, do you want to overwrite it?'); + const verification = await verify(msg.channel, author); + if (!verification) continue; + } + await this.client.redis.set( + `chess-${author.id}`, + this.exportGame(game, blackTime, whiteTime, whitePlayer.id === author.id ? 'white' : 'black') + ); + saved = true; + break; + } const timeTaken = new Date() - now; if (gameState.turn === 'black') blackTime -= timeTaken - 5000; if (gameState.turn === 'white') whiteTime -= timeTaken - 5000; @@ -114,9 +151,16 @@ module.exports = class ChessCommand extends Command { } } this.client.games.delete(msg.channel.id); + if (saved) { + return msg.say(stripIndents` + Game saved! Use ${this.usage(opponent.tag)} to resume it. + You do not have to use the same opponent to resume the game. + If you want to delete your saved game, use ${this.client.registry.commands.get('chess-delete').usage()}. + `); + } const gameState = game.exportJson(); if (!gameState.checkMate) return msg.say('Game ended due to forfeit.'); - const winner = gameState.turn === 'black' ? msg.author : opponent; + const winner = gameState.turn === 'black' ? whitePlayer : blackPlayer; return msg.say(`Checkmate! Congrats, ${winner}!`, { files: [{ attachment: this.displayBoard(gameState), name: 'chess.png' }] }); @@ -230,4 +274,13 @@ module.exports = class ChessCommand extends Command { } return { name, color }; } + + exportGame(game, blackTime, whiteTime, playerColor) { + return JSON.stringify({ + fen: game.exportFEN(), + blackTime, + whiteTime, + color: playerColor + }); + } }; diff --git a/package.json b/package.json index b5388b3c..57db231c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "126.12.0", + "version": "126.12.1", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {