Last active
December 3, 2020 19:22
-
-
Save softwarechido/f2e6b51f5df807549779bb2bf3cc16d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Lambda | |
/* eslint-disable func-names */ | |
/* eslint-disable no-console */ | |
const Alexa = require('ask-sdk-core'); | |
const questions = require('./questions'); | |
const i18n = require('i18next'); | |
const sprintf = require('i18next-sprintf-postprocessor'); | |
const ANSWER_COUNT = 4; | |
const GAME_LENGTH = 5; | |
const SKILL_NAME = 'Trivia do Brasil'; | |
const FALLBACK_MESSAGE = 'Lembre-se, nessa habilidade, faço perguntas e você responde com o número da sua resposta. Diga-me para repetir para se perguntar novamente ou você pode começar um novo jogo. Como posso te ajudar? '; | |
const FALLBACK_REPROMPT = 'Como posso te ajudar?'; | |
const languageString = { | |
pt: { | |
translation: { | |
QUESTIONS: questions.QUESTIONS_PT_BR, | |
GAME_NAME: 'Trivia do Brasil', | |
HELP_MESSAGE: 'Farei a você %s perguntas de múltipla escolha. Responda com o número da resposta. Para iniciar um novo jogo, diga, inicie o jogo. Como posso te ajudar?', | |
REPEAT_QUESTION_MESSAGE: 'Para repetir a última pergunta, diga-me: repita', | |
ASK_MESSAGE_START: 'Você gostaria de começar a jogar?', | |
HELP_REPROMPT: 'Para responder, basta me dizer o número da sua resposta', | |
STOP_MESSAGE: 'Ok, vamos jogar outra hora', | |
CANCEL_MESSAGE: 'Ok, vamos jogar outra hora', | |
NO_MESSAGE: 'Ok, volte em breve. Tchau', | |
TRIVIA_UNHANDLED: 'Tente dizer um número entre 1 e %s', | |
HELP_UNHANDLED: 'Diga-me que sim para continuar, não para terminar o jogo', | |
START_UNHANDLED: 'Diga-me para começar o jogo', | |
NEW_GAME_MESSAGE: 'bem-vindo a %s. ', | |
WELCOME_MESSAGE: 'Vou fazer-lhe %s perguntas, tentar adivinhar a resposta correta dizendo o número da resposta, vamos começar. ', | |
ANSWER_CORRECT_MESSAGE: 'correto. ', | |
ANSWER_WRONG_MESSAGE: 'incorreto. ', | |
CORRECT_ANSWER_MESSAGE: 'A resposta correta é %s: %s. ', | |
ANSWER_IS_MESSAGE: 'Essa resposta é ', | |
TELL_QUESTION_MESSAGE: 'pergunta %s. %s ', | |
GAME_OVER_MESSAGE1: 'Você obteve %s resposta correta para %s pergunta. Obrigado por brincar comigo!', | |
GAME_OVER_MESSAGE: 'Você obteve %s resposta correta para %s perguntas. Obrigado por brincar comigo!', | |
SCORE_IS_MESSAGE: 'Sua pontuação é %s. ' | |
}, | |
} | |
}; | |
function populateGameQuestions(translatedQuestions) { | |
const gameQuestions = []; | |
const indexList = []; | |
let index = translatedQuestions.length; | |
if (GAME_LENGTH > index) { | |
throw new Error('Longitud de Juego Inválida'); | |
} | |
for (let i = 0; i < translatedQuestions.length; i += 1) { | |
indexList.push(i); | |
} | |
for (let j = 0; j < GAME_LENGTH; j += 1) { | |
const rand = Math.floor(Math.random() * index); | |
index -= 1; | |
const temp = indexList[index]; | |
indexList[index] = indexList[rand]; | |
indexList[rand] = temp; | |
gameQuestions.push(indexList[index]); | |
} | |
return gameQuestions; | |
} | |
function populateRoundAnswers( gameQuestionIndexes, correctAnswerIndex, correctAnswerTargetLocation, translatedQuestions) { | |
const answers = []; | |
const translatedQuestion = translatedQuestions[gameQuestionIndexes[correctAnswerIndex]]; | |
const answersCopy = translatedQuestion[Object.keys(translatedQuestion)[0]].slice(); | |
let index = answersCopy.length; | |
if (index < ANSWER_COUNT) { | |
throw new Error('No hay suficiente respuestas para la pregunta'); | |
} | |
// Shuffle the answers, excluding the first element which is the correct answer. | |
for (let j = 1; j < answersCopy.length; j += 1) { | |
const rand = Math.floor(Math.random() * (index - 1)) + 1; | |
index -= 1; | |
const swapTemp1 = answersCopy[index]; | |
answersCopy[index] = answersCopy[rand]; | |
answersCopy[rand] = swapTemp1; | |
} | |
// Swap the correct answer into the target location | |
for (let i = 0; i < ANSWER_COUNT; i += 1) { | |
answers[i] = answersCopy[i]; | |
} | |
const swapTemp2 = answers[0]; | |
answers[0] = answers[correctAnswerTargetLocation]; | |
answers[correctAnswerTargetLocation] = swapTemp2; | |
return answers; | |
} | |
function isAnswerSlotValid(intent) { | |
const answerSlotFilled = intent | |
&& intent.slots | |
&& intent.slots.Answer | |
&& intent.slots.Answer.value; | |
const answerSlotIsInt = answerSlotFilled | |
&& !Number.isNaN(parseInt(intent.slots.Answer.value, 10)); | |
return answerSlotIsInt | |
&& parseInt(intent.slots.Answer.value, 10) < (ANSWER_COUNT + 1) | |
&& parseInt(intent.slots.Answer.value, 10) > 0; | |
} | |
function handleUserGuess(userGaveUp, handlerInput) { | |
const { requestEnvelope, attributesManager, responseBuilder } = handlerInput; | |
const { intent } = requestEnvelope.request; | |
const answerSlotValid = isAnswerSlotValid(intent); | |
let speechOutput = ''; | |
let speechOutputAnalysis = ''; | |
const sessionAttributes = attributesManager.getSessionAttributes(); | |
const gameQuestions = sessionAttributes.questions; | |
let correctAnswerIndex = parseInt(sessionAttributes.correctAnswerIndex, 10); | |
let currentScore = parseInt(sessionAttributes.score, 10); | |
let currentQuestionIndex = parseInt(sessionAttributes.currentQuestionIndex, 10); | |
const { correctAnswerText } = sessionAttributes; | |
const requestAttributes = attributesManager.getRequestAttributes(); | |
const translatedQuestions = requestAttributes.t('QUESTIONS'); | |
if (answerSlotValid | |
&& parseInt(intent.slots.Answer.value, 10) === sessionAttributes.correctAnswerIndex) { | |
currentScore += 1; | |
speechOutputAnalysis = requestAttributes.t('ANSWER_CORRECT_MESSAGE'); | |
} else { | |
if (!userGaveUp) { | |
speechOutputAnalysis = requestAttributes.t('ANSWER_WRONG_MESSAGE'); | |
} | |
speechOutputAnalysis += requestAttributes.t( | |
'CORRECT_ANSWER_MESSAGE', | |
correctAnswerIndex, | |
correctAnswerText | |
); | |
} | |
// Check if we can exit the game session after GAME_LENGTH questions (zero-indexed) | |
if (sessionAttributes.currentQuestionIndex === GAME_LENGTH - 1) { | |
speechOutput = userGaveUp ? '' : requestAttributes.t('ANSWER_IS_MESSAGE'); | |
if (currentScore===1){ | |
speechOutput += speechOutputAnalysis + requestAttributes.t( | |
'GAME_OVER_MESSAGE1', | |
currentScore.toString(), | |
GAME_LENGTH.toString()); | |
} | |
else{ | |
speechOutput += speechOutputAnalysis + requestAttributes.t( | |
'GAME_OVER_MESSAGE1', | |
currentScore.toString(), | |
GAME_LENGTH.toString()); | |
} | |
return responseBuilder | |
.speak(speechOutput) | |
.withShouldEndSession(true) | |
.getResponse(); | |
} | |
currentQuestionIndex += 1; | |
correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); | |
const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; | |
const roundAnswers = populateRoundAnswers( | |
gameQuestions, | |
currentQuestionIndex, | |
correctAnswerIndex, | |
translatedQuestions | |
); | |
const questionIndexForSpeech = currentQuestionIndex + 1; | |
let repromptText = requestAttributes.t( | |
'TELL_QUESTION_MESSAGE', | |
questionIndexForSpeech.toString(), | |
spokenQuestion | |
); | |
for (let i = 0; i < ANSWER_COUNT; i += 1) { | |
repromptText += `${i + 1}. ${roundAnswers[i]}. `; | |
} | |
speechOutput += userGaveUp ? '' : requestAttributes.t('ANSWER_IS_MESSAGE'); | |
speechOutput += speechOutputAnalysis | |
+ requestAttributes.t('SCORE_IS_MESSAGE', currentScore.toString()) | |
+ repromptText; | |
const translatedQuestion = translatedQuestions[gameQuestions[currentQuestionIndex]]; | |
Object.assign(sessionAttributes, { | |
speechOutput: repromptText, | |
repromptText, | |
currentQuestionIndex, | |
correctAnswerIndex: correctAnswerIndex + 1, | |
questions: gameQuestions, | |
score: currentScore, | |
correctAnswerText: translatedQuestion[Object.keys(translatedQuestion)[0]][0] | |
}); | |
return responseBuilder.speak(speechOutput) | |
.reprompt(repromptText) | |
.withSimpleCard(requestAttributes.t('GAME_NAME'), repromptText) | |
.getResponse(); | |
} | |
function startGame(newGame, handlerInput) { | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
let speechOutput = newGame | |
? requestAttributes.t('NEW_GAME_MESSAGE', requestAttributes.t('GAME_NAME')) | |
+ requestAttributes.t('WELCOME_MESSAGE', GAME_LENGTH.toString()) | |
: ''; | |
const translatedQuestions = requestAttributes.t('QUESTIONS'); | |
const gameQuestions = populateGameQuestions(translatedQuestions); | |
const correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); | |
const roundAnswers = populateRoundAnswers( | |
gameQuestions, | |
0, | |
correctAnswerIndex, | |
translatedQuestions | |
); | |
const currentQuestionIndex = 0; | |
const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; | |
let repromptText = requestAttributes.t('TELL_QUESTION_MESSAGE', '1', spokenQuestion); | |
for (let i = 0; i < ANSWER_COUNT; i += 1) { | |
repromptText += `${i + 1}. ${roundAnswers[i]}. `; | |
} | |
speechOutput += repromptText; | |
const sessionAttributes = {}; | |
const translatedQuestion = translatedQuestions[gameQuestions[currentQuestionIndex]]; | |
Object.assign(sessionAttributes, { | |
speechOutput: repromptText, | |
repromptText, | |
currentQuestionIndex, | |
correctAnswerIndex: correctAnswerIndex + 1, | |
questions: gameQuestions, | |
score: 0, | |
correctAnswerText: translatedQuestion[Object.keys(translatedQuestion)[0]][0] | |
}); | |
handlerInput.attributesManager.setSessionAttributes(sessionAttributes); | |
return handlerInput.responseBuilder | |
.speak(speechOutput) | |
.reprompt(repromptText) | |
.withSimpleCard(requestAttributes.t('GAME_NAME'), repromptText) | |
.getResponse(); | |
} | |
function helpTheUser(newGame, handlerInput) { | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
const askMessage = newGame | |
? requestAttributes.t('ASK_MESSAGE_START') | |
: requestAttributes.t('REPEAT_QUESTION_MESSAGE') + requestAttributes.t('STOP_MESSAGE'); | |
const speechOutput = requestAttributes.t('HELP_MESSAGE', GAME_LENGTH) + askMessage; | |
const repromptText = requestAttributes.t('HELP_REPROMPT') + askMessage; | |
return handlerInput.responseBuilder.speak(speechOutput).reprompt(repromptText).getResponse(); | |
} | |
const LocalizationInterceptor = { | |
process(handlerInput) { | |
const localizationClient = i18n.use(sprintf).init({ | |
lng: handlerInput.requestEnvelope.request.locale, | |
overloadTranslationOptionHandler: sprintf.overloadTranslationOptionHandler, | |
resources: languageString, | |
returnObjects: true | |
}); | |
const attributes = handlerInput.attributesManager.getRequestAttributes(); | |
attributes.t = function (...args) { | |
return localizationClient.t(...args); | |
}; | |
}, | |
}; | |
const LaunchRequest = { | |
canHandle(handlerInput) { | |
const { request } = handlerInput.requestEnvelope; | |
return request.type === 'LaunchRequest' | |
|| (request.type === 'IntentRequest' | |
&& request.intent.name === 'AMAZON.StartOverIntent'); | |
}, | |
handle(handlerInput) { | |
return startGame(true, handlerInput); | |
}, | |
}; | |
const HelpIntent = { | |
canHandle(handlerInput) { | |
const { request } = handlerInput.requestEnvelope; | |
return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent'; | |
}, | |
handle(handlerInput) { | |
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
const newGame = !(sessionAttributes.questions); | |
return helpTheUser(newGame, handlerInput); | |
}, | |
}; | |
const FallbackHandler = { | |
canHandle(handlerInput) { | |
const request = handlerInput.requestEnvelope.request; | |
return request.type === 'IntentRequest' | |
&& request.intent.name === 'SimulateFallBackIntent'; | |
}, | |
handle(handlerInput) { | |
return handlerInput.responseBuilder | |
.speak(FALLBACK_MESSAGE) | |
.reprompt(FALLBACK_REPROMPT) | |
.getResponse(); | |
}, | |
}; | |
const UnhandledIntent = { | |
canHandle() { | |
return true; | |
}, | |
handle(handlerInput) { | |
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
if (Object.keys(sessionAttributes).length === 0) { | |
const speechOutput = requestAttributes.t('START_UNHANDLED'); | |
return handlerInput.attributesManager | |
.speak(speechOutput) | |
.reprompt(speechOutput) | |
.getResponse(); | |
} else if (sessionAttributes.questions) { | |
const speechOutput = requestAttributes.t('TRIVIA_UNHANDLED', ANSWER_COUNT.toString()); | |
return handlerInput.responseBuilder | |
.speak(speechOutput) | |
.reprompt(speechOutput) | |
.getResponse(); | |
} | |
const speechOutput = requestAttributes.t('HELP_UNHANDLED'); | |
return handlerInput.responseBuilder.speak(speechOutput).reprompt(speechOutput).getResponse(); | |
}, | |
}; | |
const SessionEndedRequest = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest'; | |
}, | |
handle(handlerInput) { | |
console.log(`La sesión se ha finalizado con la razón: ${handlerInput.requestEnvelope.request.reason}`); | |
return handlerInput.responseBuilder.withShouldEndSession(true).getResponse(); | |
}, | |
}; | |
const AnswerIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& (handlerInput.requestEnvelope.request.intent.name === 'AnswerIntent' | |
|| handlerInput.requestEnvelope.request.intent.name === 'DontKnowIntent'); | |
}, | |
handle(handlerInput) { | |
if (handlerInput.requestEnvelope.request.intent.name === 'AnswerIntent') { | |
return handleUserGuess(false, handlerInput); | |
} | |
return handleUserGuess(true, handlerInput); | |
}, | |
}; | |
const RepeatIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.RepeatIntent'; | |
}, | |
handle(handlerInput) { | |
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
return handlerInput.responseBuilder.speak(sessionAttributes.speechOutput) | |
.reprompt(sessionAttributes.repromptText) | |
.getResponse(); | |
}, | |
}; | |
const ResumeIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AAMAZON.ResumeIntent'; | |
}, | |
handle(handlerInput) { | |
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
return handlerInput.responseBuilder.speak(sessionAttributes.speechOutput) | |
.reprompt(sessionAttributes.repromptText) | |
.getResponse(); | |
}, | |
}; | |
const YesIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.YesIntent'; | |
}, | |
handle(handlerInput) { | |
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
if (sessionAttributes.questions) { | |
return handlerInput.responseBuilder.speak(sessionAttributes.speechOutput) | |
.reprompt(sessionAttributes.repromptText) | |
.getResponse(); | |
} | |
return startGame(false, handlerInput); | |
}, | |
}; | |
const StopIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent'; | |
}, | |
handle(handlerInput) { | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
const speechOutput = requestAttributes.t('STOP_MESSAGE'); | |
return handlerInput.responseBuilder.speak(speechOutput) | |
.withShouldEndSession(true) | |
.getResponse(); | |
}, | |
}; | |
const CancelIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'; | |
}, | |
handle(handlerInput) { | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
const speechOutput = requestAttributes.t('CANCEL_MESSAGE'); | |
return handlerInput.responseBuilder.speak(speechOutput) | |
.withShouldEndSession(true) | |
.getResponse(); | |
}, | |
}; | |
const NoIntent = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.NoIntent'; | |
}, | |
handle(handlerInput) { | |
const requestAttributes = handlerInput.attributesManager.getRequestAttributes(); | |
const speechOutput = requestAttributes.t('NO_MESSAGE'); | |
return handlerInput.responseBuilder.speak(speechOutput).withShouldEndSession(true).getResponse(); | |
}, | |
}; | |
const ErrorHandler = { | |
canHandle() { | |
return true; | |
}, | |
handle(handlerInput, error) { | |
console.log(`Error: ${error.message}`); | |
return handlerInput.responseBuilder | |
.speak('Lo siento, no puedo entender el comando. Por favor, intenta de nuevo.') | |
.reprompt('Lo siento, no puedo entender el comando. Por favor, intenta de nuevo.') | |
.getResponse(); | |
}, | |
}; | |
const skillBuilder = Alexa.SkillBuilders.custom(); | |
exports.handler = skillBuilder | |
.addRequestHandlers( | |
LaunchRequest, | |
HelpIntent, | |
AnswerIntent, | |
RepeatIntent, | |
YesIntent, | |
StopIntent, | |
CancelIntent, | |
NoIntent, | |
SessionEndedRequest, | |
FallbackHandler, | |
UnhandledIntent | |
) | |
.addRequestInterceptors(LocalizationInterceptor) | |
.addErrorHandlers(ErrorHandler) | |
.lambda(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"interactionModel": { | |
"languageModel": { | |
"invocationName": "trivia do brasil", | |
"intents": [ | |
{ | |
"name": "AMAZON.CancelIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AMAZON.HelpIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AMAZON.StopIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AnswerIntent", | |
"slots": [ | |
{ | |
"name": "Answer", | |
"type": "AMAZON.NUMBER" | |
} | |
], | |
"samples": [ | |
"minha resposta é {Answer}", | |
"a resposta é {Answer}", | |
"é {Answer}", | |
"{Answer} é a resposta", | |
"{Answer}" | |
] | |
}, | |
{ | |
"name": "DontKnowIntent", | |
"slots": [], | |
"samples": [ | |
"não sei ", | |
"nem idéia", | |
"não o conheço" | |
] | |
}, | |
{ | |
"name": "AMAZON.StartOverIntent", | |
"samples": [ | |
"inicie o jogo", | |
"Eu quero começar um novo jogo", | |
"com um novo jogo", | |
"iniciar um novo jogo" | |
] | |
}, | |
{ | |
"name": "AMAZON.RepeatIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AMAZON.YesIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AMAZON.NoIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "AMAZON.NavigateHomeIntent", | |
"samples": [] | |
}, | |
{ | |
"name": "SimulateFallBackIntent", | |
"slots": [ | |
{ | |
"name": "anything", | |
"type": "AMAZON.SearchQuery" | |
} | |
], | |
"samples": [ | |
"{anything} z", | |
"{anything} y", | |
"{anything} a", | |
"{anything} b", | |
"{anything} c", | |
"{anything} d", | |
"{anything} e", | |
"{anything} f", | |
"{anything} g", | |
"{anything} h", | |
"{anything} i", | |
"{anything} j", | |
"{anything} k", | |
"{anything} l", | |
"{anything} m", | |
"{anything} n", | |
"{anything} o", | |
"{anything} p", | |
"{anything} q", | |
"{anything} r", | |
"{anything} s", | |
"{anything} t", | |
"{anything} u", | |
"{anything} v", | |
"{anything} w", | |
"{anything} x", | |
"ellos", | |
"ustedes ", | |
"nosotros", | |
"tu", | |
"yo", | |
"algo", | |
"lo que sea", | |
"a {anything}" | |
] | |
} | |
], | |
"types": [] | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "trivia", | |
"version": "1.1.0", | |
"description": "Skill de Ejemplo para crear Skills de Trivia", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "Amazon Alexa", | |
"license": "ISC", | |
"dependencies": { | |
"ask-sdk-core": "^2.6.0", | |
"ask-sdk-model": "^1.18.0", | |
"aws-sdk": "^2.326.0", | |
"i18next": "^10.6.0", | |
"i18next-sprintf-postprocessor": "^0.2.2" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
QUESTIONS_PT_BR: [{ | |
'¿Qual é a capital de Acre?': ['Río Branco', ' Cruzeiro do Sul', 'Tarauacá', 'Sena Madureira', 'Brasiléia', 'Camelias', ], | |
}, { | |
'¿Qual é a capital de Alagoas?': ['Maceió', 'Arapiraca', 'Coruripe', 'Maceió', 'Palmeira dos Indios', 'Santana do Ipanema', ], | |
}, { | |
'¿Qual é a capital de Amapá?': ['Macapá', 'Calçoene', 'Cutias', 'Ferreira Gomes', 'Itaubal', 'Laranjal do Jari', ], | |
}, { | |
'¿Qual é a capital de Amazonas?': ['Manaos', 'Itacoatiara', 'Manacapuru', 'Coari', 'Parintins', 'Tefé', ], | |
}, { | |
'¿Qual é a capital de Bahía?': ['Salvador de Bahía', 'Recôncavo', 'Costa dos Coquieros', 'Dendé', 'Cacau', 'Descubrimiento', ], | |
}, { | |
'¿Qual é a capital de Ceará?': ['Fortaleza', 'Caucaia', 'Juazeiro do Norte', 'Maracanaú', 'Sobral', 'Crato', ], | |
}, { | |
'¿Qual é a capital de Distrito Federal?': ['Brasília', 'Gama', 'Taguatinga', 'Brazlândia', 'Sobradinho', 'Planaltina', ], | |
}, { | |
'¿Qual é a capital de Espírito Santo?': ['Vitória', ' Guarapari', 'Jacaraípe', 'Manguinhos', ' Domingos Martins', 'Castelo', ], | |
}, { | |
'¿Qual é a capital de Goiás?': ['Goiânia', 'Anápolis', 'Rio Verde', 'Luziânia', 'Trindade', 'Catalão', ], | |
}, { | |
'¿Qual é a capital de Maranhão?': ['São Luís', 'Imperatriz', 'Timon', 'Caxias', 'São José de Ribamar', 'Codó', ], | |
}, { | |
'¿Qual é a capital de Mato Grosso?': ['Cuiabá', 'Várzea Grande', 'Rondonópolis', 'Sinop', 'Cáceres', 'Sorriso', ], | |
}, { | |
'¿Qual é a capital de Mato Grosso del Sur?': ['Campo Grande', 'Jesús María', 'Calvillo', 'Aguardiente', 'Calandria', 'Camelias', ], | |
}, { | |
'¿Qual é a capital de Minas Gerais?': ['Belo Horizonte', 'Uberlândia', 'Contagem', 'Juiz de Fora', 'Betim', 'Montes Claros', ], | |
}, { | |
'¿Qual é a capital de Pará?': ['Belém', 'Ananindeua', 'Santarém', 'Marabá', 'Castanhal', 'Abaetetuba', ], | |
}, { | |
'¿Qual é a capital de Paraíba?': ['João Pessoa', 'Campina Grande', 'Santa Rita', 'Patos', 'Bayeux', 'Sousa', ], | |
}, { | |
'¿Qual é a capital de Paraná?': ['Curitiba', 'Londrina', 'Maringá', 'Foz do Iguaçu', 'Ponta Grossa', 'Cascavel', ], | |
}, { | |
'¿Qual é a capital de Pernambuco?': ['Recife', 'Jaboatão dos Guararapes', 'Olinda', 'Caruaru', 'Petrolina', 'Paulista', ], | |
}, { | |
'¿Qual é a capital de Piauí?': ['Teresina', 'Parnaíba', 'Picos', 'Floriano', 'Barras', 'Altos', ], | |
}, { | |
'¿Qual é a capital de Río de Janeiro?': ['Río de Janeiro', 'Belford Roxo', 'Duque de Caxias', 'Guapimirim', 'Itaboraí', 'Itaguaí', ], | |
}, { | |
'¿Qual é a capital de Río Grande del Norte?': ['Natal', 'Parnamirim', 'Mossoró', 'Caicó', 'Macaíba', 'Currais Nuevos', ], | |
}, { | |
'¿Qual é a capital de Río Grande del Sur?': ['Porto Alegre', 'Caxias do Sul', 'Pelotas', 'Canoas', 'Santa Maria', 'Santana do Livramento', ], | |
}, { | |
'¿Qual é a capital de Rondônia?': ['Porto Velho', 'Guajará-Mirim', 'Costa Marques', 'Vilhena', 'Nueva Mamoré', 'São Miguel del Guaporé', ], | |
}, { | |
'¿Qual é a capital de Roraima?': ['Boa Vista', 'Pacaraima', 'Bonfim', 'Cantá', 'Caracaraí', 'Caroebe', ], | |
}, { | |
'¿Qual é a capital de Santa Catarina?': ['Florianópolis', 'Antônio Carlos', 'Biguaçu', 'Palhoça', 'São José', 'São Pedro de Alcântara', ], | |
}, { | |
'¿Qual é a capital de São Paulo?': ['São Paulo', 'Campinas', 'Santos', 'Ribeirão Preto', 'São José do Rio Preto', 'Sorocaba', ], | |
}, { | |
'¿Qual é a capital de Sergipe?': ['Aracaju', 'Nossa Senhora do Socorro', 'Lagarto', 'Itabaiana', 'São Cristóvão', 'Estância', ], | |
}, { | |
'¿Qual é a capital de Tocantins?': ['Palmas', 'Araguaína', 'Gurupi', 'Porto Nacional', 'Paraíso do Tocantins', 'Tocantinópolis', ], | |
}, ] | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment