Hyun-woo Park
Published © MIT

Baseball Game

Let's play the baseball game with Alexa. Alexa will make three digit numbers, and you guess.

BeginnerFull instructions provided1 hour1,762
Baseball Game

Things used in this project

Hardware components

Amazon Echo
Amazon Alexa Amazon Echo
×1

Software apps and online services

AWS Lambda
Amazon Web Services AWS Lambda

Story

Read more

Code

baseballgame.py

Python
A lambda code for playing baseball game with alexa
from __future__ import print_function
from random import shuffle

CHANCES = 10


# --------------- Helpers that build all of the responses ----------------------

def build_speechlet_response(title, output, reprompt_text, should_end_session):
    return {
        'outputSpeech': {
            'type': 'PlainText',
            'text': output
        },
        'card': {
            'type': 'Simple',
            'title': "SessionSpeechlet - " + title,
            'content': "SessionSpeechlet - " + output
        },
        'reprompt': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': reprompt_text
            }
        },
        'shouldEndSession': should_end_session
    }


def build_response(session_attributes, speechlet_response):
    return {
        'version': '1.0',
        'sessionAttributes': session_attributes,
        'response': speechlet_response
    }


# --------------- Functions that control the skill's behavior ------------------
def get_random_numbers_for_game():
    numbers = range(1, 10)  # one to nine
    shuffle(numbers)
    return numbers[:3]


def get_welcome_response():
    session_attributes = {}
    card_title = "Welcome"
    speech_output = "Welcome to the Baseball Game. " \
                    "You can start by saying new game. "
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "You can start by saying new game. "
    should_end_session = False

    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))


def handle_session_end_request():
    card_title = "Session Ended"
    speech_output = "Thank you for playing Baseball Game. " \
                    "Have an awesome day! "
    # Setting this to true ends the session and exits the skill.
    should_end_session = True
    return build_response({}, build_speechlet_response(
        card_title, speech_output, None, should_end_session))


def new_game(intent, session):
    card_title = intent['name']
    session_attributes = {}
    should_end_session = False

    session_attributes = {
        'numbers': get_random_numbers_for_game(),
        'chance': CHANCES,
    }

    speech_output = "Now starting new game. " \
                    "I made a three digit number and you have "\
                    + str(session_attributes['chance']) + " chances." \
                    "Guess the three number by saying, " \
                    "Is it three, one, seven?"
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "Guess the number by saying, " \
                    "Is it three, one, seven?"

    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))


def invalid_number(session_attributes, card_title):
    speech_output = "Guess three different numbers."
    reprompt_text = "Guess the number by saying, " \
                    "Is it three, one, seven?"
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, False))


def get_game_result(correct, answer):
    strike = 0
    ball = 0

    for i in range(0, 3):
        for j in range(0, 3):
            if correct[i] == answer[j]:
                if i == j:
                    strike += 1
                else:
                    ball += 1

    return {'strike': strike, 'ball': ball}


def guess_number(intent, session):
    card_title = intent['name']
    session_attributes = {}
    should_end_session = False

    if session.get('attributes', {}) and "numbers" in session.get('attributes', {}):
        session_attributes = session['attributes']

        if 'Number' in intent['slots']:
            reprompt_text = "Guess again."
            number = intent['slots']['Number']['value']

            try:
                number = int(number)
            except:
                # We could not parse it as number
                return invalid_number(session_attributes, card_title)

            # Check range
            if number < 123 or number > 987:
                return invalid_number(session_attributes, card_title)

            numbers = [int(_) for _ in str(number)]

            # Check duplication
            if len(set(numbers)) < 3:
                return invalid_number(session_attributes, card_title)

            session_attributes['chance'] -= 1

            result = get_game_result(session_attributes['numbers'], numbers)

            if result['strike'] == 3:
                # Correct answer
                if session_attributes['chance'] == 9:
                    speech_output = "Fantastic. Are you an lambda function itself? How did you bet? Yes, the number was " + ', '.join([str(_) for _ in numbers]) + ". "
                else:
                    speech_output = "Yes, you got it! The number was " + ', '.join([str(_) for _ in numbers]) + ". " \
                                    + "Succeed in {} tries.".format(CHANCES - session_attributes['chance'])

                reprompt_text = "You can start it again by saying new game. "
                should_end_session = True
            else:
                result_text = ""

                if result['strike'] == 0 and result['ball'] == 0:
                    result_text = "Out. No numbers were matched. "
                else:
                    result_text = "You got "
                    if result['strike'] > 0 and result['ball'] == 0:
                        result_text += "{} strike. ".format(result['strike'])
                    elif result['strike'] == 0 and result['ball'] > 0:
                        result_text += "{} ball. ".format(result['ball'])
                    else:
                        result_text += "{} strike and {} ball. ".format(result['strike'], result['ball'])

                if session_attributes['chance'] > 1:
                    result_text += "You have {} more chances. ".format(session_attributes['chance'])
                elif session_attributes['chance'] == 1:
                    result_text += "You have only one chance. "
                else:
                    result_text += "Sorry, no more chances. "
                    result_text += "It was " + ', '.join([str(_) for _ in session_attributes['numbers']]) + ". "
                    reprompt_text = "You can start it again by saying new game. "
                    should_end_session = True

                speech_output = "Your guess is " + ', '.join([str(_) for _ in numbers]) + ". " + result_text
        else:
            speech_output = "I'm not sure what you're guessing. " \
                            "Please try again."
            reprompt_text = "I'm not sure what you're guessing. " \
                            "Guess the three number by saying, " \
                            "Is it three, one, seven?"
    else:
        speech_output = "You can start by saying new game. "
        reprompt_text = "You can start by saying new game. "

    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))


def finish_game(intent, session):
    session_attributes = {}
    reprompt_text = None
    should_end_session = False

    if session.get('attributes', {}) and "numbers" in session.get('attributes', {}):
        numbers = session['attributes']['numbers']

        speech_output = "The number was " + ', '.join([str(_) for _ in numbers]) + \
                        ". Goodbye."
        should_end_session = True
    else:
        speech_output = "You can start by saying new game. "
        reprompt_text = "You can start by saying new game. "

    return build_response(session_attributes, build_speechlet_response(
        intent['name'], speech_output, reprompt_text, should_end_session))


# --------------- Events ------------------

def on_session_started(session_started_request, session):
    """ Called when the session starts """

    print("on_session_started requestId=" + session_started_request['requestId']
          + ", sessionId=" + session['sessionId'])


def on_launch(launch_request, session):
    """ Called when the user launches the skill without specifying what they
    want
    """

    print("on_launch requestId=" + launch_request['requestId'] +
          ", sessionId=" + session['sessionId'])
    # Dispatch to your skill's launch
    return get_welcome_response()


def on_intent(intent_request, session):
    """ Called when the user specifies an intent for this skill """

    print("on_intent requestId=" + intent_request['requestId'] +
          ", sessionId=" + session['sessionId'])

    intent = intent_request['intent']
    intent_name = intent['name']

    # Dispatch to your skill's intent handlers
    if intent_name == "NewGame":
        return new_game(intent, session)
    elif intent_name == "TheNumberIs":
        return guess_number(intent, session)
    elif intent_name == "WhatIsTheNumber":
        return finish_game(intent, session)
    elif intent_name == "AMAZON.HelpIntent":
        return get_welcome_response()
    elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
        return handle_session_end_request()
    else:
        raise ValueError("Invalid intent")


def on_session_ended(session_ended_request, session):
    """ Called when the user ends the session.

    Is not called when the skill returns should_end_session=true
    """
    print("on_session_ended requestId=" + session_ended_request['requestId'] +
          ", sessionId=" + session['sessionId'])
    # add cleanup logic here


# --------------- Main handler ------------------

def lambda_handler(event, context):
    """ Route the incoming request based on type (LaunchRequest, IntentRequest,
    etc.) The JSON body of the request is provided in the event parameter.
    """
    print("event.session.application.applicationId=" +
          event['session']['application']['applicationId'])

    """
    Uncomment this if statement and populate with your skill's application ID to
    prevent someone else from configuring a skill that sends requests to this
    function.
    """
    # if (event['session']['application']['applicationId'] !=
    #         "amzn1.echo-sdk-ams.app.[unique-value-here]"):
    #     raise ValueError("Invalid Application ID")

    if event['session']['new']:
        on_session_started({'requestId': event['request']['requestId']},
                           event['session'])

    if event['request']['type'] == "LaunchRequest":
        return on_launch(event['request'], event['session'])
    elif event['request']['type'] == "IntentRequest":
        return on_intent(event['request'], event['session'])
    elif event['request']['type'] == "SessionEndedRequest":
        return on_session_ended(event['request'], event['session'])

Credits

Hyun-woo Park

Hyun-woo Park

1 project • 0 followers

Comments