Alex Merchen
Created September 24, 2018 © GPL3+

Star Wars Trivia with Echo Buttons

Like the title says, I show you how to create a star wars trivia game using the excellent amazon echo buttons.

BeginnerFull instructions provided3 hours55

Things used in this project

Story

Read more

Code

messages.js

JavaScript
These are the default messages for the game. They reference the settings and the questions files to get that information
/*
 * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
 * Licensed under the Amazon Software License (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 * http://aws.amazon.com/asl/
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
'use strict';

const questions = require('./questions');
const settings = require('./settings');
const GAME_TITLE = 'Star Wars Trivia';

const messages = {
  en: {
    translation: {
      'QUESTIONS': questions.questions_en_US,
      'GENERAL_HELP': {
        outputSpeech: 'To get started just ask me to play a game. ' +
          'What would you like to do? ',
        reprompt: "Sorry, I didn't catch that, what would you like to do next?",
        displayTitle: GAME_TITLE + ' - Help',
        displayText: 'This is a trivia game for the Echo Buttons. ' +
          'To get started just ask me to play a game.'
      },
      'UNHANDLED_REQUEST': {
        outputSpeech: "Sorry, I didn't get that. Please say again!",
        reprompt: "Please say it again. You can ask for help if you're not sure what to do."
      },
      'GOOD_BYE': {
        outputSpeech: "Ok, see you next time!",
        reprompt: ''
      },

      //
      //--------------------  Start Game Related Prompts -------------------------------------------
      //
      'START_GAME': {
        outputSpeech: "Welcome to " + GAME_TITLE + ". This game supports up to " +
          settings.GAME.MAX_PLAYERS + " players. " +
          "How many players are there?",
        reprompt: "How many players?",
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "Welcome to " + GAME_TITLE + ". This game supports up to " +
          settings.GAME.MAX_PLAYERS + " players."
      },
      'RESUME_GAME': {
        outputSpeech: 'Ok, we will pick up where you left off. ' +
          'How many players will be playing?',
        reprompt: 'How many players?',
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "Welcome back!"
      },
      'DONT_RESUME_GAME': {
        outputSpeech: 'Ok, lets start a new game. How many players will be playing?',
        reprompt: 'How many players?',
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "Ok. Let's start a new game!"
      },
      'ASK_TO_RESUME': {
        outputSpeech: "It looks like you have a {{player_count}} player game in progress, " +
          "would you like to resume?",
        reprompt: 'Would you like to resume the last game?',
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "You have a {{player_count}} player game in progress."
      },
      'PLAYERCOUNT_INVALID': {
        outputSpeech: 'Please say a number between one and ' + settings.GAME.MAX_PLAYERS,
        reprompt: 'Please say a number between one and ' + settings.GAME.MAX_PLAYERS
      },
      'SINGLE_PLAYER_GAME_READY': {
        outputSpeech: ["Fantastic! Are you ready to start the game?"],
        reprompt: "Ready to start the game?",
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "Are you ready to start the game?"
      },

      //
      //--------------------  Roll Call Related Prompts -------------------------------------------
      //
      'ROLL_CALL_HELP': {
        outputSpeech: 'This is a trivia game for Echo Buttons. ' +
          'In order to play the game, each player must check in by ' +
          'pressing an Echo Button. Would you like to continue and ' +
          'check players in for the game?',
        reprompt: "Sorry, I didn't catch that, what would you like to do next?",
        displayTitle: GAME_TITLE + ' - Help',
        displayText: 'In order to play the game, each player must check in by ' +
          'pressing an Echo Button. Would you like to continue?'
      },
      'ROLL_CALL_CONTINUE': {
        outputSpeech: "Ok. Players, press your buttons now, " +
          "so I'll know which buttons you will be using.",
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "To resume the game, each player, please press your button once!"
      },
      'ROLL_CALL_TIME_OUT': {
        outputSpeech: "<say-as interpret-as='interjection'>uh oh</say-as>, " +
          "looks like times up and I haven't heard from all players. " +
          "Did you want to continue?",
        reprompt: "should we continue?"
      },
      'ROLL_CALL_RESUME_GAME': {
        outputSpeech: "To resume the game, each player, please press your button once!",
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "To resume the game, each player, please press your button once!"
      },
      'ROLL_CALL_COMPLETE': {
        outputSpeech: ["Great! We can start the game. Are you ready?",
        "Awesome. All players registered. Are you ready to start the game?"],
        reprompt: "Ready to start the game?",
        displayTitle: GAME_TITLE + " - Welcome",
        displayText: "Are you ready to start the game?"
      },
      'ROLL_CALL_HELLO_PLAYER': {
        outputSpeech: "Hello, player {{player_number}}. "
      },
      'ROLL_CALL_NEXT_PLAYER_PROMPT': {
        outputSpeech: "Ok, your turn Player {{player_number}}, press your button."
      },

      //
      //--------------------  Game Play Related Prompts -------------------------------------------
      //
      'GAME_CANCELLED': {
        outputSpeech: "Ok, see you next time! " +
          "We'll save this game for later if you'd like to resume",
        reprompt: '',
        displayText: "See you next time!",
        displayTitle: "Thanks for playing!"
      },
      'GAME_FINISHED_INTRO': {
        outputSpeech: "The game is finished. Let's hear the final scores."
      },
      'SINGLE_PLAYER_GAME_FINISHED_INTRO': {
        outputSpeech: "The game is finished. Let's hear your final score."
      },
      'GAME_FINISHED': {
        outputSpeech: "Thanks for playing",
        reprompt: '',
        displayText: "See you next time!",
        displayTitle: "Thanks for playing!"
      },
      'PLAY_GAME_FIRST_QUESTION': {
        outputSpeech: "Ok! Let's start the game!"
      },
      'PLAY_GAME_SKIP_QUESTION': {
        outputSpeech: "Alright. Let's try another question."
      },
      'PLAY_GAME_SKIP_LAST_QUESTION': {
        outputSpeech: "Alright. That was the last question."
      },
      'PLAY_GAME_MID_GAME': {
        outputSpeech: "Ok! Let's keep going. " +
          "We are on question {{current_question}}!"
      },
      'ANSWER_TIME_OUT_DURING_PLAY': {
        outputSpeech: "I didn't hear any presses. Would you like to keep playing?",
        reprompt: "Would you like to keep playing?"
      },
      'BUZZ_IN_DURING_PLAY': {
        outputSpeech: "Ok, player {{player_number}}, what's the answer?",
        reprompt: "Player {{player_number}}, are you there?"
      },
      'CORRECT_ANSWER_DURING_PLAY': {
        outputSpeech: "Correct! Great job player {{player_number}}."
      },
      'INCORRECT_ANSWER_DURING_PLAY': {
        outputSpeech: "Sorry, wrong answer player {{player_number}}."
      },
      'INCORRECT_ANSWER_TOO_MANY_TIMES': {
        outputSpeech: "Sorry, wrong answer player {{player_number}}. " +
          "Let's try another question."
      },
      'SINGLE_PLAYER_CORRECT_ANSWER_DURING_PLAY': {
        outputSpeech: "Correct! Great job."
      },
      'SINGLE_PLAYER_INCORRECT_ANSWER_DURING_PLAY': {
        outputSpeech: "Sorry, wrong answer."
      },
      'MISUNDERSTOOD_ANSWER': {
        outputSpeech: "Sorry, I didn't get that. Please say again!",
        reprompt: "Please repeat the answer."
      },
      'ANSWER_WITHOUT_BUTTONS': {
        outputSpeech: "<say-as interpret-as='interjection'>now now</say-as>" +
          "<break time='1s'/>Press your button to answer the question!"
      },
      'ANSWER_BEFORE_QUESTION': {
        outputSpeech: "I haven't asked the question yet! Wait for me to ask, then " +
          "press your button if you know the answer! Are you ready?",
        reprompt: "Are you ready to play?"
      },
      'ASK_QUESTION_DISPLAY': {
        displayTitle: GAME_TITLE + " - Question {{question_number}}"
      },
      'ANSWER_QUESTION_CORRECT_DISPLAY': {
        displayTitle: GAME_TITLE + " - Player {{player_number}}",
        displayText: ["Great job! That's right.",
        "Awesome! That's the answer.",
        "Correct! You got it."]
      },
      'ANSWER_QUESTION_INCORRECT_DISPLAY': {
        displayTitle: GAME_TITLE + " - Player {{player_number}}",
        displayText: ["Opps! That's not right.",
        "Oh no! That's not the answer.",
        "No, that's not it!"]
      },
      'SINGLE_PLAYER_ANSWER_QUESTION_CORRECT_DISPLAY': {
        displayTitle: GAME_TITLE,
        displayText: ["Great job! That's right.",
        "Awesome! That's the answer.",
        "Correct! You got it."]
      },
      'SINGLE_PLAYER_ANSWER_QUESTION_INCORRECT_DISPLAY': {
        displayTitle: GAME_TITLE,
        displayText: ["Opps! That's not right.",
        "Oh no! That's not the answer.",
        "No, that's not it!"]
      },
      'ASK_FIRST_QUESTION_NEW_GAME_DISPLAY': {
        displayTitle: GAME_TITLE + " - New Game",
        displayText: "Get ready to start!"
      },
      'ASK_FIRST_QUESTION_RESUME_DISPLAY': {
        displayTitle: GAME_TITLE + " - Resume Game",
        displayText: "Get ready to start!"
      },
      'GAME_PLAY_HELP': {
        outputSpeech: 'This is a trivia game for Echo Buttons. ' +
          'During the game, I will ask one question at a time. ' +
          'If you know the answer, press your button for a chance ' +
          'to answer. You will earn a point for each question you ' +
          'answer correctly. Would you like to continue to play? ',
        reprompt: "Sorry, I didn't catch that, what would you like to do next?",
        displayTitle: GAME_TITLE + " - Help",
        displayText: 'During the game, I will ask one question at a time. ' +
          'If you know the answer, press your button for a chance ' +
          'to answer. You will earn a point for each question you ' +
          'answer correctly.'
      },

      //
      //--------------------  Round Summary Related Prompts -------------------------------------
      //
      'GAME_ROUND_SUMMARY_INTRO': {
        outputSpeech: "After the <say-as interpret-as='ordinal'>{{round}}</say-as> round."
      },
      'GAME_ROUND_SUMMARY_OUTRO': {
        outputSpeech: "Let's continue!"
      },

      //
      //--------------------  Scoring Related Prompts -------------------------------------------
      //
      'SCORING_TIED_NO_ANSWERS': {
        outputSpeech: "It's a tie! With no correct answers. Can you do better?"
      },
      'SCORING_TIED_ONE_ANSWER': {
        outputSpeech: "It's a tie! With a single correct answer. What a game!"
      },
      'SCORING_TIED_MULTIPLE_ANSWERS': {
        outputSpeech: "It's a tie! With {{answer_count}} correct answers. What a game!"
      },

      'SCORING_SINGLE_PLAYER_NO_ANSWERS': {
        outputSpeech: "You haven't answered any questions correctly"
      },
      'SCORING_SINGLE_PLAYER_ONE_ANSWER': {
        outputSpeech: "You answered a single question correctly"
      },
      'SCORING_SINGLE_PLAYER_MULTIPLE_ANSWERS': {
        outputSpeech: "You have {{answer_count}} correct answers"
      },
      'SCORING_MULTI_PLAYERS': {
        outputSpeech: "In <say-as interpret-as='ordinal'>{{place}}</say-as> place, " +
          " {{score_details}}"
      }
    }
  },

  //
  // To override by territory follow the below pattern
  //
  // For additional information on translations and formatting messages see https://www.i18next.com/
  //
  'en-US': {
    translation: {
      'GAME_ROUND_SUMMARY_OUTRO': {
        outputSpeech: "Let's continue!"
      }
    },
  },
  'en-GB': {
    translation: {
      'QUESTIONS': questions.questions_en_GB,
      'GAME_ROUND_SUMMARY_OUTRO': {
        outputSpeech: "Onward!"
      }
    }
  }
};

module.exports = messages;

invocation.json

JSON
This is for all of the possible responses in the game
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "star wars trivia",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": [
                        "how do I play this game",
                        "how is this game played",
                        "how do I play this"
                    ]
                },
                {
                    "name": "AMAZON.YesIntent",
                    "samples": [
                        "ready"
                    ]
                },
                {
                    "name": "AMAZON.NoIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "PlayerCount",
                    "slots": [
                        {
                            "name": "players",
                            "type": "AMAZON.NUMBER"
                        }
                    ],
                    "samples": [
                        "{players} players",
                        "there are {players}",
                        "there are {players} players",
                        "there are {players} of us",
                        "we have {players}",
                        "we have {players} players",
                        "there will be {players}",
                        "there will be {players} players"
                    ]
                },
                {
                    "name": "AnswerQuestionIntent",
                    "slots": [
                        {
                            "name": "answers",
                            "type": "answers"
                        }
                    ],
                    "samples": [
                        "a {answers}",
                        "the {answers}",
                        "the answer is {answers}",
                        "my answers is {answers}",
                        "is it {answers}",
                        "it is {answers}",
                        "it was {answers}",
                        "it might be {answers}",
                        "i think it is {answers}",
                        "i think it was {answers}",
                        "i think it might be {answers}",
                        "i think the answer is {answers}",
                        "i think the answer might be {answers}"
                    ]
                },
                {
                    "name": "AnswerOnlyIntent",
                    "slots": [
                        {
                            "name": "answers",
                            "type": "answers"
                        }
                    ],
                    "samples": [
                        "{answers}"
                    ]
                },
                {
                    "name": "PlayGame",
                    "slots": [],
                    "samples": [
                        "play",
                        "play the game",
                        "play a game",
                        "I'm ready to play",
                        "let's play",
                        "start a game",
                        "start the game",
                        "let's start the game",
                        "ready to play",
                        "ready to start",
                        "let's start",
                        "let's begin",
                        "begin the game",
                        "get started"
                    ]
                },
                {
                    "name": "AMAZON.StartOverIntent",
                    "samples": [
                        "start new game",
                        "play a new game",
                        "start a new game",
                        "begin a new game",
                        "start game",
                        "begin new game",
                        "new game",
                        "start over"
                    ]
                },
                {
                    "name": "DontKnowIntent",
                    "slots": [],
                    "samples": [
                        "I don't know",
                        "don't know",
                        "I am not sure",
                        "I have not idea",
                        "I don't understand",
                        "I've got no clue",
                        "I've got no idea",
                        "I have no clue",
                        "I have no idea",
                        "I am clueless"
                    ]
                },
                {
                    "name": "AMAZON.MoreIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateSettingsIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NextIntent",
                    "samples": [
                        "skip",
                        "skip this question",
                        "skip this one",
                        "next question",
                        "go to next question",
                        "go to the next question",
                        "I give up",
                        "we give up"
                    ]
                },
                {
                    "name": "AMAZON.PageUpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.PageDownIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.PreviousIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.ScrollRightIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.ScrollDownIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.ScrollLeftIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.ScrollUpIntent",
                    "samples": []
                },
                {
                    "name": "PlayerCountOnly",
                    "slots": [
                        {
                            "name": "players",
                            "type": "AMAZON.NUMBER"
                        }
                    ],
                    "samples": [
                        "{players}"
                    ]
                }
            ],
            "types": [
                {
                    "name": "answers",
                    "values": [
                        {
                            "name": {
                                "value": "anakin"
                            }
                        },
                        {
                            "name": {
                                "value": "new hope"
                            }
                        },
                        {
                            "name": {
                                "value": "princess leia"
                            }
                        },
                        {
                            "name": {
                                "value": "green"
                            }
                        },
                        {
                            "name": {
                                "value": "laser shooter"
                            }
                        },
                        {
                            "name": {
                                "value": "admiral"
                            }
                        },
                        {
                            "name": {
                                "value": "15"
                            }
                        },
                        {
                            "name": {
                                "value": "867"
                            }
                        },
                        {
                            "name": {
                                "value": "ugnaughts"
                            }
                        },
                        {
                            "name": {
                                "value": "general grievous"
                            }
                        },
                        {
                            "name": {
                                "value": "empire strikes back"
                            }
                        },
                        {
                            "name": {
                                "value": "boba fett"
                            }
                        },
                        {
                            "name": {
                                "value": "han solo"
                            }
                        },
                        {
                            "name": {
                                "value": "maul"
                            }
                        },
                        {
                            "name": {
                                "value": "endor"
                            }
                        },
                        {
                            "name": {
                                "value": "moisture farmer"
                            }
                        },
                        {
                            "name": {
                                "value": "solo"
                            }
                        },
                        {
                            "name": {
                                "value": "cross bow"
                            }
                        },
                        {
                            "name": {
                                "value": "commander"
                            }
                        },
                        {
                            "name": {
                                "value": "14"
                            }
                        },
                        {
                            "name": {
                                "value": "900"
                            }
                        },
                        {
                            "name": {
                                "value": "kashyyk"
                            }
                        },
                        {
                            "name": {
                                "value": "purple"
                            }
                        },
                        {
                            "name": {
                                "value": "general snoke"
                            }
                        },
                        {
                            "name": {
                                "value": "count dookoo"
                            }
                        },
                        {
                            "name": {
                                "value": "last jedi"
                            }
                        },
                        {
                            "name": {
                                "value": "jabba the hut"
                            }
                        },
                        {
                            "name": {
                                "value": "starkiller"
                            }
                        },
                        {
                            "name": {
                                "value": "bounty hunter"
                            }
                        },
                        {
                            "name": {
                                "value": "amidala"
                            }
                        },
                        {
                            "name": {
                                "value": "yoda"
                            }
                        },
                        {
                            "name": {
                                "value": "shot gun"
                            }
                        },
                        {
                            "name": {
                                "value": "general"
                            }
                        },
                        {
                            "name": {
                                "value": "13"
                            }
                        },
                        {
                            "name": {
                                "value": "2000"
                            }
                        },
                        {
                            "name": {
                                "value": "yogis"
                            }
                        },
                        {
                            "name": {
                                "value": "blue"
                            }
                        },
                        {
                            "name": {
                                "value": "dagobah"
                            }
                        },
                        {
                            "name": {
                                "value": "darth vader"
                            }
                        },
                        {
                            "name": {
                                "value": "phantom menace"
                            }
                        },
                        {
                            "name": {
                                "value": "greedo"
                            }
                        },
                        {
                            "name": {
                                "value": "jar jar binks"
                            }
                        },
                        {
                            "name": {
                                "value": "spaceman"
                            }
                        },
                        {
                            "name": {
                                "value": "tattoine\njedi"
                            }
                        },
                        {
                            "name": {
                                "value": "organa"
                            }
                        },
                        {
                            "name": {
                                "value": "qui got jinn"
                            }
                        },
                        {
                            "name": {
                                "value": "DL-44"
                            }
                        },
                        {
                            "name": {
                                "value": "12"
                            }
                        },
                        {
                            "name": {
                                "value": "10"
                            }
                        },
                        {
                            "name": {
                                "value": "wookies"
                            }
                        },
                        {
                            "name": {
                                "value": "yellow"
                            }
                        },
                        {
                            "name": {
                                "value": "jakku"
                            }
                        },
                        {
                            "name": {
                                "value": "darth maul"
                            }
                        },
                        {
                            "name": {
                                "value": "takodana"
                            }
                        }
                    ]
                }
            ]
        }
    }
}

questions.js

JavaScript
These are the questions that are asked for the game
'use strict';
/*
 * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
 * Licensed under the Amazon Software License (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 * http://aws.amazon.com/asl/
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */


/**
 * Questions library
 *
 * Use this file to create your own set of questions.
 *
 * Object properties:
 *      index:          The index of the question in this list
 *      question:       The question you want Alexa to ask
 *      answers:        The list of available answers
 *      correct_answer: The correct answer to the question
 *
 * When adding or updating questions and answers, you must take the list of all values
 * in each of the 'answers' arrays for all questions and add them to a custom slot
 * in your skill called 'answers'.
 *
 * The 'answers' custom slot is be mapped to a couple of intents in the interaction model.
 * One intent, named 'AnswerOnlyIntent', contains only the slot, by itself, in order
 * to maximize the accuracy of the model.
 *
 * For example:
 *      AnswerOnlyIntent {answers}
 *
 * The other intent, 'AnswerQuestionIntent', provides more complex speech patterns
 * to match other utternaces users may include with their answers.
 *
 * For example:
 *      AnswerQuestionIntent is it {answers}
 *      AnswerQuestionIntent it is {answers}
 *      AnswerQuestionIntent the answer is {answers}
 *      AnswerQuestionIntent I think the answer is {answers}
 *
 * See model file at models/en-US.json for a complete example.
 */
module.exports = Object.freeze({
    questions_en_US: [
        {
            index: 1,
            question: 'Who is Luke Skywalker’s dad?',
            answers: ['anakin', 'darth maul', 'count dookoo', 'jar jar binks'],
            correct_answer: 'anakin'
        },
        {
          index: 2,
          question: 'Which is the only film of the original six in which desert planet Tatooine doesn’t appear?',
          answers: ['new hope', 'empire strikes back', 'last jedi', 'phantom menace'],
          correct_answer: 'empire strikes back'
        },
        {
            index: 3,
            question: 'What’s the name of the green-skinned bounty hunter Han Solo kills in Mos Eisley’s cantina?',
            answers: ['jar jar binks', 'boba fett', 'jabba the hut', 'greedo'],
            correct_answer: 'greedo'
        },
        {
            index: 4,
            question: 'Who kills Jabba The Hutt?',
            answers: ['princess leia', 'han solo', 'darth maul', 'jar jar binks'],
            correct_answer: 'princess leia'
        },
        {
            index: 5,
            question: 'What was Luke Skywalker’s original surname?',
            answers: ['jar jar binks', 'maul', 'starkiller', 'spaceman'],
            correct_answer: 'starkiller'
        },
        {
            index: 6,
            question: 'What planet do Wookiees come from?',
            answers: ['kashyyk', 'endor', 'jakku', 'tattoine'],
            correct_answer: 'kashyyk'
        },
        {
            index: 7,
            question: 'What does Luke’s uncle Owen do as a job?',
            answers: ['jar jar binks', 'moisture farmer', 'bounty hunter', 'jedi'],
            correct_answer: 'moisture farmer'
        },
        {
            index: 8,
            question: 'Which of these last names does Leia NOT have a family connection to?',
            answers: ['maul', 'solo', 'amidala', 'organa'],
            correct_answer: 'maul'
        },
        {
            index: 9,
            question: 'Obi-Wan learned to become one with the force from who?',
            answers: ['han solo', 'maul', 'yoda', 'qui got jinn'],
            correct_answer: 'qui gon jinn'
        },
        {
            index: 10,
            question: 'What color lasers do Tie Fighters shoot?',
            answers: ['green', 'purple', 'blue', 'yellow'],
            correct_answer: 'green'
        },
	{
            index: 11,
            question: 'What type of gun does han solo have?',
            answers: ['laser shooter', 'cross bow', 'shot gun', 'DL-44'],
            correct_answer: 'DL-44'
        },
	{
            index: 12,
            question: 'What rank does han solo obtain during the galactic civil war?',
            answers: ['admiral', 'commander', 'general', 'yellow'],
            correct_answer: 'general'
        },
	{
            index: 13,
            question: 'How old was pad may when she became queen?',
            answers: ['15', '14', '13', '12'],
            correct_answer: '14'
        },
	{
            index: 14,
            question: 'How old was yoda when he died?',
            answers: ['867', '900', '2000', '10'],
            correct_answer: '900'
        },
	{
            index: 15,
            question: 'What is the species of the workers on cloud city who helped freeze han solo in carbonite?',
            answers: ['ugnaughts', 'jar jar binks', 'yogis', 'wookies'],
            correct_answer: 'ugnaughts'
        },
	{
            index: 16,
            question: 'Where does yoda live?',
            answers: ['endor', 'kashyyk', 'dagobah', 'jakku'],
            correct_answer: 'dagobah'
        },
	{
            index: 17,
            question: 'What color is mace windus light saber?',
            answers: ['green', 'purple', 'blue', 'yellow'],
            correct_answer: 'purple'
        },
	{
            index: 18,
            question: 'Where is rey from?',
            answers: ['endor', 'kashyyk', 'dagobah', 'jakku'],
            correct_answer: 'jakku'
        },
	{
            index: 19,
            question: 'Who is the leader of the first order?',
            answers: ['general grievous', 'general snoke', 'darth vader', 'darth maul'],
            correct_answer: 'general snoke'
        },
	{
            index: 20,
            question: 'Which planet does maz kanata live?',
            answers: ['endor', 'dagobah', 'jakku', 'takodana'],
            correct_answer: 'takodana'
        }

    ],
    questions_en_GB: [
      {
            index: 1,
            question: 'Who is Luke Skywalker’s dad?',
            answers: ['anakin', 'darth maul', 'count dookoo', 'jar jar binks'],
            correct_answer: 'anakin'
        },
        {
          index: 2,
          question: 'Which is the only film of the original six in which desert planet Tatooine doesn’t appear?',
          answers: ['new hope', 'empire strikes back', 'last jedi', 'phantom menace'],
          correct_answer: 'empire strikes back'
        },
        {
            index: 3,
            question: 'What’s the name of the green-skinned bounty hunter Han Solo kills in Mos Eisley’s cantina?',
            answers: ['jar jar binks', 'boba fett', 'jabba the hut', 'greedo'],
            correct_answer: 'greedo'
        },
        {
            index: 4,
            question: 'Who kills Jabba The Hutt?',
            answers: ['princess leia', 'han solo', 'darth maul', 'jar jar binks'],
            correct_answer: 'princess leia'
        },
        {
            index: 5,
            question: 'What was Luke Skywalker’s original surname?',
            answers: ['jar jar binks', 'maul', 'starkiller', 'spaceman'],
            correct_answer: 'starkiller'
        },
        {
            index: 6,
            question: 'What planet do Wookiees come from?',
            answers: ['kashyyk', 'endor', 'jakku', 'tattoine'],
            correct_answer: 'kashyyk'
        },
        {
            index: 7,
            question: 'What does Luke’s uncle Owen do as a job?',
            answers: ['jar jar binks', 'moisture farmer', 'bounty hunter', 'jedi'],
            correct_answer: 'moisture farmer'
        },
        {
            index: 8,
            question: 'Which of these last names does Leia NOT have a family connection to?',
            answers: ['maul', 'solo', 'amidala', 'organa'],
            correct_answer: 'maul'
        },
        {
            index: 9,
            question: 'Obi-Wan learned to become one with the force from who?',
            answers: ['han solo', 'darth maul', 'yoda', 'qui got jinn'],
            correct_answer: 'qui gon jinn'
        },
        {
            index: 10,
            question: 'What color lasers do Tie Fighters shoot?',
            answers: ['green', 'purple', 'blue', 'yellow'],
            correct_answer: 'green'
        },
	{
            index: 11,
            question: 'What type of gun does han solo have?',
            answers: ['laser shooter', 'cross bow', 'shot gun', 'DL-44'],
            correct_answer: 'DL-44'
        },
	{
            index: 12,
            question: 'What rank does han solo obtain during the galactic civil war?',
            answers: ['admiral', 'commander', 'general', 'yellow'],
            correct_answer: 'general'
        },
	{
            index: 13,
            question: 'How old was pad may when she became queen?',
            answers: ['15', '14', '13', '12'],
            correct_answer: '14'
        },
	{
            index: 14,
            question: 'How old was yoda when he died?',
            answers: ['867', '900', '2000', '10'],
            correct_answer: '900'
        },
	{
            index: 15,
            question: 'What is the species of the workers on cloud city who helped freeze han solo in carbonite?',
            answers: ['ugnaughts', 'jar jar binks', 'yogis', 'wookies'],
            correct_answer: 'ugnaughts'
        },
	{
            index: 16,
            question: 'Where does yoda live?',
            answers: ['endor', 'kashyyk', 'dagobah', 'jakku'],
            correct_answer: 'dagobah'
        },
	{
            index: 17,
            question: 'What color is mace windus light saber?',
            answers: ['green', 'purple', 'blue', 'yellow'],
            correct_answer: 'purple'
        },
	{
            index: 18,
            question: 'Where is rey from?',
            answers: ['endor', 'kashyyk', 'dagobah', 'jakku'],
            correct_answer: 'jakku'
        },
	{
            index: 19,
            question: 'Who is the leader of the first order?',
            answers: ['general grievous', 'general snoke', 'darth vader', 'darth maul'],
            correct_answer: 'general snoke'
        },
	{
            index: 20,
            question: 'Which planet does maz kanata live?',
            answers: ['endor', 'dagobah', 'jakku', 'takodana'],
            correct_answer: 'takodana'
        }

  ]
});

settings.js

JavaScript
These are the settings for the game - how many players, questions per round, etc.
"use strict";
/*
 * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
 * Licensed under the Amazon Software License (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 * http://aws.amazon.com/asl/
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

const animations = require('../utils/animations.js');

/**
 * Settings file
 *
 * Use this file to configure the behavior of your trivia game
 */
module.exports = (function () {
  /**
   * APP_ID:
   *  The skill ID to be matched against requests for confirmation.
   *  It helps protect against spamming your skill.
   *  Replace this with the value of your skill ID to enable this protection.
   */
  const APP_ID = '';

  /**
   * GAME - Game settings
   *      MAX_PLAYERS - A number between 2 and 4
   *      QUESTIONS - The total number of questions you will ask per game. Must be
   *          less than or equal to the total number of questions in config/questions.js
   *      QUESTIONS_PER_ROUND - Number of questions you want to ask before giving a game summary.
   *          Should divide evenly into the total number of questions.
   *      ANSWER_SIMILARITY - A percentage value marking how similar an answer need to be to the
   *          correct answer to be considered correct. Used with the string-similarity package
   *          See github readme for setup instructions
   *      MAX_ANSWERS_PER_QUESTION - Maximum number of answers allowed for each question.
   *      SHUFFLE_QUESTIONS - if enabled, questions are presented in randomized order, otherwise
   *          each question is presented in the same answer as they are listed in the questions file.
   */
  const GAME_OPTIONS = {
    MAX_PLAYERS: 4,
    QUESTIONS_PER_GAME: 6,
    QUESTIONS_PER_ROUND: 2,
    ANSWER_SIMILARITY: .60,
    MAX_ANSWERS_PER_QUESTION: 4,
    SHUFFLE_QUESTIONS: true
  };

  /**
   * ROLLCALL - Control how players register themselves for the game
   *      QUICK_START
   *          Allows for all buttons up to GAME.MAX_PLAYERS to press their buttons during
   *          roll call before the skill will decide they are registered
   *      NAMED_PLAYERS
   *          On each button press up to GAME.MAX_PLAYERS, acknowledge the button press
   *          and call the player out by name
   */
  const ROLLCALL_STATES = {
    QUICK_START: false,
    NAMED_PLAYERS: true
  };

  /**
   * STORAGE.SESSION_TABLE:
   *  The name of the table in DynamoDB where you want to store session and game data.
   *  You can leave this empty if you do not wish to use DynamoDB to automatically
   *  store game data between sessions after each request.
   */
  const STORAGE = {
    // Session persistence
    SESSION_TABLE: 'star-wars-trivia'
  };

  /**
   * COLORS - Change the behavior and colors of the buttons
   *
   *      QUESTION_COLOR - The color the buttons will be when a question is asked.
   *          This is the signal to the users that they should buzz in
   *      BUZZ_IN_COLOR - The color to change the buttons to when someone buzzes in
   *      MISSED_BUZZ_IN - This is the color other buttons will turn when the first player
   *          buzzes in. In this case 'black' is off
   *      INCORRECT_COLOR - The color the button will blink when a player gets a question correct
   *      CORRECT_COLOR - The color a button will blink when the answering player gets the question
   *          correct.
   */
  const COLORS = Object.freeze({
    // Color you want the buttons to be when expecting input
    QUESTION_COLOR: 'blue',
    // Color you want the first button to chime in to be
    BUZZ_IN_COLOR: 'purple',
    // Color you want the other buttons who didn't chime in
    MISSED_BUZZ_IN: 'black',
    // Incorrect answer color
    INCORRECT_COLOR: 'red',
    // Correct color
    CORRECT_COLOR: 'green',
    // Exit color
    EXIT_COLOR: 'white'
  });

  /**
   * AUDIO - Links to sound effects used in the game
   *      ROLL_CALL_COMPLETE
   *          Once all players have buzzed in, play this sound
   *      WAITING_FOR_BUZZ_IN_AUDIO
   *          A ticking sound used to indicate that the skill is waiting for a button press
   *      BUZZ_IN_AUDIO
   *          The sound to play when a user 'buzzes in' and is ready to answer a question
   *      CORRECT_ANSWER_AUDIO
   *          A sound effect to play when the users answer correctly
   *      INCORRECT_ANSWER_AUDIO
   *          The sound effect to play when a user answers incorrectly
   */
  const AUDIO = Object.freeze({
    WAITING_FOR_ROLL_CALL_AUDIO: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_countdown_loop_32s_full_01.mp3'/>",
    ROLL_CALL_COMPLETE: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_intro_01.mp3'/>",
    WAITING_FOR_BUZZ_IN_AUDIO: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_waiting_loop_30s_01.mp3'/>",
    BUZZ_IN_AUDIO: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_neutral_response_01.mp3'/>",
    CORRECT_ANSWER_AUDIO: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_positive_response_02.mp3'/>",
    INCORRECT_ANSWER_AUDIO: "<audio src='https://s3.amazonaws.com/ask-soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_negative_response_02.mp3'/>"
  });

  /**
   * A set of images to show on backgrounds and in display templates when the skill
   * is used with a device with a screen like the Echo Show or Echo Spot
   * https://developer.amazon.com/docs/custom-skills/display-interface-reference.html
   *
   * The skill template chooses images randomly from each array to provide some
   * variety for the user.
   */
  const IMAGES = Object.freeze({
    BACKGROUND_IMAGES: [
      'https://d2vbr0xakfjx9a.cloudfront.net/bg1.jpg',
      'https://d2vbr0xakfjx9a.cloudfront.net/bg2.jpg'
    ],
    CORRECT_ANSWER_IMAGES: [
      'https://d2vbr0xakfjx9a.cloudfront.net/correct1.png',
      'https://d2vbr0xakfjx9a.cloudfront.net/correct2.png',
      'https://d2vbr0xakfjx9a.cloudfront.net/correct3.png',
      'https://d2vbr0xakfjx9a.cloudfront.net/correct4.png'
    ],
    INCORRECT_ANSWER_IMAGES: [
      'https://d2vbr0xakfjx9a.cloudfront.net/wrong1.png',
      'https://d2vbr0xakfjx9a.cloudfront.net/wrong2.png',
      'https://d2vbr0xakfjx9a.cloudfront.net/wrong3.png',
    ]
  });

  /**
   * ANIMATIONS - set up light animations that will be used throughout the game
   */
  const GAME_ANIMATIONS = Object.freeze({
    // Intro - Plays when a customer opens a Skill.
    'INTRO_ANIMATION': animations.ComplexAnimations
      .SpectrumAnimation(10, ["red", "orange", "yellow"]),

    // ** Pre-Roll Call Animation - Buttons that are connected light up.
    'PRE_ROLL_CALL_ANIMATION': animations.BasicAnimations
      .FadeInAnimation(1, "white", 40000),

    // ** Pre-Roll Call Animation - Buttons that are connected light up.
    'ROLL_CALL_BUTTON_ADDED_ANIMATION': animations.BasicAnimations
      .SolidAnimation(1, "green", 40000),

    // ** Roll Call Complete Animation - displays on all buttons in play
    'ROLL_CALL_COMPLETE_ANIMATION': animations.ComplexAnimations
      .SpectrumAnimation(6, ['red', 'orange', 'green', 'yellow', 'white']),

    // ** Roll Call Check-In Animation - buttons change state when added via roll call.
    'ROLL_CALL_CHECKIN_ANIMATION': animations.BasicAnimations
      .SolidAnimation(1, "green", 3000),

    // Buzz In Animation - plays on answering players button
    'BUZZ_IN_ANIMATION': animations.BasicAnimations
      .SolidAnimation(1, COLORS.BUZZ_IN_COLOR, 6000),

    // Buzz In Animation - played for non-answering players buttons
    'BUZZ_IN_OTHER_PLAYERS_ANIMATION': animations.BasicAnimations
      .SolidAnimation(1, 'black', 200),

    // Listen For Answer Animation - played to all buttons after a question is asked
    'LISTEN_FOR_ANSWER_ANIMATION': animations.BasicAnimations
      .SolidAnimation(1, COLORS.QUESTION_COLOR, 26000),

    // Wrong Answer Animation - Player gets something wrong.
    'INCORRECT_ANSWER_ANIMATION': animations.ComplexAnimations
      .AnswerAnimation(COLORS.INCORRECT_COLOR, 'black', 1000),

    // Right Answer Animation - Player gets something right.
    'CORRECT_ANSWER_ANIMATION': animations.ComplexAnimations
      .AnswerAnimation(COLORS.CORRECT_COLOR, 'black', 1000),

    // Exit Animation - plays when the exiting the skill
    'EXIT_ANIMATION': animations.BasicAnimations
      .FadeOutAnimation(1, COLORS.EXIT_COLOR, 1500),
  });

  /*
   * Define the different states that this skill can be in. For the Trivia skill,
   * we define ROLLCALL, GAME_LOOP, ROLLCALL_EXIT, and the initial state called
   * START_GAME_STATE (which maps to the initial state).
   */
  const SKILL_STATES = {
    // Start mode performs roll call and button registration.
    // https://developer.amazon.com/docs/gadget-skills/discover-echo-buttons.html
    START_GAME_STATE: '',
    ROLLCALL_STATE: '_ROLLCALL',
    BUTTON_GAME_STATE: '_BUTTON_GAME',
    BUTTONLESS_GAME_STATE: '_BUTTONLESS_GAME'
  };

  // return the externally exposed settings object
  return Object.freeze({
    APP_ID: APP_ID,
    STORAGE: STORAGE,
    ROLLCALL: ROLLCALL_STATES,
    AUDIO: AUDIO,
    IMAGES: IMAGES,
    GAME: GAME_OPTIONS,
    COLORS: COLORS,
    ANIMATIONS: GAME_ANIMATIONS,
    STATE: SKILL_STATES,
    LOG_LEVEL: 'DEBUG',
    pickRandom(arry) {
      if (Array.isArray(arry)) {
        return arry[Math.floor(Math.random() * Math.floor(arry.length))]
      }
      return arry;
    }
  });
})();

Credits

Alex Merchen

Alex Merchen

22 projects • 37 followers
I'm an EE with a Masters in ECE. I like building things.

Comments