chessbot-mastodon/index.js

87 lines
3.9 KiB
JavaScript
Raw Normal View History

2024-09-29 00:52:17 +00:00
const { createRestAPIClient, createStreamingAPIClient } = require('masto'),
jsChessEngine = require('js-chess-engine'),
ChessImageGenerator = require('chess-image-generator'),
config = require('./config.js'),
fs = require('fs');
(async () => {
const nick = config.nick,
rest = createRestAPIClient({
url: `https://${config.url}`,
accessToken: config.accessToken,
requestInit: {
headers: [
['User-Agent', nick]
]
}
}),
ws = createStreamingAPIClient({
streamingApiUrl: `wss://${config.url}`,
accessToken: config.accessToken,
retry: true
}),
sendMessage = async (game, aimove, status, msg) => {
const imageGenerator = new ChessImageGenerator({
size: 720,
light: 'rgb(200, 200, 200)',
dark: '#333333',
style: 'merida'
})
await imageGenerator.loadFEN(game.exportFEN())
const buf = await imageGenerator.generateBuffer(),
statusImage = await rest.v2.media.create({
file: new Blob([buf], { type: 'image/png' }),
skipPolling: true,
description: aimove ? `Chessbot move ${Object.keys(aimove)[0]} to ${Object.values(aimove)[0]}` : 'Chessbot'
})
let canmove
if (aimove) {
moves = game.moves()
canmove = Object.keys(moves).map(key => `move ${key} to ${moves[key].join(', ')}`)
}
await rest.v1.statuses.create({
status: `${msg}${aimove ? '\nMovimientos posibles:\n' + canmove.join('\n') : ''}`,
mediaIds: [statusImage.id],
visibility: 'public',
inReplyToId: status?.id,
language: status?.language
})
}
let game
if (fs.existsSync('game.txt')) {
game = new jsChessEngine.Game(JSON.parse(fs.readFileSync('game.txt').toString()))
sendMessage(game, null, null, `Partida en juego. Su turno.`)
}
for await (const notification of ws.user.notification.subscribe()) {
if (notification.payload['type'] === 'mention' && notification.payload['status']) {
const status = notification.payload['status']
if (status && status.visibility !== 'direct' && status.account.acct !== nick && status.content.trim() !== '') {
const content = ('' + status.content).replace(/<[^>]*>?/gm, '').split(' ').filter(token => !token.startsWith('@'))
if (!game || game?.status?.isFinished) {
game = new jsChessEngine.Game()
sendMessage(game, status, 'Una partidita de ajedrez profesor Falken?')
}
else if (content.length > 1
&& content[0] === 'move'
&& content[1].match(/^[A-H]{1}[1-8]{1}$/)
&& content[2].match(/^[A-H]{1}[1-8]{1}$/)) {
game.move(content[1], content[2])
const d = Date.now(),
levelIA = Math.floor(Math.random() * 5),
aimove = game.aiMove(levelIA),
time = Date.now() - d
if (game?.status && game?.status?.checkMate) {
await sendMessage(game, aimove, status, 'Jaque.')
} else {
await sendMessage(game, aimove, status, `Su turno, movimiento IA ${Object.keys(aimove)[0]} a ${Object.values(aimove)[0]} nivel ${levelIA + 1} en ${time / 1000}s`)
}
}
if (game?.status?.isFinished) {
fs.rmSync('game.txt')
} else {
fs.writeFileSync('game.txt', JSON.stringify(game.exportJson()))
}
}
}
}
})()