Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Niccolò Avogaro
Published

Capital Test

A nice quiz about capitals.

BeginnerFull instructions provided10 hours810

Things used in this project

Hardware components

Amazon Echo
Amazon Alexa Amazon Echo
×1

Software apps and online services

Alexa Skills Kit
Amazon Alexa Alexa Skills Kit

Story

Read more

Code

Capital Test Lambda Function

C#
It's the Lambda Function of the skill and it's the main code of the skill
'use strict';

// These are all the questions the program does

var questions = [
    {
        "What's the capital of the state Alabama ": [
            "Montgomery",
            "Birmingham",
            "Mobile",
            "Huntsville"
        ]
    },
        {
        "What's the capital of the state Arizona ": [
            "Phoenix",
            "Raleigh",
            "Benson",
            "Topeka"
        ]
    },
        {
        "What's the capital of the state Alaska ": [
            "Juneau",
            "Anchorage",
            "Fairbanks",
            "Mobile"
        ]
    },
        {
        "What's the capital of the state Arkansas ": [
            "13,000",
            "1,200",
            "5,000",
            "120,000"
        ]
    },
        {
        "What's the capital of the state California ": [
            "Sacramento",
            "Los Angeles",
            "San Francisco",
            "San José"
        ]
    },
    
    {
        "What's the capital of the state North Carolina": [
            "Raleigh",
            "Lakewood",
            "Greensboro",
            "Durham"
        ]
    },
    {
        "What's the capital of the state South Carolina": [
            "Columbia",
            "Charleston",
            "Memphis",
            "Releigh"
        ]
    },
{
        "What's the capital of the state Colorado ": [
            "Denver",
            "Aurora",
            "Lakewood",
            "Memphis"
        ]
    },
    {
        "What's the capital of the state Connecticut ": [
            "Hartford",
            "New Haven",
            "Tallahassee",
            "Waterbury"
        ]
    },
    {
        "What's the capital of the state North Dakota": [
            "Bismarck",
            "Fargo",
            "Cleveland",
            "Tulsa"
        ]
    },
    {
        "What's the capital of the state South Dakota ": [
            "Pierre",
            "Sioux falls",
            "Watertown",
            "Yankton"
        ]
    },
    {
        "What's the capital of the state Delaware ": [
            "Dover",
            "Newark",
            "Releigh",
            "Seaford"
        ]
    },
    {
        "What's the capital of the state Florida ": [
            "Tallahassee",
            "Orlando",
            "Miami",
            "Atlanta"
        ]
    },
    {
        "What's the capital of the state Georgia ": [
            "Atlanta",
            "Athens",
            "Augusta",
            "Savannah"
        ]
    },
    {
        "What's the capital of the state Hawaii ": [
            "Honolulu",
            "San Paulo",
            "Houston",
            "Boise"
        ]
    },
    {
        "What's the capital of the state Idaho ": [
            "Boise",
            "Magnolia",
            "Springfield",
            "Rockford"
        ]
    },
    {
        "What's the capital of the state Illinois ": [
            "Springfield",
            "Rockford",
            "Chicago",
            "South Bend"
        ]
    },
    {
        "What's the capital of the state Indiana ": [
            "Indianapolis",
            "Evansville",
            "Indiana city",
            "Cedar Rapids"
        ]
    },
    {
        "What's the capital of the state Iowa ": [
            "Des Moines",
            "Cedar rapids",
            "Topeka",
            "Wichita"
        ]
    },
{
        "What's the capital of the state Kansas ": [
            "Topeka",
            "Olathe",
            "Whichita",
            "Davenport"
        ]
    },
        {
        "What's the capital of the state Kentucky ": [
            "Frankfort",
            "Louisville",
            "Lexington",
            "Shreveport"
        ]
    },
    {
        "What's the capital of the state Louisiana ": [
            "Baton Rouge",
            "Lafayette",
            "New Orleans",
            "Louisiana City"
        ]
    },
        {
        "What's the capital of the state Maine ": [
            "Augusta",
            "Maine city",
            "Santa fe",
            "Indianapolis"
        ]
    },
        {
        "What's the capital of the state Maryland ": [
            "Annapolis",
            "Baltimore",
            "Richmond",
            "Boston"
        ]
    },
        {
        "What's the capital of the state Massachussets ": [
            "Boston",
            "Cambridge",
            "Springfield",
            "Baltimore"
        ]
    },
        {
        "What's the capital of the state Michigan ": [
            "Lansing",
            "Boston",
            "Detroit",
            "Releigh"
        ]
    },
        {
        "What's the capital of the state Minnesota ": [
            "Saint paul",
            "Lansing",
            "Warren",
            "Detroit"
        ]
    },
        {
        "What's the capital of the state Missisipi ": [
            "Jackson",
            "Detroit",
            "Columbia",
            "Rochester"
        ]
    },
        {
        "What's the capital of the state Missouri ": [
            "Jefferson City",
            "Kansas City",
            "Saint Louis",
            "Billings"
        ]
    },
        {
        "What's the capital of the state Montana ": [
            "Helena",
            "Billings",
            "Reno",
            "Montana Bay"
        ]
    },
        {
        "What's the capital of the state Nebraska ": [
            "Lincoln",
            "Omaha",
            "Reno",
            "Austin"
        ]
    },
        {
        "What's the capital of the state Nevada ": [
            "Carson city",
            "Las Vegas",
            "Henderson",
            "Charleston"
        ]
    },
        {
        "What's the capital of the state New Hampshire ": [
            "Concord",
            "Carson city",
            "Oklahoma City",
            "Columbus"
        ]
    },
        {
        "What's the capital of the state New Jersey ": [
            "Trenton",
            "Salem",
            "Elizabeth",
            "Newark"
        ]
    },
        {
        "What's the capital of the state New Mexico ": [
            "Santa fe",
            "Albuquerque",
            "Richmond",
            "Charleston"
        ]
    },
        {
        "What's the capital of the state New York ": [
            "Albany",
            "New york",
            "Montpellier",
            "Salt lake city"
        ]
    },
        {
        "What's the capital of the state Ohio ": [
            "Columbus",
            "Charleston",
            "Dayton",
            "Norman"
        ]
    },
        {
        "What's the capital of the state Oklahoma ": [
            "Oklahoma city",
            "Salem",
            "Norman",
            "Eugene"
        ]
    },        {
        "What's the capital of the state Oregon ": [
            "Salem",
            "Eugene",
            "Harrisburg",
            "Richmond"
        ]
    },        {
        "What's the capital of the state Pennsylvania ": [
            "Harrisburg",
            "Charleston",
            "Philadelphia",
            "Nashville"
        ]
    },        {
        "What's the capital of the state Rhode Island ": [
            "Providence",
            "Nashville",
            "Vegance",
            "Rhode City"
        ]
    },        {
        "What's the capital of the state Tennessee ": [
            "Nashville",
            "Memphis",
            "Chattanooga",
            "Amarillo"
        ]
    },        {
        "What's the capital of the state Texas ": [
            "Austin",
            "Dallas",
            "Odessa",
            "Garland"
        ]
    },        {
        "What's the capital of the state Utah ": [
            "Salt lake city",
            "West valley city",
            "Hampton",
            "Norfolk"
        ]
    },        {
        "What's the capital of the state Vermont ": [
            "Montpelier",
            "Vermont city",
            "Richmond",
            "Norfolk"
        ]
    },        {
        "What's the capital of the state Virginia ": [
            "Richmond",
            "Norfolk",
            "Everett",
            "Spokane"
        ]
    },        {
        "What's the capital of the state West Virginia ": [
            "Charleston",
            "Chesapeake",
            "Madison",
            "Hampton"
        ]
    },        {
        "What's the capital of the state Washington ": [
            "Olympia",
            "Washington D.C.",
            "Seattle",
            "Madison"
        ]
    },        {
        "What's the capital of the state Wisconsin ": [
            "Madison",
            "Cheyenne",
            "Concord",
            "Helena"
        ]
    },        {
        "What's the capital of the state Wyoming ": [
            "Cheyenne",
            "Madison",
            "Milwaukee",
            "Bellevue"
        ]
    }
    
];

exports.handler = function (event, context) {
    try {
        console.log("event.session.application.applicationId=" + event.session.application.applicationId);


     if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.5cc7cbcc-0cf8-4b7d-901b-3364a770e9dc") {
         context.fail("Invalid Application ID");
      }

        if (event.session.new) {
            onSessionStarted({requestId: event.request.requestId}, event.session);
        }

        if (event.request.type === "LaunchRequest") {
            onLaunch(event.request,
                event.session,
                function callback(sessionAttributes, speechletResponse) {
                    context.succeed(buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === "IntentRequest") {
            onIntent(event.request,
                event.session,
                function callback(sessionAttributes, speechletResponse) {
                    context.succeed(buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === "SessionEndedRequest") {
            onSessionEnded(event.request, event.session);
            context.succeed();
        }
    } catch (e) {
        context.fail("Exception: " + e);
    }
};

/**
 * The first function the program calls when it starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId
        + ", sessionId=" + session.sessionId);

}

/**
 * Called when the user invokes the skill without specifying what he want.
 */
function onLaunch(launchRequest, session, callback) {
    console.log("onLaunch requestId=" + launchRequest.requestId
        + ", sessionId=" + session.sessionId);

    getWelcomeResponse(callback);
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
    console.log("onIntent requestId=" + intentRequest.requestId
        + ", sessionId=" + session.sessionId);

    var intent = intentRequest.intent,
        intentName = intentRequest.intent.name;

    // handle yes/no intent after the user has been prompted
    if (session.attributes && session.attributes.userPromptedToContinue) {
        delete session.attributes.userPromptedToContinue;
        if ("AMAZON.NoIntent" === intentName) {
            handleFinishSessionRequest(intent, session, callback);
        } else if ("AMAZON.YesIntent" === intentName) {
            handleRepeatRequest(intent, session, callback);
        }
    }

    // dispatch custom intents to handlers here
    if ("AnswerIntent" === intentName) {
        handleAnswerRequest(intent, session, callback);
    } else if ("AnswerOnlyIntent" === intentName) {
        handleAnswerRequest(intent, session, callback);
    } else if ("DontKnowIntent" === intentName) {
        handleAnswerRequest(intent, session, callback);
    } else if ("AMAZON.YesIntent" === intentName) {
        handleAnswerRequest(intent, session, callback);
    } else if ("AMAZON.NoIntent" === intentName) {
        handleAnswerRequest(intent, session, callback);
    } else if ("AMAZON.StartOverIntent" === intentName) {
        getWelcomeResponse(callback);
    } else if ("AMAZON.RepeatIntent" === intentName) {
        handleRepeatRequest(intent, session, callback);
    } else if ("AMAZON.HelpIntent" === intentName) {
        handleGetHelpRequest(intent, session, callback);
    } else if ("AMAZON.StopIntent" === intentName) {
        handleFinishSessionRequest(intent, session, callback);
    } else if ("AMAZON.CancelIntent" === intentName) {
        handleFinishSessionRequest(intent, session, callback);
    } else {
        throw "Invalid intent";
    }
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId
        + ", sessionId=" + session.sessionId);

}

// ------- Skill specific business logic -------

var ANSWER_COUNT = 4;
var GAME_LENGTH = 5;
var CARD_TITLE = "Capitals Quiz"; 

function getWelcomeResponse(callback) {
    var sessionAttributes = {},
        speechOutput = "Welcome to this nice trivia about States' Capitals. I will ask you " + GAME_LENGTH.toString()
            + " questions, try to get as many right as you can. Just say the number of the answer. Let's begin. ",
        shouldEndSession = false,

        gameQuestions = populateGameQuestions(),
        correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)), // Generate a random index for the correct answer, from 0 to 3
        roundAnswers = populateRoundAnswers(gameQuestions, 0, correctAnswerIndex),

        currentQuestionIndex = 0,
        spokenQuestion = Object.keys(questions[gameQuestions[currentQuestionIndex]])[0],
        repromptText = "Question 1. " + spokenQuestion + " ",

        i, j;

    for (i = 0; i < ANSWER_COUNT; i++) {
        repromptText += (i+1).toString() + ". " + roundAnswers[i] + ". "
    }
    speechOutput += repromptText;
    sessionAttributes = {
        "speechOutput": repromptText,
        "repromptText": repromptText,
        "currentQuestionIndex": currentQuestionIndex,
        "correctAnswerIndex": correctAnswerIndex + 1,
        "questions": gameQuestions,
        "score": 0,
        "correctAnswerText":
            questions[gameQuestions[currentQuestionIndex]][Object.keys(questions[gameQuestions[currentQuestionIndex]])[0]][0]
    };
    callback(sessionAttributes,
        buildSpeechletResponse(CARD_TITLE, speechOutput, repromptText, shouldEndSession));
}

function populateGameQuestions() {
    var gameQuestions = [];
    var indexList = [];
    var index = questions.length;

    if (GAME_LENGTH > index){
        throw "Invalid Game Length.";
    }

    for (var i = 0; i < questions.length; i++){
        indexList.push(i);
    }

    // Pick GAME_LENGTH random questions from the list to ask the user.
    for (var j = 0; j < GAME_LENGTH; j++){
        var rand = Math.floor(Math.random() * index);
        index -= 1;

        var temp = indexList[index];
        indexList[index] = indexList[rand];
        indexList[rand] = temp;
        gameQuestions.push(indexList[index]);
    }

    return gameQuestions;
}

function populateRoundAnswers(gameQuestionIndexes, correctAnswerIndex, correctAnswerTargetLocation) {
    // Get the answers for a given question, and place the correct answer at the spot marked by the
    // correctAnswerTargetLocation variable. 
    var answers = [],
        answersCopy = questions[gameQuestionIndexes[correctAnswerIndex]][Object.keys(questions[gameQuestionIndexes[correctAnswerIndex]])[0]],
        temp, i;

    var index = answersCopy.length;

    if (index < ANSWER_COUNT){
        throw "Not enough answers for question.";
    }

    // Shuffle the answers, excluding the first element.
    for (var j = 1; j < answersCopy.length; j++){
        var rand = Math.floor(Math.random() * (index - 1)) + 1;
        index -= 1;

        var temp = answersCopy[index];
        answersCopy[index] = answersCopy[rand];
        answersCopy[rand] = temp;
    }

    // Swap the correct answer into the target location
    for (i = 0; i < ANSWER_COUNT; i++) {
        answers[i] = answersCopy[i];
    }
    temp = answers[0];
    answers[0] = answers[correctAnswerTargetLocation];
    answers[correctAnswerTargetLocation] = temp;
    return answers;
}

function handleAnswerRequest(intent, session, callback) {
    var speechOutput = "";
    var sessionAttributes = {};
    var gameInProgress = session.attributes && session.attributes.questions;
    var answerSlotValid = isAnswerSlotValid(intent);
    var userGaveUp = intent.name === "DontKnowIntent";

    if (!gameInProgress) {
        // If the user responded with an answer but there is no game in progress, ask the user
        // if they want to start a new game. 
        sessionAttributes.userPromptedToContinue = true;
        speechOutput = "There is no game in progress. Do you want to start a new game? ";
        callback(sessionAttributes,
            buildSpeechletResponse(CARD_TITLE, speechOutput, speechOutput, false));
    } else if (!answerSlotValid && !userGaveUp) {
        // If the user provided answer isn't a number > 0 and < ANSWER_COUNT,
        // return an error message to the user. Remember to guide the user into providing correct values.
        var reprompt = session.attributes.speechOutput;
        var speechOutput = "Your answer must be a number between 1 and " + ANSWER_COUNT + ". " + reprompt;
        callback(session.attributes,
            buildSpeechletResponse(CARD_TITLE, speechOutput, reprompt, false));
    } else {
        var gameQuestions = session.attributes.questions,
            correctAnswerIndex = parseInt(session.attributes.correctAnswerIndex),
            currentScore = parseInt(session.attributes.score),
            currentQuestionIndex = parseInt(session.attributes.currentQuestionIndex),
            correctAnswerText = session.attributes.correctAnswerText;

        var speechOutputAnalysis = "";

        if (answerSlotValid && parseInt(intent.slots.Answer.value) == correctAnswerIndex) {
            currentScore++;
            speechOutputAnalysis = "correct. ";
        } else {
            if (!userGaveUp) {
                speechOutputAnalysis = "wrong. "
            }
            speechOutputAnalysis += "The correct answer is " + correctAnswerIndex + ": " + correctAnswerText + ". ";
        }
        // if currentQuestionIndex is 4, we've reached 5 questions (zero-indexed) and can exit the game session
        if (currentQuestionIndex == GAME_LENGTH - 1) {
            speechOutput = userGaveUp ? "" : "That answer is ";
            speechOutput += speechOutputAnalysis + "You got " + currentScore.toString() + " out of "
                + GAME_LENGTH.toString() + " questions correct. Thank you for playing!";
            callback(session.attributes,
                buildSpeechletResponse(CARD_TITLE, speechOutput, "", true));
        } else {
            currentQuestionIndex += 1;
            var spokenQuestion = Object.keys(questions[gameQuestions[currentQuestionIndex]])[0];
            // Generate a random index for the correct answer, from 0 to 3
            correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT));
            var roundAnswers = populateRoundAnswers(gameQuestions, currentQuestionIndex, correctAnswerIndex),

                questionIndexForSpeech = currentQuestionIndex + 1,
                repromptText = "Question " + questionIndexForSpeech.toString() + ". " + spokenQuestion + " ";
            for (var i = 0; i < ANSWER_COUNT; i++) {
                repromptText += (i+1).toString() + ". " + roundAnswers[i] + ". "
            }
            speechOutput += userGaveUp ? "" : "That answer is ";
            speechOutput += speechOutputAnalysis + "Your score is " + currentScore.toString() + ". " + repromptText;

            sessionAttributes = {
                "speechOutput": repromptText,
                "repromptText": repromptText,
                "currentQuestionIndex": currentQuestionIndex,
                "correctAnswerIndex": correctAnswerIndex + 1,
                "questions": gameQuestions,
                "score": currentScore,
                "correctAnswerText":
                    questions[gameQuestions[currentQuestionIndex]][Object.keys(questions[gameQuestions[currentQuestionIndex]])[0]][0]
            };
            callback(sessionAttributes,
                buildSpeechletResponse(CARD_TITLE, speechOutput, repromptText, false));
        }
    }
}

function handleRepeatRequest(intent, session, callback) {
    // Repeat the previous speechOutput and repromptText from the session attributes if available
    // else start a new game session
    if (!session.attributes || !session.attributes.speechOutput) {
        getWelcomeResponse(callback);
    } else {
        callback(session.attributes,
            buildSpeechletResponseWithoutCard(session.attributes.speechOutput, session.attributes.repromptText, false));
    }
}

function handleGetHelpRequest(intent, session, callback) {
    // Provide a help prompt for the user, explaining how the game is played. Then, continue the game
    // if there is one in progress, or provide the option to start another one.

    // Set a flag to track that we're in the Help state.
    session.attributes.userPromptedToContinue = true;


    var speechOutput = "I will ask you " + GAME_LENGTH + " multiple choice questions. Respond with the number of the answer. "
        + "For example, say one, two, three, or four. To start a new game at any time, say, start game. "
        + "To repeat the last question, say, repeat. "
        + "Would you like to keep playing?",
        repromptText = "To give an answer to a question, respond with the number of the answer . "
        + "Would you like to keep playing?";
        var shouldEndSession = false;
    callback(session.attributes,
        buildSpeechletResponseWithoutCard(speechOutput, repromptText, shouldEndSession));
}

function handleFinishSessionRequest(intent, session, callback) {
    // End the session with a "Good bye!" if the user wants to quit the game
    callback(session.attributes,
        buildSpeechletResponseWithoutCard("Good bye!", "", true));
}

function isAnswerSlotValid(intent) {
    var answerSlotFilled = intent.slots && intent.slots.Answer && intent.slots.Answer.value;
    var answerSlotIsInt = answerSlotFilled && !isNaN(parseInt(intent.slots.Answer.value));
    return answerSlotIsInt && parseInt(intent.slots.Answer.value) < (ANSWER_COUNT + 1) && parseInt(intent.slots.Answer.value) > 0;
}

// ------- Helper functions to build responses -------


function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        card: {
            type: "Simple",
            title: title,
            content: output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    };
}

function buildSpeechletResponseWithoutCard(output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    };
}

function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: "1.0",
        sessionAttributes: sessionAttributes,
        response: speechletResponse
    };
}

Credits

Niccolò Avogaro

Niccolò Avogaro

4 projects • 24 followers
Italian student, iot lover

Comments