From 6428c01e6c2db14ddf1c6101703ee6239dd8cb31 Mon Sep 17 00:00:00 2001 From: Niels Simenon Date: Mon, 24 Oct 2022 01:55:30 +0200 Subject: [PATCH] Added Rock, Paper, Scissors. --- config/default.js | 3 +- src/games/dice.js | 7 ++-- src/games/kill.js | 2 +- src/games/rock-paper-scissors.js | 72 ++++++++++++++++++++++++++++++++ src/games/say.js | 2 +- src/irc.js | 4 +- src/play.js | 2 +- src/utils/get-leaders.js | 2 +- 8 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 src/games/rock-paper-scissors.js diff --git a/config/default.js b/config/default.js index 1fa05ed..4b343ea 100644 --- a/config/default.js +++ b/config/default.js @@ -4,7 +4,6 @@ module.exports = { platform: 'schat', user: { id: 'aisha', - nick: 'aisha', username: 'Aisha', realName: 'Aisha', }, @@ -22,7 +21,7 @@ module.exports = { greeting: 'Hi, I am aisha, your game host!', usernamePrefix: '@', channels: ['GamesNight'], - games: ['mash', 'trivia', 'letters', 'duck', 'dice', 'ping', 'say', 'kill', 'uptime', 'help'], + games: ['mash', 'trivia', 'letters', 'duck', 'dice', 'rock-paper-scissors', 'ping', 'say', 'kill', 'uptime', 'help'], schatColors: { red: 'red', orange: 'orange', diff --git a/src/games/dice.js b/src/games/dice.js index a5dd0fa..33ce346 100644 --- a/src/games/dice.js +++ b/src/games/dice.js @@ -16,8 +16,8 @@ function onCommand(args, context) { return; } - if (rolls > config.dice.maxFaces) { - context.sendMessage(`Your dice can have at most ${config.dice.maxFace} faces`, context.room.id); + if (faces > config.dice.maxFaces) { + context.sendMessage(`Your dice can have at most ${config.dice.maxFaces} faces`, context.room.id); return; } @@ -28,10 +28,11 @@ function onCommand(args, context) { return `${style.grey(dieFaces[result - 1] || '☐')} ${style.bold(result)}`; // eslint-disable-line no-irregular-whitespace }); - context.sendMessage(results.join(' | '), context.room.id); + context.sendMessage(results.join(style.grey(' | ')), context.room.id); } module.exports = { onCommand, commands: ['dice', 'die', 'roll'], + help: 'What\'s your next move? Try ~dice [rolls] [faces], ~die or ~roll', }; diff --git a/src/games/kill.js b/src/games/kill.js index 6c880b3..61e5674 100644 --- a/src/games/kill.js +++ b/src/games/kill.js @@ -7,7 +7,7 @@ function onCommand(args, context) { context.sendMessage('Shutting down... :sleeping:', context.room?.id, { type: 'message', label: false }, context.message.user?.username); } - if (config.platform === 'irc' && context.room.id === config.user.nick) { + if (config.platform === 'irc' && context.room.id === config.user.id) { // if the room ID is the bot's own nickname, it's a PM and we should reply to the sender context.sendMessage('Shutting down... 😴', context.user.id, { label: false }); } else if (config.platform === 'irc') { diff --git a/src/games/rock-paper-scissors.js b/src/games/rock-paper-scissors.js new file mode 100644 index 0000000..c275686 --- /dev/null +++ b/src/games/rock-paper-scissors.js @@ -0,0 +1,72 @@ +'use strict'; + +const config = require('config'); +const crypto = require('crypto'); +const timers = require('timers/promises'); + +const style = require('../utils/style'); + +const wins = { + rock: 'scissors', + paper: 'rock', + scissors: 'paper', +}; + +const emojis = { + rock: '🪨', + paper: '📄', + scissors: '✂️', +}; + +async function play(context, hand) { + const counter = Object.keys(wins)[crypto.randomInt(0, 3)]; + + const userWins = wins[hand] === counter; + const botWins = wins[counter] === hand; + + await timers.setTimeout(500); + context.sendMessage(`${emojis.rock} Rock!`, context.room.id); + await timers.setTimeout(500); + context.sendMessage(`${emojis.paper} Paper!`, context.room.id); + await timers.setTimeout(500); + context.sendMessage(`${emojis.scissors} Scissors!`, context.room.id); + await timers.setTimeout(750); + + if (userWins) { + context.sendMessage(`${style.bold('You win!')} ${config.user.username} played ${style.italic(counter)} ${emojis[counter]} against your ${style.italic(hand)} ${emojis[hand]}`, context.room.id); + + context.setPoints(context.user, 1); + context.setPoints(config.user, 1); + + return; + } + + if (botWins) { + context.sendMessage(`${style.bold('You lose...')} ${config.user.username} played ${style.italic(counter)} ${emojis[counter]} against your ${style.italic(hand)} ${emojis[hand]}`, context.room.id); + + context.setPoints(context.user, -1); + context.setPoints(config.user, 1); + + return; + } + + context.sendMessage(`${style.bold('It\'s a draw.')} ${config.user.username} also played ${style.italic(counter)} ${emojis[counter]}`, context.room.id); +} + +async function onCommand(args, context) { + return play(context, context.command); +} + +async function onMessage(args, context) { + if (context.user?.username !== config.user.username && Object.values(emojis).some((emoji) => new RegExp(`^${emoji}$`, 'u').test(context.message.body))) { + play(context, context.command); + } +} + +module.exports = { + onCommand, + onMessage, + name: 'Rock, Paper, Scissors', + commands: ['rock', 'paper', 'scissors'], + help: 'What\'s your next move? Try ~dice [rolls] [faces], ~die or ~roll', +}; diff --git a/src/games/say.js b/src/games/say.js index d90a409..0c020db 100644 --- a/src/games/say.js +++ b/src/games/say.js @@ -12,7 +12,7 @@ function onCommand(args, context) { return; } - if (config.platform === 'irc' && context.room.id === config.user.nick) { + if (config.platform === 'irc' && context.room.id === config.user.id) { // if the room ID is the bot's own nickname, it's a PM and we should reply to the sender context.sendMessage(args.join(' '), context.user.id, { label: false }); } diff --git a/src/irc.js b/src/irc.js index 0cc0314..872f5f3 100644 --- a/src/irc.js +++ b/src/irc.js @@ -13,7 +13,7 @@ const { logger.setLevel(argv.level || 'info'); -const client = new irc.Client(config.server, config.user.nick, { +const client = new irc.Client(config.server, config.user.id, { userName: config.user.username, realName: config.user.realName, password: config.user.password, @@ -30,7 +30,7 @@ async function init() { })), }; - const games = await getGames(bot, config.user.nick); + const games = await getGames(bot, config.user.id); client.addListener('registered', () => { logger.info('Connected!'); diff --git a/src/play.js b/src/play.js index bdbb652..d8b8ba2 100644 --- a/src/play.js +++ b/src/play.js @@ -235,7 +235,7 @@ function onMessage(message, bot, games) { } } - Object.values(games).forEach((game) => game.onMessage?.(message, { + Object.values(Object.fromEntries(Object.values(games).map((game) => [game.key, game]))).forEach((game) => game.onMessage?.(message, { ...game, bot, message, diff --git a/src/utils/get-leaders.js b/src/utils/get-leaders.js index 8b30578..d176fc6 100644 --- a/src/utils/get-leaders.js +++ b/src/utils/get-leaders.js @@ -11,7 +11,7 @@ function getLeaders(points, user, ping = true, limit = Infinity) { const username = userKey.split(':')[1] || userKey; // process the points file if (index === 0) { - return `${style.bold(style.yellow(`${ping ? config.usernamePrefix : ''}${username}`))} with ${style.bold(`${score}`)} points`; + return `${style.bold(style.yellow(`${ping || username === user.username ? config.usernamePrefix : ''}${username}`))} with ${style.bold(`${score}`)} points`; } return `${style.bold(style.cyan(`${ping ? config.usernamePrefix : ''}${username}`))} with ${style.bold(`${score}`)} points`;