MP1: Area Mode

In the first Machine Project checkpoint, MP0, you started making a cool Android app 1. This checkpoint and all subsequent ones build on that codebase, adding new features and improving the structure of the code.

In this second checkpoint (MP1), you will use your new object-oriented programming skills to package up some game logic into a class that will help you implement a new mode of the game.

In area mode, the objectives that can be captured are rectangular cells on an evenly spaced grid rather than specific targets. Entering a cell captures it—if possible. If at least one capture has already been made, subsequent cells can only be captured if they share a side with the most recently captured cell.

1. MP1 Deadline

Again, deadlines for each checkpoint vary by your deadline group. MP1 is due at:

  • 11:59 PM on Sunday 03/01/2020 for the Blue Group: all labs starting at 3 PM or earlier

  • 11:59 PM on Monday 03/02/2020 for the Orange Group: all labs starting at 4 PM or later

Since MP1 is another multi-week checkpoint, 10% of your grade on it is for submitting code that earns at least 40 points by 11:59PM on Sunday 02/23/2020 (Blue) or Monday 02/24/2020 (Orange). Late submissions will be subject to the MP late submission policy.

2. Getting Started with MP1

2.1. Obtaining MP1

You’ll be working on the same repository for the entirety of the Machine Project, so you already have your GitHub repository ready to go; all that’s missing is some provided UI and the test suite for Checkpoint 1.

To do this we are going to provide you with a remote: an alternate version of the Git repository from which changes can be merged. The one we will provide contains multiple changes to your current project. The release for MP1 adds two important files: the test suite itself and an Android Studio run configuration that will allow you to run the test suites easily. It also modifies MainActivity a bit so the user can choose what mode of game they want to play in your app.

To update your project with the remote and get started on MP1, follow these instructions:

  1. First, commit your work! This makes sure that you can easily undo any problems that the merge may cause. It should complete cleanly, but you never know.

  2. Next, go to VCS | Git | Remotes. A dialog should appear listing the existing remote (your personal repository).

  3. Press the small plus button. This brings up the Define Remote dialog. Enter release for the name and this for the URL:

  4. Press OK on both dialogs. You’ve added the remote.

  5. Get the remote code. Select VCS | Git | Fetch from the menu to download the remote commit. However, it still needs to be merged with your work.

  6. Merge the changes! Now we need to merge the changes from your computer with our remote repository, so go back to the menu and choose VCS | Git | Merge Changes. Check the remotes/release/mp1 branch you just fetched and press Merge! The Version Control pane will appear to inform you of 4 items updated from the server.

  7. If the branches don’t merge properly, please get help right away! Post on the forum, come down to office hours, or get help in lab next week. MP1 is a challenge and we want you to get started right away.

You also need to configure the autograder so that it knows that you’re working on MP1. Open the grade.yaml file in the root of the project, change the checkpoint setting from 0 to 1, and do File | Sync Project with Gradle Files. Running the Grade task should then produce a grade report for Checkpoint 1 rather than Checkpoint 0.

2.2. Late MP0 Submissions

If you didn’t finish the TargetVisitChecker functions in MP0, you can still do MP1. Changing the useProvided setting in grade.yaml from false to true (after updating checkpoint to 1) and doing a Gradle sync will make the app and grader use our correct TargetVisitChecker implementation. That is, calling TargetVisitChecker functions from GameActivity will produce the result from our solution, not your code. If you’re happy with your TargetVisitChecker implementation, leave useProvided set to false to continue using your MP0 code.

5% of the MP1 grade requires a working target mode game, so even if you use our provided TargetVisitChecker functions, you will still need to implement the GameActivity logic of MP0 yourself. If you have not done this, please do so now. Come to office hours if you need help.

If you want to go back later and work on a late MP0 submission for half credit, change the checkpoint setting in grade.yaml back to 0. That tells our grader to do an MP0 grading run. It’s OK if you’ve started working on MP1 or even a later checkpoint when you regrade MP0. The test suites are forward-compatible.

3. Multiple Activities in Android

Most apps have multiple different screens that are shown at different times. To switch to a different activity, code has to launch the new activity using an Intent. An intent specifies what is to be done and provides any extra information needed to do that—kind of like calling a function.

To create an intent to launch an activity, you need to specify the current context 2 and the new activity:

Intent intent = new Intent(this, OtherActivity.class);
// Don't worry about what the .class part means

Once you have an intent, you can pass it to the startActivity function to act on it:


By default, when a new activity is launched, the user can return to the old one by using the back button on the device. To make the old activity completely finish and no longer be available, you can call finish() after the startActivity call.

Additional data that needs to be passed to the new activity can be placed in extras. Intent extras are identified by a string name and can have various kinds of values. Each intent can have many extras. To add an extra, use a putExtra instance method of the intent:

intent.putExtra("name", "Jane Smith");
intent.putExtra("gpa", 4.0);

To access this data from the new activity, use the getIntent function to get the Intent that was used to launch the activity. To extract extras from the intent, call the get<Type>Extra functions, like getStringExtra or getDoubleExtra. The functions to get extras of primitive types require you to specify a default value that will be returned in case that extra wasn’t present. For example:

Intent intent = getIntent();
String name = intent.getStringExtra("name");
double gpa = intent.getDoubleExtra("gpa", 0.0); // 0.0 is the default

If you’d like more information, feel free to refer to Android’s official Intent documentation.

4. Your Goal

When you’re done with MP1, your Campus Snake 125 app will support target mode and the new area mode. In area mode, the map will show a grid of cells and highlight captured cells with green rectangles. There will be a user interface to select the game mode and set game configuration (proximity threshold for target mode, area and cell size for area mode).

MP1 is a step up from MP0, and may seem overwhelming at first. This is normal! As we always recommend: start early, take it one step at a time, get help when you need it, and you’ll be able to build amazing things.

4.1. AreaDivider Class

You may notice after acquiring the Checkpoint 1 test suite that the project can no longer compile. This is because the test code refers to an AreaDivider class that you need to create. So the first order of business is to define that class and the needed functions on it, and you need to make it in the logic directory.

To add a new class file in the Project view, right-click the package folder (logic inside that contains all the existing logic files you’ve been working on and choose New | Java Class. Enter the class name, AreaDivider in this case, in the Name box and press OK. If prompted to add the file to Git, press Add.

You must create the new file in our logic package, the one containing LineCrossDetector and TargetVisitChecker. If you incorrectly create it elsewhere, it will not be accessible during grading.

To see what you need to add to this class, refer to our official Javadoc. You may find our coordinate system figure helpful.

You should finish AreaDivider before moving on to the rest of the MP, so please be sure to start on this section as soon as possible!

4.2. Area Mode Gameplay

Now that we provided the user’s game setup stored in intents and you have your AreaDivider class to help with area division and grid drawing, you can add logic to GameActivity to make area mode games work.

First, GameActivity needs to know the game configuration. Add logic to onCreate to get the intent and record the needed information in instance variables of your design. You will probably want to wrap our provided target mode variable setup in an if statement, then use the other (area mode) branch to create an AreaDivider instance to manage cell boundaries and a boolean[][] to store whether each cell has been visited.

Update setUpMap to check the game mode and render the grid if the game is area mode. This should be very easy because all the work is done by the AreaDivider object. If the game is target mode, markers should still be placed at target positions like in MP0.

Similarly, add a branch to onLocationUpdate with area mode gameplay logic: detect cell capture and show the user’s progress on the map. Initially any cell in the area can be captured. Subsequent captures are only possible of the cell the user is currently in is uncaptured and shares one side with the most recently captured cell 3. When a cell is captured, it should be filled with a green polygon 4. To add a polygon to a Google Maps control, pass a PolygonOptions instance to the map’s addPolygon method. As you read the PolygonOptions method summary, look for two methods that you’ll need: one to add vertices to the polygon and one to set the polygon’s fill color.

To make the custom proximity threshold take effect, tweak your MP0 target mode logic in onLocationUpdate to use your proximity threshold variable instead of a constant.

5. Grading

MP1 is worth 100 points total, broken down as follows:

  • 10 points for implementing isValid in AreaDivider

  • 10 points for implementing getXCells and getYCells in AreaDivider

  • 10 points for implementing getXIndex and getYIndex in AreaDivider

  • 10 points for implementing getCellBounds in AreaDivider

  • 10 points for implementing renderGrid in AreaDivider

  • 10 points for making target mode respect the user’s proximity threshold setting

  • 20 points for making area mode work in NewGameActivity

  • 10 points for having no checkstyle violations

  • 10 points for submitting code that earns at least 40 points by 8 PM on your early deadline day

5.1. Test Cases

Just like on MP0, we have provided a test suite that exhaustively tests your code. You should not modify the test suite, but feel free to examine it to see what it is doing with your code, especially when you’re debugging test failures. Checkpoint1Test is stored in the same folder as Checkpoint0Test, under the test part of the src folder hierarchy.

To run Checkpoint 1 tests, change the run configurations dropdown to Test Checkpoint 1 and press the green run button. You can also run a specific test function using the button in the left margin when looking at the test suite code. After updating grade.yaml, the Grade run configuration that you used in MP0 will grade MP1 instead.

5.2. Submitting Your Work

Follow the instructions from the submitting portion of the CS 125 workflow instructions.

5.3. Style Points

Like in MP0, 10% of your MP1 score is from successful checkstyle validation. One thing checked by checkstyle is the presence of Javadoc documentation on each function and function parameter.

Android Studio can help with this: once you’ve written a function signature, typing /** (the start of a Javadoc comment) right above the function and pressing Enter will insert any necessary @param and @return tags for you to fill out. checkstyle also wants all function parameters to be declared final (like we did in MP0), which means you cannot reassign them inside the function.

6. Cliffhanger

After completing MP1 you may be thinking that it would be nice to bundle all the target mode logic together in one place and all the area mode logic together in another, rather than having all those if statements throughout GameActivity. Later in lecture you’ll learn about a concept called polymorphism that will allow us to do this.

Now that we can create customized games, we’ll want some way to share or join games with other people and see ongoing games' configuration. We’ll start on that in the next checkpoint by connecting the app to a server.

7. Cheating

All submissions on all CS 125 assignments will be checked for plagiarism. You may not submit work done by anyone else, nor may you share your assignment code with others. Please review the cheating policies from the syllabus.

Created 7/14/2020
Updated 7/14/2020
Commit 2091ea3 // History // View
Built 7/14/2020 @ 16:58 EDT