CSC 15 Lab 11: On Permutations, and the Separation of Computation from IO ############################## Part I. ############################## Your goal for this lab is to write a memory teaser game similar to the one demonstrated in class. Your program needs to have at least the same features as my program. For the first part of the assignment, you need to write a program that's independent of any user interface. In my program, there is an array of colors: Colors = ["blue","red","green","yellow","purple","brown","orange","pink","white","gray"] You can replace colors with something else, like (domesticated) animals. The idea is that the player/user is first shown (read) these colors, "color number 0 is blue, color number 1 is red, etc.", then asked a series of questions: "what is color number 2?", etc. Each time an answer is entered, a response (correct/incorrect) is given and a score is tabulated. The player is given a final score at the end along with an appropriate message such as "congratulations, you have perfect memory." 1. Write a function (can be independent of any class) def genpermutation(n): that returns an array of n numbers and which contains each of 0...n-1 exactly once. For example, genpermutation(5) may return [3,4,2,0,1], that is, an array of length 5 containing each of the numbers 0-4. You function needs to be "truly random" and efficient. If you find this too hard to do at first, just use an identity permutation: P = [0]*n for i in range(0,n): P[i] = i return P # returns [0,1,2,3,...,n-1] This makes for a less interesting game, until you can write a better version of the permutation function. You can use this permutation to scramble the Color array as follows (I'll give you some code this time:) # apply permutation P destructively to array A def applyperm(P,A): if len(P) != len(A): return # don't change if not possible to permute B = A.copy() # copy A's contents into B (shallow) for i in range(0,len(B)): B[i] = A[P[i]] for i in range(0,len(A)): # don't combine loops A[i] = B[i] # applyperm Now calling applyperm(genpermutation(len(Colors)),Colors) # will scramble your colors. You want to permute the colors at the beginning so that the game is different each time. You will need to use another random permutation when asking the player for the colors (don't start by asking for color number 0...) Alternatively, you can make the game even harder my using a permutation to read out the numbers and colors at the beginning. 2. Write a class for your game. The rest of your code must go into this class. You can look at the number guessing game example (better version) for ideas as to how to write this class. Note that although it's an Alexa program, the class is completely independent of the Alex interface. As further hint, in my class I have the following instance variables and their initial values: self.state = 0 self.index = 0 # can also use self.state-2 to index Colors self.QuestionOrder = genpermutation(len(Colors)) # order of numbers to ask Although your class should be interface independent, you should write it so that it can be used in both a synchronous or asynchronous (event-driven) environment. ############################## Part II. ############################## In part 2 of this assignment, you will build a user interface for your game. If you're not interested in Alexa, or can't get it to work, you can just write a plain text-based interface using input and print commands (you can just print a bunch of blank lines to scroll the color info out of the way before quizzing the player). To write an Alexa skill, follow the example for the 'hofstra facts' program and download the skeleton lambda_shell.zip folder from the homepage and insert your memorygame.py (or whatever is your program name) into the folder. In your program, to get the user response to a question such as "what is color number 3?", you need to do the following in your "handle" method: def handle(self, handler_input): slots = handler_input.request_envelope.request.intent.slots human_res = slots["answer_value"].value # ... human_res will be a string representing user response (which should be a color) If you have an AWS account, select the "Lambda" service and create a new function. Follow the demonstration in class (choose defaults and the lambda_execution model). Select Python 3.6 (consistent with the .zip folder) and memorygame.handler as the handler (must match the name of your file and the name 'handler' as defined towards the end of your program). Now on the client side, sign into an Amazon developer account and navigate to creating an Alexa skill. For simplicity, you can just select the Edit JSON tab an paste in the following: { "interactionModel": { "languageModel": { "invocationName": "memory teaser", "intents": [ { "name": "AMAZON.FallbackIntent", "samples": [] }, { "name": "AMAZON.CancelIntent", "samples": [] }, { "name": "AMAZON.HelpIntent", "samples": [] }, { "name": "AMAZON.StopIntent", "samples": [] }, { "name": "AMAZON.NavigateHomeIntent", "samples": [] }, { "name": "AMAZON.YesIntent", "samples": [] }, { "name": "AMAZON.NoIntent", "samples": [] }, { "name": "ColorIntent", "slots": [ { "name": "answer_value", "type": "AMAZON.Color" } ], "samples": [ "it is {answer_value}", "is it {answer_value}", "{answer_value}" ] }, { "name": "AMAZON.RepeatIntent", "samples": [ "repeat", "say again", "again" ] } ], "types": [] } } } Now to connect the client side with the server side, you need to select "Endpoint". Select AWS Lambda ARN, then goto the AWS console and copy the arn at the top, which should be something like arn:aws:lambda:us-east-1:129636253206:function:memteaser paste this in the "Default region" slot back at the developer console. Then copy the "Skill ID" from the client side and, on the AWS server side, in the "Add triggers" window select 'Alexa Skills Kit', and paste in the Skill ID into the entry at the bottom. Save. Back on the client side, save the endpoint, go back to the Edit Json tab, click save model, then build. Then, after build is successful, you can then test the program. ## In case of an error, copy the JSON Input from the test window, and goto the AWS side. Select configure test, and create a new test by replacing the default json with the json that produced the error, and click on test. You can examine the details and logs. If you still can't find the error, insert log points into your code like this: logger.info("inside Yes hander, game state is "+str(MyGame.state)") When constructing large strings, remember that numerical values must be converted into strings. The online Alexa Python SDK also have instructions that explain all this, but your best bet is to ask the professor for help if you're having problems.