Things used in this project

Software apps and online services:
Dp image kit 02
Amazon Alexa Alexa Skills Kit
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda
Screen%20shot%202015 07 20%20at%206.11.48%20pm
Amazon Web Services AWS DynamoDB
Flickr API

Code

package.jsonJSON
package.json - for NodeJS modules
{
  "name": "UKTreasureHunt",
  "version": "1.0.0",
  "description": "UKTreasureHunt.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "alexa",
    "skill",
    "UK Treasure Hunt"
  ],
  "author": "Khyati",
  "license": "Apache-2.0",
  "dependencies": {
    "alexa-sdk": "^1.0.9",
    "flickrapi": "^0.6.0",
    "moment": "^2.18.1"
  }
}
Lamda Function - index.jsJavaScript
Main Index.js - Code Entry Point
"use strict";


var questions = require("./questions");
var constants = require('./constants');
var gamelogic = require('./gamelogic');

var moment = require('moment');
var flickrObj = null;
var Flickr = require("flickrapi"),
    flickrOptions = {
        api_key: constants.apiKey,
        secret: constants.apiSecret,
        user_id: constants.userId,
        requestOptions: {
            timeout: 2000,
            /* other default options accepted by request.defaults */
        }
    };
Flickr.tokenOnly(flickrOptions, function (error, flickr) {
    flickrObj = flickr;
});



var languageString = {
    "en": {
        "translation": {
            "GAME_NAME": "U.K. Treasure Hunt", // Be sure to change this for your skill.
            "HELP_MESSAGE": "I will ask you %s 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. ",
            "REPEAT_QUESTION_MESSAGE": "To repeat the last question, say, repeat. ",
            "ASK_MESSAGE_START": "Would you like to start playing?",
            "HELP_REPROMPT": "To give an answer to a question, respond with the number of the answer. ",
            "STOP_MESSAGE": "Are you sure you want to stop the trail?",
            "CANCEL_MESSAGE": "Okies, We will hunt the treasure some other time. <say-as interpret-as='interjection'>ta ta</say-as>.",
            "NO_MESSAGE": "Ok, we\'ll play another time. Goodbye!",
            "TRIVIA_UNHANDLED": "Try saying a number between 1 and %s",
            "HELP_UNHANDLrighED": "Say yes to continue, or no to end the game.",
            "START_UNHANDLED": "Say start to start a new treasure trail.",
            "NEW_GAME_MESSAGE": "<say-as interpret-as='interjection'>Ahoy</say-as>, %s. Welcome to %s. ",
            "WELCOME_MESSAGE": "Find precious lost treasures from across the U.K.! " +
            "Find your treasure before stipulated time. Here is your first trail. ",
            "NEXT_TRAIL_MESSAGE": "Here is your next trail. ",
            "ANSWER_CORRECT_MESSAGE": "correct. ",
            "ANSWER_WRONG_MESSAGE": "wrong. ",
            "CORRECT_ANSWER_MESSAGE": "The correct answer is %s: %s. ",
            "ANSWER_IS_MESSAGE": "That answer is ",
            "TELL_QUESTION_MESSAGE": "Question %s. %s ",
            "GAME_OVER_MESSAGE": "You got %s out of %s questions correct. Thank you for playing!",
            "SCORE_IS_MESSAGE": "Your score is %s. ",
            "UNHANDLED_CLUE": "Sorry, I did not get that. You need to select one of the three helpers to get your clue. ",
            "UNHANDLED_DECIDE": "Sorry, I did not get that.",
            "UNHANDLED_FLY": "Sorry, that's not a valid destination.",
            "DECIDE_PROMPT": "Alright, then, %s. Now, do you wish to Ask for Clue further or Fly to Next Destination?",
            "DECIDE_REPROMPT": "Please say Ask to ask for further Clues or say, Fly to look for destinations?",
            "START_MESSAGE": "Your current location is %s. And your treasure trail will lead you to %s. Right now, it is %s and " +
                "You have 2 days to fetch your treasure. Find your next destination by asking for clues. You can ask %s, %s or %s. Whom do you wish to ask?",
            "ASK_MESSAGE": "Right now, It is %s. " +
                "You can ask %s, %s or %s. Whom do you wish to ask?",
            "ASK_UNHANDLED_MESSAGE":
            "You can ask %s, %s or %s. Whom do you wish to ask?",
            "ASK_UNHANDLED_MESSAGE_PROMPT":
            "For example, You can say, Please ask %s. Whom do you wish to ask?",
            "FLY_MESSAGE": "You have the option to fly to %s. " +
    " Where to next, %s?",
            "NEW_DEST_MESSAGE": "<say-as interpret-as='interjection'>tick-tock. tick-tock. tick-tock.</say-as>You have arrived. Welcome to %s and right now, it is %s. Now, do you wish to Ask for Clue further or Fly to Next Destination?",
            "HELP_START" : "Help asked, and here it is. U.K. Treasure Hunt is a game where you need to follow the trail across cities of U.K. At each stage, you will get the help of three helpers whom you can ask for clues. The clue will point to your next destination and then, you need to choose that destination out of the provided options and fly there. Again ask for clues for next destination, and so on until you reach the treasure. You need to reach the treasure in a stipulated time and so, make sure you do not reach to an incorrect City or spend time asking for more clues! Happy Treasure Hunting!",
            "HELP_DECIDE" : "Help asked, and here it is. At any stage of the game, you can either ask helpers for clues or fly to your next destination. You can ask upto three helpers for clues, which will point you to your next destination. So, to ask for clues, Please say, I want to ask. And to fly to your next destination, Please say, I want to fly.",
            "HELP_FLY" : "Help asked, and here it is. Once you have asked Helpers for clues, you will have to deduce which city those clues point to. You can then fly to that city to continue your trail. You will get option of three to four cities and out of those select the one where the clues lead to. For example, to fly to America, please say, Fly to America.",
            "HELP_CLUE" : "Help asked, and here it is. To complete your trail, you need to identify your next location. To help you do that, you can ask upto three helpers for clues. You may figure out the location based on one clue or you can ask other helpers as well. For example, to ask banker for clue, Please say, Ask Banker.",


        }
    }
};

var Alexa = require("alexa-sdk");

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.appId = constants.appId;
    alexa.resources = languageString;
    alexa.dynamoDBTableName = constants.dynamoDBTableName;
    alexa.registerHandlers(newSessionHandlers, startStateHandlers
        , clueStateHandlers, flyStateHandlers, decideStateHandlers
        , helpStateHandlers
        );
    alexa.execute();

};

var newSessionHandlers = {

    'NewSession': function () {
        console.log('New Sessioon 1');
        var that = this;
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
                that.handler.state = constants.states.START_MODE;
                that.emitWithState("StartGame", true);
                // result is Flickr's response
    },
    "LaunchIntent": function () {
        console.log('Launch Req 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "LaunchRequest": function () {
        console.log('Launch Req 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "AMAZON.StartOverIntent": function () {
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "AMAZON.HelpIntent": function() {
        this.handler.state = constants.states.HELP_MODE;
        this.emitWithState("helpTheUser", constants.states.START_MODE);
    },
    "Unhandled": function () {
        var speechOutput = this.t("START_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    }
};

var startStateHandlers = Alexa.CreateStateHandler(constants.states.START_MODE, {
    "StartGame": function (newGame) {
        console.log('Start Mode: Start Game');
        var speechOutput = newGame ? this.t("NEW_GAME_MESSAGE", this.attributes['level'], this.t("GAME_NAME"))  : "";
        if (this.attributes['newuser'] == 0)
        {
            speechOutput += this.t("WELCOME_MESSAGE");
        }
        else
        {
            speechOutput += this.t("NEXT_TRAIL_MESSAGE");
        }
        var currentCountry = gamelogic.getStartCountry();
        var currentTime = moment();
        var data = questions.data;
        var helper = questions.helper;
        var endTime = moment();
        endTime.add(2, 'd');

        var trail = gamelogic.buildTreasureTrail(currentCountry);
        var treasure = getRandomTreasure();

        var repromptText = this.t("START_MESSAGE", data[currentCountry].country, treasure,
            currentTime.format("Do MMMM h A"), helper[trail[0].helper[0]].helper,
            helper[trail[0].helper[1]].helper, helper[trail[0].helper[2]].helper);

        speechOutput += repromptText;

        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentCountry": currentCountry,
            "currentTime": currentTime,
            "currentStep": 0,
            "rightStep": 0,
            "newuser": 1,
            "trail": trail,
            "treasure": treasure,
            "endTime": endTime,
            "startCountry": currentCountry,
            "currentState": constants.states.CLUE_MODE,
            "isRightTrack": true
        });

        this.handler.state = constants.states.CLUE_MODE;
        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
    },
    "LaunchIntent": function () {
        console.log('Launch Req start');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "LaunchRequest": function () {
        console.log('Launch Req start');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },


    "AMAZON.HelpIntent": function() {
        this.handler.state = constants.states.HELP_MODE;
        this.emitWithState("helpTheUser", constants.states.START_MODE);
    }

});


var clueStateHandlers = Alexa.CreateStateHandler(constants.states.CLUE_MODE, {
    "AskIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        handleUserClue.call(this);
    },
    "LaunchIntent": function () {
        console.log('Launch CLue 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "LaunchRequest": function () {
        console.log('Launch CLue 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },


    "AMAZON.StartOverIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.emit(":ask", this.attributes["speechOutput"], this.attributes["repromptText"]);
    },
    "AMAZON.HelpIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.HELP_MODE;
        this.emitWithState("helpTheUser", constants.states.CLUE_MODE);
    },
    "AMAZON.NoIntent": function() {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = constants.states.START_MODE;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.CancelIntent": function () {
        this.handler.state = constants.states.START_MODE;
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "AMAZON.YesIntent": function () {
        if(this.attributes['askedCancel'])
        {
            var speechOutput = this.t("CANCEL_MESSAGE");
            this.handler.state = constants.states.START_MODE;
            this.emit(":tell", speechOutput);
        }
        else
        {
            this.emitWithState("Unhandled");
        }
    },
    "AMAZON.StopIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": true
        });
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "Unhandled": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        var data = questions.data;
        var helper = questions.helper;
        var currentStep = this.attributes['currentStep'];
        var trail = this.attributes['trail'];
        var currentCountry = this.attributes['currentCountry'];
        var currentTime = moment(this.attributes['currentTime']);

        var speechText = this.t("UNHANDLED_CLUE") + this.t("ASK_UNHANDLED_MESSAGE",
            helper[trail[0].helper[0]].helper,
            helper[trail[0].helper[1]].helper, helper[trail[0].helper[2]].helper);

        var repromptText = this.t("ASK_UNHANDLED_MESSAGE_PROMPT",
            helper[trail[0].helper[0]].helper);

        
        Object.assign(this.attributes, {
            "speechOutput": speechText,
            "repromptText": repromptText
        });

        this.emit(":askWithCard", speechText, repromptText, this.t("GAME_NAME"), getCardString(speechText));
    },
    "SessionEndedRequest": function () {
        this.handler.state = constants.states.START_MODE;
        this.emit(':saveState', true);
        console.log("Session ended in trivia state: " + this.event.request.reason);
    }
});
function handleUserClue() {
    var answerSlotValid = isHelperSlotValid(this.event.request.intent);
    if(!answerSlotValid)
    {
        this.emitWithState("Unhandled");
        return;
    }
    else
    {
        var currentTime = moment(this.attributes['currentTime']);
        currentTime.add(2, 'h');
        Object.assign(this.attributes, {
            "currentTime": currentTime
        });

        //check if gameover
        if (checkIfGameOver.call(this))
        {
            var repromptText = getTimeOutText.call(this);
            repromptText = repromptText.clue.replace('%s', currentTime.format("Do MMMM h A"));

            this.emit(":tellWithCard", repromptText, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
            return;
        }
        // check if back
        var thisNote = this.event.request.intent.slots.Helper.value.toLowerCase().trim();
        thisNote = thisNote.replace(/[^a-zA-Z]/gi, '');
        if (thisNote === 'back') {
            this.handler.state = constants.states.DECIDE_MODE;
            var speechOutput = this.t("DECIDE_PROMPT", this.attributes['level']);
            var repromptText = this.t("DECIDE_REPROMPT");
            Object.assign(this.attributes, {
                "speechOutput": speechOutput,
                "repromptText": repromptText
            });
            this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
            return;
        }
        else
        {
            var currentStep = this.attributes['currentStep'];
            var rightStep = this.attributes['rightStep'];

            var clue = '';
            if (currentStep == rightStep)
                clue = getHelperClue.call(this, this.event.request.intent);
            else
                clue = getIncorrectClue.call(this).clue;

            var helperNAme = getHelper.call(this, this.event.request.intent);
            console.log('Clue: ' + clue);
            if(clue !== '')
            {
                this.handler.state = constants.states.DECIDE_MODE;
                var speechOutput = 'The ' + helperNAme + ' says, ' + clue + '. ' + this.t("DECIDE_PROMPT", this.attributes['level']);
                var repromptText = this.t("DECIDE_REPROMPT");
                Object.assign(this.attributes, {
                    "speechOutput": speechOutput,
                    "repromptText": repromptText
                });
                var that = this;
                var trivia = this.attributes['trail'];
                var country = trivia[this.attributes['currentStep']].country;
                var randPage = getRandomNumber(0, 5);
                var randPerPage = getRandomNumber(0, 30);
                Flickr.tokenOnly(flickrOptions, function (error, flickr) {
                    // we can now use "flickr" as our API object,
                    // but we can only call public methods and access public data
                    console.log("Token Recd: " + questions.data[country].country);
                    flickr.photos.search({
                        tags: questions.data[country].country,
                        extras: "url_l", //"url_l,license,owner_name",
                        licenses: "0,7",
                        safe_search: 1,
                        //is_commons: true,
                        page: randPage,
                        per_page: randPerPage
                    }, function (err, result) {
                        console.log('Err: ' + err);
                        var photo = "";
                        if (!err) {
                            try {
                                var l = result.photos.photo.length;
                                if (l > 0)
                                {
                                    var randNo = getRandomNumber(0, l);
                                    console.log(randNo);
                                    photo = result.photos.photo[randNo].url_l;
                                    console.log(photo);
                                }
                            }
                            catch(e)
                            {
                                photo = "";
                            }
                        }
                        if (photo !== "")
                            that.emit(":askWithCard", speechOutput, repromptText, that.t("GAME_NAME"), getCardString(speechOutput),
                                { largeImageUrl: photo, smallImageUrl: photo });
                        else
                            that.emit(":askWithCard", speechOutput, repromptText, that.t("GAME_NAME"), getCardString(speechOutput));

                    });
                });

            }
            else
            {
                this.emitWithState("Unhandled");
            }
        }
    }


}

var decideStateHandlers = Alexa.CreateStateHandler(constants.states.DECIDE_MODE, {
    "DecideIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        handleUserDecide.call(this);
    },
    "LaunchIntent": function () {
        console.log('Launch Decide 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "LaunchRequest": function () {
        console.log('Launch Decide 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },

    "AMAZON.StartOverIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.emit(":ask", this.attributes["speechOutput"], this.attributes["repromptText"]);
    },
    "AMAZON.HelpIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.HELP_MODE;
        this.emitWithState("helpTheUser", constants.states.DECIDE_MODE);
    },
    "AMAZON.NoIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = constants.states.START_MODE;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.CancelIntent": function () {
        this.handler.state = constants.states.START_MODE;
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "AMAZON.YesIntent": function () {
        if(this.attributes['askedCancel'])
        {
            var speechOutput = this.t("CANCEL_MESSAGE");
            this.handler.state = constants.states.START_MODE;
            this.emit(":tell", speechOutput);
        }
        else
        {
            this.emitWithState("Unhandled");
        }
    },
    "AMAZON.StopIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": true
        });
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "Unhandled": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.emit(":ask", this.t("UNHANDLED_DECIDE") + ' ' + this.attributes["repromptText"], this.attributes["repromptText"]);
    },
    "SessionEndedRequest": function () {
        this.emit(':saveState', true);
        console.log("Session ended in trivia state: " + this.event.request.reason);
    }
});
function handleUserDecide() {
    var answerSlotValid = isDecideSlotValid(this.event.request.intent);
    console.log('Ans: ' + answerSlotValid);
    if (answerSlotValid === '') {
        this.emitWithState("Unhandled");
        return;
    }
    else {
        if(answerSlotValid == 'fly')
        {
            this.handler.state = constants.states.FLY_MODE;
            var data = questions.data;
            // generate list of countries and ask user

            var sh = [];

            var currentStep = this.attributes['currentStep'];
            var rightStep = this.attributes['rightStep'];

            if (currentStep == rightStep)
                sh = getCountryList.call(this);
            else
                sh = getCountryListIncorrect.call(this);

            var cntName = '';
            for (var x = 0 ; x < sh.length ; x++) {
                var n = data[sh[x]].country;
                cntName += n;
                if (x == sh.length - 1)
                    cntName += '';
                else if (x == sh.length - 2)
                    cntName += ' or ';
                else
                    cntName += ', ';
            }
            console.log('--------=========-----------');
            console.log(JSON.stringify(cntName));
            var repromptText = this.t("FLY_MESSAGE", cntName, this.attributes['level']);
            Object.assign(this.attributes, {
                "speechOutput": repromptText,
                "repromptText": repromptText,
                "flyOptions": sh
            });

            this.emit(":askWithCard", repromptText, repromptText, this.t("GAME_NAME"), getCardString(repromptText));

        }
        else if(answerSlotValid == 'ask')
        {
            this.handler.state = constants.states.CLUE_MODE;
            // get list of current helpers and send
            var data = questions.data;
            var helper = questions.helper;

            var currentStep = this.attributes['currentStep'];
            var trail = this.attributes['trail'];
            var currentCountry = this.attributes['currentCountry'];
            var currentTime = moment(this.attributes['currentTime']);

            var repromptText = this.t("ASK_MESSAGE", 
                currentTime.format("Do MMMM h A"), helper[trail[currentStep].helper[0]].helper,
                helper[trail[currentStep].helper[1]].helper, helper[trail[currentStep].helper[2]].helper);


            Object.assign(this.attributes, {
                "speechOutput": repromptText,
                "repromptText": repromptText
            });

            this.emit(":askWithCard", repromptText, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
        }
    }


}

var flyStateHandlers = Alexa.CreateStateHandler(constants.states.FLY_MODE, {
    "FlyIntent": function () {
        console.log('FlyIntent');
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        handleUserFly.call(this);
    },
    "LaunchIntent": function () {
        console.log('Launch Fly 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },
    "LaunchRequest": function () {
        console.log('Launch Fly 1');
        if (Object.keys(this.attributes).length === 0) {
            console.log('New Session');
            this.attributes['level'] = 'Treasure Hunter';
            this.attributes['trail'] = [];
            this.attributes['history'] = [];
            this.attributes['score'] = 0;
            this.attributes['newuser'] = 0;
        }
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", true);
    },

    "AMAZON.StartOverIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.emit(":ask", this.attributes["speechOutput"], this.attributes["repromptText"]);
    },
    "AMAZON.HelpIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.HELP_MODE;
        this.emitWithState("helpTheUser", constants.states.DECIDE_MODE);
    },
    "AMAZON.NoIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = constants.states.START_MODE;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.CancelIntent": function () {
        this.handler.state = constants.states.START_MODE;
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "AMAZON.YesIntent": function () {
        if(this.attributes['askedCancel'])
        {
            var speechOutput = this.t("CANCEL_MESSAGE");
            this.handler.state = constants.states.START_MODE;
            this.emit(":tell", speechOutput);
        }
        else
        {
            this.emitWithState("Unhandled");
        }
    },
    "AMAZON.StopIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": true
        });
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "Unhandled": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        console.log('UnahnIntent');
        this.emit(":ask", this.t("UNHANDLED_FLY") + ' ' + this.attributes["repromptText"], this.attributes["repromptText"]);
    },
    "SessionEndedRequest": function () {
        this.emit(':saveState', true);
        console.log("Session ended in trivia state: " + this.event.request.reason);
    }
});
function handleUserFly() {
    var answerSlotValid = isDestinationSlotValid.call(this, this.event.request.intent);
    console.log('>>> ' + answerSlotValid);
    if (!answerSlotValid) {
        this.emitWithState("Unhandled");
        return;
    }
    else {
        var currentTime = moment(this.attributes['currentTime']);
        var timeAdd = getRandomNumber(4, 8);
        currentTime.add(timeAdd, 'h');

        // check if time over


        Object.assign(this.attributes, {
            "currentTime": currentTime
        });

        if (checkIfGameOver.call(this))
        {
            var repromptText = getTimeOutText.call(this);
            repromptText = repromptText.clue.replace('%s', currentTime.format("Do MMMM h A"));

            this.emit(":tellWithCard", repromptText, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
            return;
        }

        // check if back
        var thisNote = this.event.request.intent.slots.Destination.value.toLowerCase().trim();
        thisNote = thisNote.replace(/[^a-zA-Z]/gi, '');
        console.log('NOTES: ' + thisNote);
        if (thisNote === 'back') {
            this.handler.state = constants.states.DECIDE_MODE;
            var speechOutput = this.t("DECIDE_PROMPT", this.attributes['level']);
            var repromptText = this.t("DECIDE_REPROMPT");
            Object.assign(this.attributes, {
                "speechOutput": speechOutput,
                "repromptText": repromptText
            });
            this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
            return;
        }
        else {
            var destination = getDestination.call(this, this.event.request.intent);
            console.log('Destination: ' + JSON.stringify(destination));
            var currentStep = this.attributes['currentStep'];
            var rightStep = this.attributes['rightStep'];
            var trail = this.attributes['trail'];
            var currentCountry = this.attributes['currentCountry'];
            var currentTime = moment(this.attributes['currentTime']);

            var isRightTrack = destination[0].countryId == trail[rightStep].country;
            if (rightStep == 0 && rightStep != currentStep)
            {
                isRightTrack = destination[0].countryId == this.attributes['startCountry'];
            }
            console.log('>> ' + rightStep + ' ' + currentStep)
            console.log('>>> ' + isRightTrack + ' ' + destination[0].countryId + ' : ' + trail[rightStep].country);
            if (isRightTrack)
            {
                if (destination[0].countryId == this.attributes['startCountry'])
                    rightStep = 0;
                for (var tt = 0 ; tt < trail.length ; tt++) {

                    console.log('>>>>>> ' + tt + ' ' + destination[0].countryId + ' : ' + trail[tt].country);
                    if (trail[tt].country == destination[0].countryId) {
                        rightStep = tt + 1;
                        break;
                    }
                }
            }

            if (rightStep == 5) {
                // game over
                var winText = getWinText.call(this);
                console.log(">>> " + questions.data[trail[rightStep - 1].country] + '  ' + winText);
                var score = this.attributes['score'];
                var level = this.attributes['level'];
                var left = 0;
                var lastLevel = level;
                var addLevelText = true;
                score = score + 1;

                if (score < 5)
                {
                    level = questions.level[0].level;
                    left = 5 - score;
                }
                else if (score < 10)
                {
                    level = questions.level[1].level;
                    left = 10 - score;
                }
                else if (score < 15)
                {
                    level = questions.level[2].level;
                    left = 15 - score;
                }
                else if (score < 20)
                {
                    level = questions.level[3].level;
                    left = 20 - score;
                }
                else if (score < 25)
                {
                    level = questions.level[4].level;
                    left = 25 - score;
                }
                else 
                {
                    addLevelText = false;
                }
                Object.assign(this.attributes, {
                    "score": score,
                    "level": level
                });
                console.log('>>' + score + ' ' + level);
                var repromptText = winText.clue.replace('%s', questions.data[trail[rightStep - 1].country].country);

                repromptText += ' The ' + this.attributes['treasure'] + ' is all yours! ';
                if (addLevelText)
                {
                    if (level === lastLevel) {
                        repromptText += ' You have completed ' + score + ' Trails successfully! And, your current rank is ' +
                            level + '. ' + left + ' more trails until your next promotion! Happy Treasure Hunting!<say-as interpret-as="interjection">ta ta</say-as>';
                    }
                    else
                    {
                        repromptText += ' <say-as interpret-as="interjection">woo hoo</say-as>. You have earned a promotion. Your current rank is ' + level + '. And, you have completed ' + score +
                            ' Trails successfully! ' + left + ' more trails until your next promotion! Happy Treasure Hunting!<say-as interpret-as="interjection">ta ta</say-as>';

                    }
                }
                this.emit(":tellWithCard", repromptText, this.t("GAME_NAME"), getCardString(repromptText));
                return;

            }
            else {
                currentStep++;
                console.log('curr: ' + currentStep + '  : right ' + rightStep + ' ' + isRightTrack);
                if (isRightTrack) {
                    currentStep = rightStep;
                }
                this.handler.state = constants.states.DECIDE_MODE;
                currentCountry = trail[rightStep].country;
                var repromptText = this.t("NEW_DEST_MESSAGE", destination[0].country,
                currentTime.format("Do MMMM h A"));


                Object.assign(this.attributes, {
                    "speechOutput": repromptText,
                    "repromptText": repromptText,
                    "currentTime": currentTime,
                    "currentStep": currentStep,
                    "isRightTrack": isRightTrack,
                    "rightStep": rightStep,
                    "currentCountry": currentCountry
                });

                this.emit(":askWithCard", repromptText, repromptText, this.t("GAME_NAME"), getCardString(repromptText));
            }
        }
    }


}


var helpStateHandlers = Alexa.CreateStateHandler(constants.states.HELP_MODE, {
    "helpTheUser": function (state) {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.attributes["currentState"] = state;
        this.handler.state = state;
        var speechOutput = this.t("HELP_MESSAGE");
        if(state == constants.states.START_MODE)
        {
            speechOutput = this.t("HELP_START");
        }
        else if(state == constants.states.CLUE_MODE)
        {
            speechOutput = this.t("HELP_CLUE");
        }
        else if(state == constants.states.DECIDE_MODE)
        {
            speechOutput = this.t("HELP_DECIDE");
        }
        else if(state == constants.states.FLY_MODE)
        {
            speechOutput = this.t("HELP_FLY");
        }
        
        this.emit(":ask", speechOutput + ' Now, ' + this.attributes['speechOutput'], speechOutput + ' Now, ' + this.attributes['repromptText']);
    },
    "AMAZON.StartOverIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.handler.state = constants.states.START_MODE;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        this.emitWithState("helpTheUser", this.handler.state);
    },
    "AMAZON.HelpIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });

        this.emitWithState("helpTheUser", this.handler.state);
    },
    "AMAZON.YesIntent": function () {
        if (this.attributes['askedCancel']) {
            var speechOutput = this.t("CANCEL_MESSAGE");
            this.handler.state = constants.states.START_MODE;
            this.emit(":tell", speechOutput);
        }
        else {
            this.emitWithState("Unhandled");
        }
    },
    "AMAZON.StopIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": true
        });
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "AMAZON.NoIntent": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = constants.states.START_MODE;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.CancelIntent": function () {
        this.handler.state = constants.states.START_MODE;
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "Unhandled": function () {
        Object.assign(this.attributes, {
            "askedCancel": false
        });
        var speechOutput = this.t("HELP_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "SessionEndedRequest": function () {
        console.log("Session ended in help state: " + this.event.request.reason);
    }
});
/*
function handleUserGuess(userGaveUp) {
    var answerSlotValid = isAnswerSlotValid(this.event.request.intent);
    var speechOutput = "";
    var speechOutputAnalysis = "";
    var gameQuestions = this.attributes.questions;
    var correctAnswerIndex = parseInt(this.attributes.correctAnswerIndex);
    var currentScore = parseInt(this.attributes.score);
    var currentQuestionIndex = parseInt(this.attributes.currentQuestionIndex);
    var correctAnswerText = this.attributes.correctAnswerText;
    var translatedQuestions = this.t("QUESTIONS");

    if (answerSlotValid && parseInt(this.event.request.intent.slots.Answer.value) == this.attributes["correctAnswerIndex"]) {
        currentScore++;
        speechOutputAnalysis = this.t("ANSWER_CORRECT_MESSAGE");
    } else {
        if (!userGaveUp) {
            speechOutputAnalysis = this.t("ANSWER_WRONG_MESSAGE");
        }

        speechOutputAnalysis += this.t("CORRECT_ANSWER_MESSAGE", correctAnswerIndex, correctAnswerText);
    }

    // Check if we can exit the game session after GAME_LENGTH questions (zero-indexed)
    if (this.attributes["currentQuestionIndex"] == GAME_LENGTH - 1) {
        speechOutput = userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("GAME_OVER_MESSAGE", currentScore.toString(), GAME_LENGTH.toString());

        this.emit(":tell", speechOutput)
    } else {
        currentQuestionIndex += 1;
        correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT));
        var spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0];
        var roundAnswers = populateRoundAnswers.call(this, gameQuestions, currentQuestionIndex, correctAnswerIndex, translatedQuestions);
        var questionIndexForSpeech = currentQuestionIndex + 1;
        var repromptText = this.t("TELL_QUESTION_MESSAGE", questionIndexForSpeech.toString(), spokenQuestion);

        for (var i = 0; i < ANSWER_COUNT; i++) {
            repromptText += (i+1).toString() + ". " + roundAnswers[i] + ". "
        }

        speechOutput += userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("SCORE_IS_MESSAGE", currentScore.toString()) + repromptText;

        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentQuestionIndex": currentQuestionIndex,
            "correctAnswerIndex": correctAnswerIndex + 1,
            "questions": gameQuestions,
            "score": currentScore,
            "correctAnswerText": translatedQuestions[gameQuestions[currentQuestionIndex]][Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]][0]
        });

        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), repromptText);
    }
}
*/
function isHelperSlotValid(intent) {
    var answerSlotFilled = intent && intent.slots && intent.slots.Helper && intent.slots.Helper.value;
    var isValid = false;

    if (answerSlotFilled)
    {
        var thisNote = intent.slots.Helper.value.toLowerCase().trim();
        thisNote = thisNote.replace(/[^a-zA-Z]/gi, '');
        if (questions.helper.filter(function (e) { return e.helper.toLowerCase().trim() == thisNote }).length == 1)
        {
            console.log('Valid: ' + answerSlotFilled);
            isValid = true;
        }
        // check for back
        if (thisNote === 'back')
            isValid = true;


    }

    return isValid;
}

function isDestinationSlotValid(intent) {
    var answerSlotFilled = intent && intent.slots && intent.slots.Destination && intent.slots.Destination.value;
    var isValid = false;

    if (answerSlotFilled) {
        console.log('Data: ' + answerSlotFilled);
        var thisNote = intent.slots.Destination.value.toLowerCase().trim();
        thisNote = thisNote.replace(/[^a-zA-Z ]/gi, '');
        var filtered = questions.data.filter(function (e) { return e.country.toLowerCase().trim() === thisNote });
        console.log('Filter: ' + thisNote + ' : ' + filtered.length);
        if (filtered.length == 1) {
            var flyList = this.attributes['flyOptions'];
            var thisCountry = filtered[0].countryId;
            console.log('Valid: ' + answerSlotFilled + ' : ' + JSON.stringify(flyList) + '  ' + thisCountry);
            var filteredValid = flyList.filter(function (e) { return e == thisCountry });
            if (filteredValid.length == 1)
            isValid = true;
        }
        // check for back
        if (thisNote === 'back')
            isValid = true;
    }

    return isValid;
}


function isDecideSlotValid(intent) {
    var answerSlotFilled = intent && intent.slots && intent.slots.Decision && intent.slots.Decision.value;
    var isValid = '';

    if (answerSlotFilled) {
        var thisNode = intent.slots.Decision.value.toLowerCase().trim();
        thisNode = thisNode.replace(/[^a-zA-Z]/gi, '');
        if (thisNode === 'ask' || thisNode === 'fly')
            isValid = thisNode;


    }

    return isValid;
}
function getDestination(intent) {
    var thisNote = intent.slots.Destination.value.toLowerCase().trim();
    thisNote = thisNote.replace(/[^a-zA-Z ]/gi, '');
    return questions.data.filter(function (e) { return e.country.toLowerCase().trim() === thisNote });
}


function getHelper(intent)
{
    var thisNote = intent.slots.Helper.value.toLowerCase().trim();
    thisNote = thisNote.replace(/[^a-zA-Z]/gi, '');
    var insData = questions.helper;
    for (var j = 0 ; j < insData.length ; j++) {
        //console.log(insData[j].helper.toLowerCase().trim() + '  ' + thisNote);
        if (insData[j].helper.toLowerCase().trim() === thisNote) {
            var id = insData[j].helperId;
            return insData[j].helper;
            break;
        }
    }
    return '';
}

function getIncorrectClue()
{
    var data = questions.incorrect;
    var thisId = getRandomNumber(0, data.length);
    return data[thisId];
}

function getRandomTreasure()
{
    var data = questions.treasure;
    var thisId = getRandomNumber(0, data.length);
    return data[thisId].treasure;
}

function getWinText()
{
    var data = questions.gameover;
    var thisId = getRandomNumber(0, data.length);
    return data[thisId];
}

function getTimeOutText() {
    var data = questions.timeout;
    var thisId = getRandomNumber(0, data.length);
    return data[thisId];
}

function checkIfGameOver() {
    var currentTime = moment(this.attributes['currentTime']);
    var endTime = moment(this.attributes['endTime']);
    var diff = currentTime.diff(endTime);
    if (diff >= 0)
        return true;

    return false;
}

function getHelperClue(intent) {
    var thisNote = intent.slots.Helper.value.toLowerCase().trim();
    thisNote = thisNote.replace(/[^a-zA-Z]/gi, '');
    var insData = questions.helper;
    for (var j = 0 ; j < insData.length ; j++) {
        //console.log(insData[j].helper.toLowerCase().trim() + '  ' + thisNote);
        if (insData[j].helper.toLowerCase().trim() === thisNote) {
            var id = insData[j].helperId;
            var trivia = this.attributes['trail'];
            console.log('into data');
            for (var i = 0 ; i < trivia[this.attributes['currentStep']].helper.length ; i++) {
                console.log(trivia[this.attributes['currentStep']].helper[i] + ' : ' + id);
                if (trivia[this.attributes['currentStep']].helper[i] == id) {
                    // Get clue at i
                    var clueid = trivia[this.attributes['currentStep']].clue[i];
                    var country = trivia[this.attributes['currentStep']].country;
                    var clue = questions.data[country]['q' + clueid];
                    return clue;
                }
            }
            break;
        }
    }
    return '';
}

function getCountryList()
{
    var trivia = this.attributes['trail'];
    // this is to be in the list
    var currentStep = this.attributes['currentStep'];
    console.log('cS: ' + currentStep);
    var country = trivia[currentStep].country;
    var cntList = [];
    cntList.push(country);
    var allCntList = [];
    allCntList.push(country);
    allCntList.push(this.attributes['startCountry']);
    console.log('> ' + JSON.stringify(cntList));
    if(currentStep == 0)
    {

    }
    else if(currentStep == 1)
    {
//        cntList.push(this.attributes['startCountry']);
        console.log('>> ' + JSON.stringify(cntList));
    }
    else
    {
  //      cntList.push(trivia[currentStep - 1].country);
        allCntList.push(trivia[currentStep - 1].country);
        console.log('>>> ' + JSON.stringify(cntList));
    }

    var data = questions.data;
    for (var i = 0 ; i < trivia.length ; i++)
    {
        allCntList.push(trivia[i].country);
    }
    console.log('All Cnt> ' + JSON.stringify(allCntList));
    var id = [];
    var cCnt = 0;
    for (var i = 0 ; i < data.length ; i++) {
        var thisId = getRandomNumber(0, data.length);
        while (id.filter(function (e) { return e == thisId }).length > 0) {
            thisId = getRandomNumber(0, data.length);
        }
        id.push(thisId);
        var thisCountry = data[thisId];
        if (allCntList.filter(function (e) { return e == thisCountry.countryId }).length == 0) {
            var cntName = thisCountry.countryId;
            cntList.push(cntName);
            cCnt++;
            if (cCnt >= 3)
            break;
        }
    }

    console.log('Cnt> ' + JSON.stringify(cntList));

    var sh = shuffle(cntList);

    return sh;
}

function getCountryListIncorrect() {
    var trivia = this.attributes['trail'];
    // this is to be in the list
    var currentStep = this.attributes['currentStep'];
    var rightStep = this.attributes['rightStep'];
    console.log('cS: ' + rightStep);
    var cntList = [];
    var allCntList = [];
    console.log('> ' + JSON.stringify(cntList));
    if (currentStep == 0) {

    }
    else if (currentStep == 1) {
        cntList.push(this.attributes['startCountry']);
        allCntList.push(this.attributes['startCountry']);
        console.log('>> ' + JSON.stringify(cntList));
    }
    else {
        cntList.push(trivia[rightStep - 1].country);
        allCntList.push(trivia[rightStep - 1].country);
        console.log('>>> ' + JSON.stringify(cntList));
        console.log(trivia[rightStep - 1].country);

    }
    /*
    var data = questions.data;
    for (var i = 0 ; i < trivia.length ; i++) {
        allCntList.push(trivia[i].country);
    }

    var id = [];
    var cCnt = 0;
    for (var i = 0 ; i < data.length ; i++) {
        var thisId = getRandomNumber(0, data.length);
        while (id.filter(function (e) { return e == thisId }).length > 0) {
            thisId = getRandomNumber(0, data.length);
        }
        id.push(thisId);
        var thisCountry = data[thisId];
        if (allCntList.filter(function (e) { return e == thisCountry.countryId }).length == 0) {
            var cntName = thisCountry.countryId;
            cntList.push(cntName);
            cCnt++;
            if (cCnt >= 4)
                break;
        }
    }

    */
    var sh = shuffle(cntList);

    return sh;
}


function shuffle(array) {
    var currentIndex = array.length, temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }

    return array;
}
var getRandomNumber = function (min, max) {
    return Math.floor(Math.random() * (max - min) + min);
}

var getCardString = function(str)
{
    return str.replace("<say-as interpret-as='interjection'>", "")
                .replace('<say-as interpret-as="interjection">', "")
                .replace("</say-as>", '');
}
gamelogic.jsJavaScript
Contains the Code for building the Game
"use strict";

var questionCount = 7;  // The number of questions available per city.
module.exports =
{
    buildTreasureTrail : function (startCountry) {
        
        return buildTrail(startCountry);
    },
    getStartCountry : function() {
        return getRandomCountry([]);
    }
};
var start = function()
{
    debugger;
    var cnt = getRandomCountry([]);
    var trail = buildTrail(cnt);
    document.getElementById('dd').innerHTML = 'Staring > ' + cnt + '<br/><br/>Trail:<br/><br/>' + JSON.stringify(trail);
}
var buildTrail = function (startCountry)
{
    debugger;
    var trail = [];
    var country = [];
    var helpers = [];
    country.push(startCountry);
    for (var i = 0 ; i < 5 ; i++) {
        var cnt = getRandomCountry(country);
        country.push(cnt);
        var helper = getRandomHelper(helpers);
        for(var x = 0 ; x < helper.length ; x++)
        helpers.push(helper[x]);
        var clue = getRandomClues(cnt);
        trail.push({
            'country': cnt,
            'helper': helper,
            'clue': clue
        });
    }

    return trail;
}

var getRandomNumber = function(min, max)
{
    return Math.floor(Math.random()*(max-min)+min);
}

var getRandomCountry = function(cnt)
{
    var cntFound = false;
    var cntName = 'Not Found';
    var data = questions.data;
    var id = [];
    for (var i = 0 ; i < data.length ; i++) {
        var thisId = getRandomNumber(0, data.length);
        while (id.filter(function (e) { return e == thisId }).length > 0)
        {
            thisId = getRandomNumber(0, data.length);
        }
        id.push(thisId);
        var thisCountry = data[thisId];
        if (cnt.filter(function (e) { return e == thisCountry.countryId }).length == 0) {
            cntName = thisCountry.countryId;
            break;
        }
    }

    return cntName;

}

var getRandomHelper = function (helper) {

    var cntFound = 0;
    var cntName = [];
    var data = questions.helper;
    var id = [];

        for(var i = 0 ; i < data.length ; i ++)
        {
            var thisId = getRandomNumber(0, data.length);
            while (id.filter(function (e) { return e === thisId }).length > 0) {
                thisId = getRandomNumber(0, data.length);
            }
            id.push(thisId);

            var thisHelper = data[thisId];
            if (helper.filter(function (e) { return e == thisHelper.helperId }).length == 0) {
//                if (helper.indexOf(thisHelper) == -1) {
                //Not In the array!
                cntName.push(thisHelper.helperId);
                cntFound++;
                if(cntFound >= 3)
                break;
            }
        }

    return cntName;

}

var getRandomClues = function (cnt) {

    var data = questions.data;
    var id = [];
    var clues = [];
    var thisCountry = data.filter(function (e) { return e.countryId == cnt });
    if (thisCountry.length > 0) {
        for(var i = 1 ; i <= questionCount ; i++)
        {
            var thisId = getRandomNumber(0, questionCount);
            while (id.filter(function (e) { return e == thisId }).length > 0) {
                thisId = getRandomNumber(0, questionCount);
            }
            id.push(thisId);
            clues.push(thisId);
            //clues.push(thisCountry[0]["q" + thisId]);
            if(clues.length >= 3)
            {
                break;
            }
        }
    }

    return clues;

}

var questions = {
    data: [
        { 'countryId': 0, 'country': 'India', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 1, 'country': 'America', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 2, 'country': 'United Kingdom', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 3, 'country': 'Algeria', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 4, 'country': 'Egypt', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 5, 'country': 'Kuwait', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 6, 'country': 'Singapore', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 7, 'country': 'Australia', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 8, 'country': 'Sri Lanka', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },
        { 'countryId': 9, 'country': 'China', 'q0': 'q0', 'q1': 'q1', 'q2': 'q2', 'q3': 'q3', 'q4': 'q4', 'q5': 'q5', 'q6': 'q6' },


    ],

    helper:
        [
            { 'helperId': 0 , 'helper': 'banker'},
            { 'helperId': 1 , 'helper': 'historian'},
            { 'helperId': 2 , 'helper': 'librarian'},
            { 'helperId': 3 , 'helper': 'teacher'},
            { 'helperId': 4 , 'helper': 'doctor'},
            { 'helperId': 5 , 'helper': 'shopkeeper'},
            { 'helperId': 6 , 'helper': 'police'},
            { 'helperId': 7 , 'helper': 'artist'},
            { 'helperId': 8 , 'helper': 'traveller'},
            { 'helperId': 9 , 'helper': 'architect'},
            { 'helperId': 10 , 'helper': 'hotelier'},
            { 'helperId': 11 , 'helper': 'manager'},
            { 'helperId': 12 , 'helper': 'pilot'},
            { 'helperId': 13 , 'helper': 'businessman'},
            { 'helperId': 14, 'helper': 'professor' }

        ]

};
constants.jsJavaScript
To define static data for the Game Engine
"use strict";

module.exports = Object.freeze({
    //Amazon Alexa Skill App Id
    appId: '',
    //Flickr API Key
    apiKey: '',
    //Flickr API Secret
    apiSecret: '',
    //Flicker User ID
    userId: '',
    //  DynamoDB Table name
    dynamoDBTableName: 'UKTreasureHuntTable',

    states : {
        START_MODE : '',
        CLUE_MODE: '_CLUE_MODE',
        DECIDE_MODE: '_DECIDE_MODE',
        FLY_MODE: '_FLY_MODE',
        HELP_MODE: '_HELP_MODE'
        
    },

    appname: 'U.K. Treasure Hunt'

});
UtterancesPlain text
Utterances used in Alexa Skill
DecideIntent I want to {Decision}
DecideIntent {Decision} for Clue further
DecideIntent {Decision} to Next Destination
DecideIntent I want to {Decision} for Clue Further
DecideIntent I want to {Decision} for Clue
DecideIntent I want to {Decision} to Next Destination
AskIntent I want to ask {Helper}
AskIntent Ask {Helper}
AskIntent Please Ask {Helper}
FlyIntent I want to fly to {Destination}
FlyIntent Fly to {Destination}
FlyIntent To {Destination}
FlyIntent Next {Destination}
FlyIntent Next destination is {Destination}
FlyIntent Take me to {Destination}
FlyIntent Fly me to {Destination}
LaunchIntent Launch Lost Treasure
LaunchIntent Ask U.K. Treasure Hunt to start a new trail
LaunchIntent Tell U.K. Treasure Hunt to start a new trail
LaunchIntent Open U.K. Treasure Hunt
LaunchIntent Start U.K. Treasure Hunt
Intent SchemaJSON
Intent Schema used for Alexa Skill
{
  "intents": [
    {
      "slots": [
        {
          "name": "Decision",
          "type": "DECIDE"
        }
      ],
      "intent": "DecideIntent"
    },
    {
      "slots": [
        {
          "name": "Helper",
          "type": "HELPER"
        }
      ],
      "intent": "AskIntent"
    },
    {
      "slots": [
        {
          "name": "Destination",
          "type": "COUNTRY"
        }
      ],
      "intent": "FlyIntent"
    },
    {
      "intent": "LaunchIntent"
    },
    {
      "intent": "AMAZON.StartOverIntent"
    },
    {
      "intent": "AMAZON.RepeatIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    },
    {
      "intent": "AMAZON.YesIntent"
    },
    {
      "intent": "AMAZON.NoIntent"
    }
  ]
}

Credits

22e4162eebe9ce7610c2901bac13a306
Khyati Majmudar

Mobility and Data Analytics Entrepreneur

Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Christmas Gift Box
Intermediate
  • 3,679
  • 595

Full instructions

Christmas Gift Box plays music and sends an email when it is opened.

IoT Red Phone
Intermediate
  • 2,760
  • 15

Work in progress

The phone will ring if you have an alert in your AWS Cloudwatch. If you pick up the handset, it tells you whats wrong.

AWS IoT Environment for Home Assistant
Intermediate
  • 2,207
  • 13

Work in progress

Home Assistant is an automation platform that can track and control all kinds of devices and automate actions, which fits well with AWS IoT.

Real-Time Workspace Occupancy Sensing Based on AWS IoT
Intermediate
  • 2,218
  • 12

Sensor-based presence detection for individual workstations: capturing occupancy trends and space utilization in real-time.

Bible Bee
Intermediate
  • 51
  • 0

Full instructions

A wonderful skill called BibleBee which tells you amazing unknown facts about THE GREATEST MAN WHO EVER LIVED ON THE EARTH - JESUS CHRIST. L

Bible Bee

Team care world

DRS for Sanitization needs of Baby
Intermediate
  • 1,180
  • 22

Full instructions

My Idea is about designing Amazon DRS enabled vending box for sanitizing needs of baby (i.e. baby diapers, baby soap and baby wipes).

Add projectSign up / Login