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:
-
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.
-
Next, go to VCS | Git | Remotes. A dialog should appear listing the existing remote (your personal repository).
-
Press the small plus button. This brings up the Define Remote dialog. Enter
release
for the name and this for the URL: https://github.com/cs125-illinois/Spring2020-MP-Release.git -
Press OK on both dialogs. You’ve added the remote.
-
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.
-
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. -
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:
startActivity(intent);
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 edu.illinois.cs.cs125.spring2020.mp
) 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
inAreaDivider
-
10 points for implementing
getXCells
andgetYCells
inAreaDivider
-
10 points for implementing
getXIndex
andgetYIndex
inAreaDivider
-
10 points for implementing
getCellBounds
inAreaDivider
-
10 points for implementing
renderGrid
inAreaDivider
-
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.