death-hangman
Version:
Un módulo dedicado a bots de discord para jugar ahorcado/hangman
174 lines (142 loc) • 5.34 kB
JavaScript
const { EventEmitter } = require('events')
class Hangman extends EventEmitter{
constructor(text, {jugadores, lowerCase = true, lives = 7, findWords = false, findWholeText = false} = {}){
super()
if(!text || typeof text != 'string') throw SyntaxError('Debes proporcionar la palabra de hangman obligatoriamente!')
if(!jugadores) throw SyntaxError('Debes proporcionar la opción {jugadores}!')
if(!Array.isArray(jugadores)) throw TypeError('La opción {jugadores} debe ser un array')
if(jugadores.length < 2) throw SyntaxError('Debes proporcionar mínimo 2 ID\'s en la opcion {jugadores}')
if((typeof lowerCase) != 'boolean') throw TypeError('La opción {lowerCase} debe ser un boolean!')
if(isNaN(lives)) throw TypeError('La opción {lives} debe ser un número!')
this.jugadores = jugadores
this.lowerCase = lowerCase
this.text = text
this._parsedText = lowerCase ? text.toLowerCase() : text
this.lives = Number(lives)
this.players = jugadores.slice(1)
this.options = {
findWords,
findWholeText,
separatorChar: ' ',
hiddenChar: '_'
}
this.game = {
text,
jugadores: jugadores,
lowerCase: lowerCase,
turn: this.nextTurn(),
lives,
ascii: this.ascii(),
chars: {
used: [],
wrong: []
},
step: 0,
ended: false,
winned: false,
lastTurn: null
}
}
handleError(options){
if(--this.game.lives == 0){
this.handleEnd(options)
}
return false
}
handleEnd({winned = false, ended = false}){
this.game.winned = winned
this.game.ended = ended
this.emit('end', this.game)
return true
}
verifyHiddenWord(word){
const hangmanText = this._parsedText
const hangmanHiddenText = this.game.ascii.join('')
const reg = RegExp(`${word}+`, 'g')
while(reg.exec(hangmanText) !== null){
const hiddenStr = hangmanHiddenText.slice(reg.lastIndex - word.length, reg.lastIndex)
if(hiddenStr.includes(this.options.hiddenChar)) return true
}
return false
}
find(letra){
if(!letra) throw TypeError('El método find requiere una letra!')
if(this.game.ended) throw TypeError('La palabra ya ha sido descubierta!')
this.game.step += 1
this.game.lastTurn = this.game.turn
this.nextTurn()
letra = String(letra)
letra = this.lowerCase ? letra.toLowerCase() : letra
if(this.game.chars.used.includes(letra)){
return this.handleError({ended: true})
}
this.game.chars.used.push(letra)
if(this._parsedText.includes(letra)){
if(letra.length > 1){
if(!this.options.findWholeText && !this.options.findWords) return this.handleError({ended: true})
if(this.options.findWholeText){
if(this._parsedText !== letra && !this.options.findWords) return this.handleError({ended: true})
else if(this._parsedText === letra){
this.showText(letra)
return this.handleEnd({winned: true, ended: true})
}
}
if(this.options.findWords){
if(!this._parsedText.split(' ').includes(letra)) return this.handleError({ended: true})
if(!this.verifyHiddenWord(letra)) return this.handleError({ended: true})
}
}
this.showText(letra)
if(!this.game.ascii.includes(this.options.hiddenChar)){
this.handleEnd({winned: true, ended: true})
}
return true
}else{
if(!this.game.chars.used.includes(letra)) this.game.chars.used.push(letra)
if(!this.game.chars.wrong.includes(letra)) this.game.chars.wrong.push(letra)
return this.handleError({ended: true})
}
}
showText(text){
const reg = RegExp(`${text}+`, 'g')
while(reg.exec(this._parsedText) !== null){
let index = reg.lastIndex - text.length
while(index !== reg.lastIndex){
this.game.ascii.splice(index, 1, this._parsedText[index])
index++
}
}
}
removePlayer(player){
if(!player || !this.players.includes(player)) throw RangeError('Debes proporcionar un jugador en la partida actual!')
const index = this.players.indexOf(player)
this.players.splice(index, 1)
this.jugadores.splice(this.jugadores.indexOf(player), 1)
if(this.game.turn === player) this.nextTurn()
return true
}
nextTurn(player){
if(player){
if(!this.players.includes(player)) throw RangeError('Debes proporcionar un jugador en la partida actual!')
while(player !== this.game.turn){
const turno = this.players.shift()
this.players.push(turno)
if('game' in this) this.game.turn = turno
}
return this.game.turn
}
const turno = this.players.shift()
this.players.push(turno)
if('game' in this) this.game.turn = turno
return turno
}
ascii(){
const hiddenWord = this.text.split('').fill(this.options.hiddenChar)
const reg = RegExp(' +', 'g')
while(reg.exec(this.text) !== null){
hiddenWord.splice(reg.lastIndex - 1, 1, this.options.separatorChar)
}
return hiddenWord
}
}
module.exports = Hangman