--- title: Project 2, Fall 2020 tags: Projects-F20, Project 2 GA: UA-128096607-1 --- # Project 2: Captured by Candy Uh oh! Doug got lost in the twists and turns of Kathi's Kandy Shop. Now he's got to find his way out... <center><img style="width:50%;height:50%" src="https://i.imgur.com/6VzUNpt.jpg"></center> ## Support This can definitely be a hard project. In addition to the Design Check, feel free to come to [TA Hours](https://cs.brown.edu/courses/csci0111/fall2020/calendar.html), or post on [Campuswire](https://campuswire.com/c/G2F5490D5) for help with the project. Also, please check the [Project 2 FAQs post](https://campuswire.com/c/G8DE0A2C4/feed/2077)! Y'all got this! :) ## Due Date Information Unlike project 1, there will not be a pre-design check submission. There will still be a design check and implementation phase. **Out:** Tuesday, October 27th **Design check sign-up:** Saturday, October 31th, 11:59pm EST **Design check dates:** Sunday, November 1st-Friday, November 6th (see TA-specific appointment calendar) **Design check group submission deadline:** two hours before your design check **In:** Friday, November 13th 9pm EST ## Summary {%youtube gMrVSYP0fr8 %} If you're having trouble viewing the video above, you can find it [here.](https://www.youtube.com/watch?v=gMrVSYP0fr8) Note that the images used in our maze will differ from the ones used above. In this project, you will be creating a maze game! The user will navigate a character around Kathi's Kandy Shop using key presses and mouse clicks. The maze will contain some special items with various effects that will be detailed below. The goal of this game is help virtual Doug find the maze's exit so he can leave the candy shop. *Note: the video above shows the maze functionality with different special items. The Snickers correspond to the bananas, the candy canes correspond to the apples, the Twizzlers correspond to the tomato, and the Pop Rocks correspond to the circles (portals)*. The maze will be populated based on a configuration Google Sheet which you can modify to make your own maze. The game will be played using a Pyret `reactor`. The reactor will run on a `GameState` datatype that you define; the `GameState` data will evolve as the game progresses. For the design check, you will be laying out the datatypes that will capture the necessary game information, and thinking through the tasks required to make the game run. Unlike Project 1, **a lot of the work for this project will happen for the design check, including writing some of the code.** For the final handin, you will be implementing the functions and reactor required to make the game run. *After all of the design checks are done, we will provide our solution to the design check phase, which you can use if you wish in producing your implementation for the final handin.* ::: info Project Learning Goals - Creating and using your own datatypes. - Using recursion to process various types of lists. - Breaking down complex goals into discrete, solveable tasks. - Using tables for code configuration rather than as datasets. ::: ## Files to Submit on Gradescope **Design check:** - `project-2-design-check.pdf` under *Project 2 Design Check* (one per project group) - `captured-by-candy.arr`, which will contain the implemented function `get-item` and datatypes for `GameState` and other necessary datatype under *Project 2 Design Check* (one per project group) **Final handin:** - The completed `captured-by-candy.arr` under *Project 2* ( (one per project group, or per person) - `project-2-src.pdf` under *Project 2 Socially Responsible Computing* (one per person) ## Important Notes Please take a look at the [updated Project Logistics Handout](https://hackmd.io/@cs111/projectlogistics) for an overview of projects logistics. These are largely the same as Project 1 logistics with the following major changes: - There is no pre design check note taking submission. - Project groups in Project 2 will be smaller, and everyone will still have the opportunity to complete the implementation phase individually if they wish. ## The Project ### A Maze Game! You will be making a maze in Pyret. The maze's layout will be dependent on a Google sheet. The Google Sheet we provide creates a maze that is 35 squares per "row" and 19 squares per "column" (19x35), but you can add or remove rows, columns, and items as you please and make the maze your own! The goal of the game is for the (human) player to navigate Doug to the door at the exit. The maze will also have some number of special items scattered throughout that Doug can collect and use. The items will be populated based on another Google Sheet. The entire maze should be surrounded by one layer of walls (except at the end location), so you don't have to deal with the player moving outside of the maze and it is clear to the player where they need to navigate to in order to complete the game. For the project, you will make write code to complete the following main tasks: * "Render" (draw) the maze, its items, and Doug * Create the logic that will the (human) player to use the mouse and keyboard to navigate the Doug around the maze #### The Player and Character The current position of the player in the maze is represented with an image of the Doug character. The player moves Doug using the `w` (up), `a` (left), `s` (down), and `d` (right) keys. The player cannot walk through walls of the maze, but can move through empty space. As an **optional** add on, you have the choice to make the character turn based on the direction they are walking (as demonstrated in the video at the top of the assignment). Implementing this feature will give you extra practice with datatypes and code design (but again it is entirely optional) and will add +1 point to make up any point losses in functionality. To accomplish this, we're giving you access to the images `doug-up.png`, `doug-down.png`, `doug-left.png`, and `doug-right.png` for the various orientations of Doug. #### Items You will implement either ++gadgets++ or ++portals++ into the game. **You only need to implement one of these to get full credit**. You may do both if you want, but you will not get extra credit. However, if you do both, it will be fun and we will grade the two implementations individually---the grade that is higher will be your grade for the project. There can be an arbitrary number of these items placed on the maze. Items are picked up when the player moves into their cells; gadgets are immediately consumed, and portals are "held on to" until use. If multiple portals are collected, Doug will be able to "hold on to" all of them - and will only lose one each time he uses a portal. Either option will be difficult in its own way; we do not think either is significantly easier than the other. :::info If you want to implement a different item (with different behavior from these), you must [email the HTAs](mailto:cs0111htas@lists.brown.edu) for approval before your design check. ::: - **Gadgets**: If you implement gadgets, your character needs to have *stamina*. Stamina is a measure of energy often used in video games. In Captured by Candy, your character's stamina depletes by moving. If your character runs out of stamina, it's game over. There are three things you can encounter in the maze: Snickers, candy canes, and Twizzlers. - Finding a **Snickers** ![snickers](https://i.imgur.com/ypvHjJs.png) replenishes Doug's stamina to its original value. - Finding a **candy cane** ![candy-cane](https://i.imgur.com/FYzxwvH.png) heals Doug for some fixed amount of stamina. - Stepping on a **Twizzler** ![twizzlers](https://i.imgur.com/OQEXU3k.png) reduces Doug's stamina to some low, fixed amount. If the current stamina is lower than this fixed amount, then the game should end. For example, if the character's stamina is 20 and they move onto Twizzlers, they may move down to 7 stamina. Then moving onto a candy cane may heal them to 7 + 8 = 15 stamina, and finding a Snickers will heal them to their original stamina (say, 30). Normal movement reduces stamina by 1 per cell. Think carefully about when you want to update the player’s stamina. There should be a visual indication of the character's stamina (in our sample, it's the yellow bar on the right, but you can handle this differently if you wish). - **Portals (Pop Rocks)**: Your character can carry one or more portals (you may choose the limit), but starts with no portals. When the character has a portal (Pop Rocks) and the user clicks some square on the screen, the character will move there *as long as the cell is within some reasonable range of the character's current location.* You can choose this range, but make sure it doesn't allow the user to easily teleport to the end of the maze! Each portal can be used only once. After the player uses all their portals, clicking on the maze should not do anything. To compute how far the user is trying to move the character, you can use the distance formula, with the change in the $x$-coordinate $\Delta x$ and the change in the $y$-coordinate $\Delta y$: $$D = \sqrt{\Delta x^2 + \Delta y ^ 2}$$ For example, if the player is at $(3, 8)$ and wants to move to $(6, 4)$, $D = \sqrt{(6 - 3)^2 + (4 - 8)^2} = \sqrt{9 + 16} = 5$. This is a "birds-eye view" of distance. #### Starting, Winning, and Losing The player/character will start at a location of your choosing. The information of where they start should be hardcoded through constants in your code. The player wins the game upon reaching the exit at a location that you set. This information should also be hardcoded through constants and should match the information in your Google sheet. We recommend having the end location on one of the edges of the maze so that it is clear when playing the game where the exit is located. The player loses the game if they run out of stamina. If you don't implement gadgets, the player doesn't have to worry about losing stamina. Upon winning or losing, the game can simply close. You may also choose to somehow inform the player that they have won or lost (as in Lab 5), but this is not a requirement. :::info A video-based overview of the spreadsheets and how the gameplay works are in [**this video**](https://www.youtube.com/watch?v=Zy3hWHe4X20&feature=youtu.be). This is the same as the one above! ::: ### Implementation Details #### Configuring the Maze (in Google Sheets) - Gadgets spreadsheet: [link](https://docs.google.com/spreadsheets/d/1IyqpqrRmGVLThtsEp7-JJDRIdncaVce6fLmJWZBjUz8/edit?usp=sharing) - Portals spreadsheet: [link](https://docs.google.com/spreadsheets/d/1Jt90nPp_qpoFg5oRFwiBCSWJWCZbecWsRHnWxbtwYGY/edit?usp=sharing) - Both items spreadsheet: [link](https://docs.google.com/spreadsheets/d/1nZxCyHtWOWXUbKOzlRAJ14ImwOKkBcGNGtpHFcV7RWk/edit?usp=sharing) Use the spreadsheet appropriate for your item implementation. Feel free to modify the maze layouts and item populations! See #2 in the "Support Code" section (below) for how to load the sheets. Each spreadsheet has two sheets: `maze-layout` and `items`. - The `maze-layout` sheet determines which parts of the maze are walls and which are blank and therefore where the player can walk. "x" corresponds to a wall, and "o" corresponds to a floor. - The `items` sheet contains a list of items that will be placed on the maze. The $x$ column is the distance from the left side of the screen, and the $y$ column is the distance from the top of the screen. You will need to edit this sheet to put items in the appropriate places. Check out the images in this [folder.]( https://cs.brown.edu/courses/csci0111/fall2020/data/project-2/index.html) :::info **Note 1:** Positions are zero-indexed; the row `"Snickers", 1, 7, "snickers.png"` corresponds to a ![snickers](https://i.imgur.com/ypvHjJs.png) being placed in the 2nd column and the 8th row. **Note 2:** You do not need to do any error checking for items being placed in invalid locations (like on walls or off the maze). ::: | Name | Image | | -------- | -------- | | Maze Sheet | ![](https://i.imgur.com/KW238Gr.png) | | Items Sheet| ![](https://i.imgur.com/YHuX7rB.png) | <!-- find a new photo that has funtionally the same information but with the correct item names and items --> #### Using Reactors to Create Games Remember the cupcake and plate program from Lab 5? The position of the cupcake was captured with a `Number`: on each tick of time, the `on-tick` function produced a new `Number` value. It also had a function to draw the cupcake based on the current `Number`. All animations in Pyret have a similar structure: there is a datatype that captures the current information for the animation (positions, colors, attributes of characters, etc), and a separate function that takes a value of that datatype and draws it. Pyret calls these functions alternately: draw the current information, update it, draw it, update it, draw it, and so on. For games based on user interaction, we want the information to update when the user presses keys (or the mouse). Rather than using the `on-tick` from the ghost program, we use a different reactor function called `on-key`, which takes the game information and name of key pressed (as a string) and produces new game information. In this case, Pyret alternates between calling `on-key`, `to-draw`, `on-key`, `to-draw`, etc. Thus, to make a game, you need a datatype that captures the information that changes as the game runs, you need a function that computes a revised datatype based on keys pressed, and you need a function that draws the current information. Pyret does the work of calling these functions to run your game. You have seen the reactor properties `init`, `to-draw`, `on-key`, `stop-when`, and `close-on-stop`. If you are implementing portals (Pop Rocks), you will also need to use the `on-mouse` function, which works similar to the `on-key` function; check out [the `on-mouse` documentation](https://www.pyret.org/docs/latest/reactors.html#%28part._on-mouse%29) for more. (for this, Pyret adds `on-mouse` to the rotation of functions it calls.) You can refresh yourself on reactor properties [here](https://www.pyret.org/docs/latest/reactors.html). You may also want to look at your code or the [solutions to Lab 5](https://code.pyret.org/editor#share=1Pj2-y4SBpgpxcZp7x0g4CZCS6wVcmwa0&v=8c4da7d), which was on reactors. ### Support Code You will be given support code that provides four functions: 1. `load-texture :: (String -> Image)` This function will load the images you can use to build up your game. Given a name of a file from the [project 2 image directory](https://cs.brown.edu/courses/csci0111/fall2020/data/project-2/index.html), `load-texture` will return that image. Every image (walls, empty squares, the player, gadgets, and portals) is 30x30 (pixels). **Examples:** - `load-texture("snickers.png")` returns this `Image`: ![snickers](https://i.imgur.com/ypvHjJs.png) - `load-texture("pop-rocks.png")` returns ![pop-rocks](https://i.imgur.com/xjVOdmb.png) 2. `load-items :: (String -> Table)` This function, given the ID of a spreadsheet, loads the `"items"` sheet into a table with columns `"name"`, `"x"`, `"y"`, and `"url"`. 3. `load-maze :: (String -> List<List<String>>)` and `load-maze-n :: (String, Number -> List<List<String>>)` This function, given the ID of a spreadsheet, loads the maze into a list of lists of the letters in the `maze-layout` sheet. If you change the number of columns, you must use `load-maze-n` which is the same as `load-maze` except it has a second parameter which is the number of columns to load. The resulting list looks like this: ![letter-array](https://puu.sh/BwKLQ/0337829e2d.png =280x) 4. `get-maze-index :: (Number -> Number)` **(used for portals only)** The reactor `on-mouse` function takes in $x$ and $y$ coordinates that do not directly correspond to which row and column in the maze the user clicked on. Because of this, `get-maze-index` is a function that takes in the coordinate that is input to `on-mouse` and converts it to a game grid coordinate. For example, if the `x`-coordinate clicked is 334, `get-maze-index(334)` returns 11 (for the 12th column). ## Deadline 1: Sign up for a design check All you have to do for the first deadline is signup for a design check with your project group (there is no pre-design check individual submission!) Since groups are smaller this time around, please only sign up for a single slot. **Note: If you haven’t received an email with your group assignment, reach out to the HTAs immediately.** ## Deadline 2: Design Check ### Requirements Unlike Project 1's Design Check, you'll be writing and submitting some code for Project 2's. There are two types of questions for the Design Check: "Pen & Paper" and "Coding". For the Pen & Paper questions, come to your design check prepared to talk about your answers in the`project-2-design-check.pdf` file that your group submitted. For the Coding questions, write the code in `captured-by-candy.arr` (this is the same file you'll be working with for your final submission). Submit both files to Gradescope at least two hours before your design check starts. We recommend doing the questions in order as much as possible, as each question will help you think about the next. #### Basic Project Setup 1. First, decide which item you will be implementing (gadgets or portals (or both))! 1. Code Setup: 1. a) Make a copy of a [configuration spreadsheet](#Configuring-the-Maze-in-Google-Sheets). In Google Sheets, you can do this by clicking `File > Make a Copy...` b) Share the spreadsheet with your group, and c) Give "Anyone with the link" the ability to view the spreadsheet (you have to go into the Advanced sharing menu to do this). 2. Make a new Pyret file called `captured-by-candy.arr`. a) Copy and paste the code in the block below. b) Replace "INSERT SPREADSHEET ID HERE" in the code you just pasted in with the ID of your spreadsheet c) Make sure it runs. Then look at `maze-data` and `item-data` to get an idea of what they look like. To find the ID of your spreadsheet, open the sheet and check the URL for the highlighted portion below: ![](https://i.imgur.com/L1EaWco.png) :::info Note: If you loaded the support code before 10/31, make sure to copy it over again for the most recent table functions! ::: # load the project support code include shared-gdrive( "cs111-2020.arr", "1imMXJxpNWFCUaawtzIJzPhbDuaLHtuDX") include shared-gdrive( "project-2-support.arr", "1N1pwFonshMA_CH99wH00h0HuuiXRja9A") include image include tables include reactors import lists as L ssid = "INSERT SPREADSHEET ID HERE" maze-data = load-maze(ssid) item-data = load-items(ssid) #| un-comment when ready! maze-game = reactor: init : init-state, to-draw : draw-game, # on-mouse : mouse-click, # portals only on-key : key-pressed, # stop-when : game-complete, # [up to you] # close-when-stop : true, # [up to you] title : "Captured by Candy!" # [you can change this title] end |# #### Design Check Questionsplate 1. **Pen & Paper**: In [Lab 5](https://hackmd.io/@cs111/lab5), you made a reactor where a cupcake moved towards a plate. We can divide the components of the animation into two categories: "Dynamic" (changing throughout the animation) and "Static" (does not change throughout the animation). The position of the plate, the shape and color of the background, and the shape and the color of the plate and cupcake were things that did *not* change as we interacted with our reactor. The cupcake position did change, both on-tick (over time) and on-key (when we pressed certain keys on our keyboard). This is represented in the chart below: | Static | Dynamic | | ------ | -------- | | plate position | Cupcake position | | Background | | | plate and cupcake shapes and colors Look at the gameplay video at the top of the document. Make a similar list or chart of the static and dynamic components of the maze game. 1. **Coding**: Create the datatypes you will need for this game. Keep in mind what you wrote for question 1: only "dynamic" information should be components of the shifting game state.(For reference, you can look at how we created the Coord datatype in Lab 5.) - Create a datatype called `GameState` for the game state. Consider what you want to keep track of in the game: position, items, stamina, or whatever you need. - You'll probably find that you'll need datatypes other than the `GameState`. Define those as well. We'll be expecting you to provide at least one more additional datatype (other than the Posn, if you choose to use it), but most implementations make use of more than this. This is also good style! - For each new datatype you make, make sure to include some examples. Put the data types and examples into `captured-by-candy.arr`. 1. **Pen & Paper**: The reactor `to-draw` function takes in the current `GameState` value and outputs an ```Image``` showing the corresponding frame of the game. Make a list of the tasks required to generate the maze image (3-5 one sentence bullet points). We suggest you spend a decent amount of time on this question: the more thorough you are, the more your TA will be able to help you at design check and the easier your jobs will be for week 2 of the project. 6. **Pen & Paper**: **(1) If you are working on the gadgets version of the game**: The reactor `on-key` function takes in the current `GameState` value and outputs a new `GameState` value that reflects changes based on which key has been pressed. Pick one of the four keys (`w`, `a`, `s`, `d`) and write out the tasks (3-5 one sentence bullet points) needed to compute the new `GameState` based on the current `GameState`. **(2) If you are working on the portals version of the game:** The reactor `on-mouse` function takes in the current `GameState` value, the `x` and `y` value of the position of the mouse event (in the reactor), and a `String` that represents the name of the mouse event. Write out the tasks needed to compute the new `GameState` based on the current `GameState`. **Again, work here should save you considerable time in week 2.** 7. **Pen & Paper**: **(1) If you are working on the gadgets version of the game:** Write one **simple** example of the function named `key-pressed` you will use as `on-key` in the reactor. Consider how the game state will change. **(2) If you are working on the portals version of the game:** Write one **simple** example of the function named `use-portal` you will use as `on-mouse` in the reactor. **Be sure to provide (a) what are the inputs to this function, (b) what is the output of the function, \(c\) what the function is doing, and (d) an example, something along the lines of:** ``` key-pressed(..., "w") is ... ``` or ``` use-portal(..., 35, 70, "button-down") is ... ``` 1. **Coding**: Write a function `get-item(l :: List<List<String>>, x :: Number, y :: Number) -> String` in Pyret that takes in a List of Lists, and get the xth element from the yth list. Once again, make sure this is in `captured-by-candy.arr`, unlike the rest of these questions, which are in the PDF. 2. **Pen & Paper**: Write down a list of 3-5 edge cases that you can think of in the program and how you plan to tackle these edge cases. Some questions to think about: What are the edge cases of the keys being pressed/communicated to the program? What are the edge cases that could happen with the stamina logic? ## Deadline 3: Final Handin The key to tackling a larger assignment like this is to build the features up gradually. For example, get the game working on just basic functionality before adding more advanced features. What might that mean here? 1. Implement a version with just the walls (no gadgets or portals), such that the player can move around the maze while respecting walls. 2. Read in the items (Snickers, candy canes, etc) from the Google Sheet, store them in your data structure(s), and make them show up when you draw the GameState. 3. Get the items to disappear when a player visits their cells. For example, when a player moves to a cell with Twizzlers, the Twizzlers disappear and the stamina decreases. 4. Make the game handle the items (modifying stamina for gadgets or teleporting for portals). These phases correspond to the grading levels for the project (see the Grading section below). You can pass the project even if you don't get beyond phase 1. *We strongly recommend saving a copy of your file after you get each stage working, just in case you need to get back to your last stable version (practicing programmers do this all the time).* ### Grading As always, you will be graded on Functionality, Design/Style, Examples, and the written portion. Key metrics are described below. #### Functionality Compared to the previous project, a larger portion of your grade will come from functionality. To help guide you as you complete your project, we've broken up functionality into three tiers. Feel free to use the categories above as a roadmap as you're implementing, or as a gauge of how far along you are: *Minimum Functionality:* - Maze floors and walls are drawn into the maze based on the spreadsheet. - A character that moves in response to key presses. - Player cannot pass through walls. - Game stops/ends when the character reaches a certain destination. *Mid-tier Functionality:* - All above. - Gadgets or portals (Pop Rocks) are rendered in the maze based on the spreadsheet. - If doing gadgets: your character must have stamina that depletes upon moving. The gadgets do not need to be functional for mid-tier functionality. Upon reaching 0 stamina, the game should end. - If doing portals: upon picking up a portal, your character can teleport. There does not need to be a limit of the portal range or the number of times the player can teleport for mid-tier functionality. *Full functionality:* - All above. - If doing gadgets: Snickers bring the character to full stamina; Twizzlers brings the character to a low stamina; candy canes heal for some amount; items disappear when walked over. - If doing portals: there is a limit to how far the character can teleport and how many times a portal can be used. #### Design/Style * Are you making good use of data classes to store information? * Are you making good use of the reactor and recursion to make sure you're not calling functions unnecessarily? * Have you followed the other guidelines of the style guide? (line length, naming convention, etc.) #### Testing * Do you have at least two examples for helper functions that output things other than an Image? * Do you have thorough testing (try to hit as many tests of edge cases as possible!) for the function(s) that move the character (the ones you use as `on-key`, or `on-mouse`). Test this function thoroughly, covering as many cases as you can. * Have you played your game and made sure it works? We won't be grading explicitly on whether you've played your game or not, but it is an effective (and fun) way to make sure your program works as you expect it to! ## Reflection on Implementation Next, you'll be reflecting on the work you've done. This project was designed to give you practice with organizing and manipulating structured data. Answer the following questions about these topics in a block comment at the bottom of `captured-by-candy.arr`. 1. Our support code represented the maze layout (walls vs floors) as a list-of-lists of strings, rather than a table. What were the advantages and disadvantages of this choice? 2. In this project, you worked with the maze in three formats: the Google Sheet with the configuration of walls, the list-of-lists version, and the image itself. For each representation, briefly describe what it is good and bad for. 3. Describe one key insight that each partner gained about programming or data organization from working on this project. 4. Describe one or two misconceptions or mistakes that you had to work through while doing the project. 5. State one or two followup questions that you have about programming or data organization after working on this project. ## Socially Responsible Computing Finally, you'll be completing an individual reflection on socially responsible computing. **Please be sure to submit these in the form of a pdf.** **Goal:** Students should understand the primary issues with privacy policies, and begin to articulate their impact on different stakeholders. **Task:** Explore privacy policy summaries for sites you use on [Terms of Service, Didn’t Read](https://tosdr.org/). **Task:** Choose two privacy policies on [Terms of Service, Didn’t Read.](https://tosdr.org/) These should be policies for tools you use currently or have used in the past. At least one should *not* be Facebook, Google, Twitter, Amazon, or Apple. For example, you may choose both Twitter and Khan Academy, but you may not choose both Apple and Google. 1. Describe your reaction to each privacy policy, if any. If the policy elicited a reaction from you, explain why you think you had that reaction – and if not, explain why not. 2. For each policy you chose, pick two bullet points from the policy summary, and answer the following questions. **(Because you're analyzing two privacy policies, you should answer these questions for four "bullet points" in total.)** * Did you know **consciously** that this was part of the company’s policy? * Who does this point serve? Consider the interests of the company itself and of the different users of the product(s). * Who might this point hurt, if anyone? Consider the interests of the company itself and of the different users of the product(s). There are no right or wrong answers here. As long as your responses are thoughtful and abide by our general course culture norms, you are free to answer the question however you wish. Your answers should be clear and concise, with enough specifics to show that you are thinking about the questions beyond a surface level. If you are curious about how we grade these portions on responsible computing, and/or want help in approaching them, please reference the [response guide](https://hackmd.io/@cs111/sta-response-guide). **Task:** We want to hear from you! Respond to [this Google Form](https://forms.gle/iTnfdFK3RW8WNeMW6) to give your feedback on socially responsible computing assignments. Your email will be tracked via a separate (linked) form, and your feedback will therefore remain anonymous. **Completion of this form will be worth 2 points on your project grade!** ## Notes on Late Days * If you plan on using one or more of your late days on this project, note that you are only allowed to use as many late days as **the partner with the least number of late days remaining has**. In other words, if one partner has 1 late day left and the other has two late days left, you are only allowed to use 1 late day on this project. As always, the 3-day maximum policy applies. * Although the Socially Responsible Computing portion of the final implentation is an individual handin, it is still considered a part of the final handin, and thus cannot have late days applied to it separately from the group submission (i.e., the group cannot submit the code on-time, and have a single partner only apply late days to their reflection.) There is no difference here if you are completing the implementation phase individually. ## FAQ - What am I supposed to use `on-key` for? - Reactors are the main way you will keep track of the state of the game. One of the useful tools for moving your character will be `on-key`, which performs a specific function when a key is pressed. This is the primary way you will be changing the game state! Everyone will need to determine what the move is and execute the move (if it is valid). If you are implementing gadgets, you will also update Doug's stamina and remove the gadget image from the game board. - What's the difference between `stop-when` and `close-when-stop`? - `stop-when` is used to determine if the game should end. It is called each time the game state changes to see if the most recent move ended the game. If `stop-when` evaluates to `true`, the game will stop; if it evaluates to `false`, the game will continue. `close-when-stop` is useful if you want to close the game window as soon as the game has ended. It does not change as the game state does. - Does it matter whether `key-pressed` checks against capital or lowercase letters? - Yes. As per the example in the snippet we provide in the design check, key-pressed should check its input string against *lowercase* letters (i.e., pressing the `w` key on your keyboard will register as a "w".) ## Campuswire and Feedback - [Campuswire](https://campuswire.com/c/G2F5490D5/) can be your friend for this Project! - Have feedback for the class or for this project? Submit your feedback [here](https://forms.gle/qjEL2oP8TjeRUR4M7