Murder

Mystery

Colin Sullivan, Steven Chen, Ana Paula Centeno

View Abstract


Overview

A crucial skill for any new programmer to learn is debugging their code. But before you can learn to debug faulty code, you have to learn to efficiently use the debugger. 

This assignment introduces students to debugging techniques such as breakpoints, the debugging toolbar, inspecting variable values, stepping through code, and more. It does this using a Murder Mystery simulation, which is randomly determined by a given ID (the student's school login ID). This simulation is framed as a Clue-style game, with a cast of six characters at a Mansion party. One character is a murderer who pursues and murders the other characters until they are the last one left, or until the night ends.

Many aspects of the simulation are randomized for each user including: player names, size of mansion, rooms of the mansion, number of items, item names/locations, player/murderer decisions, assigned questions, and more.

The MurderMystery.java Driver runs the simulation using Mansion.java and other classes, then it prints 10 questions, allowing students to input answers for each. The student Answers file can be submitted and automatically compared against the correct answers for their questions. Students do NOT have to code to complete this assignment.

 

Metadata

Summary Students debug a murder mystery simulation to answer questions about in-game attributes as well as when in-game characters dropped and picked up items, were murdered, or were at certain times. The students' unique login ID randomly determines characters, rooms, items, decisions, questions, and more.
Audience Targeted towards CS2 students. Assigned at the beginning of the semester, to teach them strategies they can use moving forwards, as well as to reacquaint them with Java code. Game difficulty can be easily adjusted to CS1/APCS level by giving fewer questions, removing some question options altogether, or simplifying game code. 
Topics Java, Debugging, OOP, Simple Data Structures, Conditionals, Loops
Difficulty This assignment can be done in less than a week with some learning support. The assignment can easily be optimally solved with 8 or fewer breakpoints/conditional breakpoints in less than 3 minutes, but will generally take students much longer.
Strengths
  • Questions can be easily solved with specific directions, but cannot be solved by current AI models.
  • Questions are flexible, and can be adjusted. Number of questions assigned or the availible question pool can be edited, to target different skill levels. Game logic can be modified and removed, to simplify certain elements of code.
  • This exercise requires students to read through code, think critically about it, and understand the logic of code they have not written. This is something they will have to do many times throughout their education, but this provides a fun scenario using OOP.
  • Students gain hands on experience breaking down problems to solve with the debugger. They must consider how the game is stored, to analyze their given questions against the code using whatever information they have.
  • Students work directly with edge cases, since many boundary cases with times and certain events drive the game. This allows students to identify how each case is covered for their questions.
  • Randomization based on student login ID gives each student a unique experience when debugging while still allowing them to take similar approaches. Instructors can easily support the variety of student questions, since few conditions are needed for each.
Weaknesses
  • If students do not understand Java objects, it may take time to understand how variables contain attributes of different types, and how the instance methods may work.
  • Without any debugging experience, there may be a learning curve working with conditional breakpoints and the debugging toolbar.
  • Using boolean conditions for breakpoints may confuse students, due to requiring access to object attributes within the correct scope. 
    • These can all be improved with some in-lecture teaching about the debugger, with simpler examples of basic class structures and loops. As well as review for using condtional breakpoints with the few boolean conditions they may need.
    • The choice of development enviroment can also make a large difference in difficulty. For example, IntelliJ provides help autocompleting conditional breakpoints by default, while VSCode does not.
  • Many specific aspects of debugging (like finding thrown exceptions or off-by-one errors) are not included, focusing on using breakpoints/searching for certain cases instead.
Dependencies Understanding of Java syntax, selection statements, loops, and boolean conditions as well as knowledge about basic objects and 2D arrays. 
Variants The most clear outcome of this assignment was that small additions can make big differences in a semester. Compared to previous semesters, many students and tutors report increased confidence in debugging ability, which also follows true in students ability to complete coding tasks. Students agreed that the assignment theme made it an approachable task, and helped them become familiar with understanding code.

 

Assignment Files

Download Student Code - This is the code provided to students, which they can run and debug to solve questions, then submit their Answers.out file

Download GameResults File - You can add this GameResults.java file to the student code, and then use it to generate the correct reference answers for any students login ID. You can enter the ID via terminal, or args[0]. This allows you to write a simple auto-grader to compare batch student answer files and return which lines (questions) are incorrect for each. The student ID the program was run with will be the first line of the output file. The filename will always be -> "refAnswers.out".

Download Student Handout - This is the student handout, describing the game as well as a basic tutorial on using the debugger.

 

Using this Assignment

To use this assignment in your course, support should be given on how to use the debugger, including breakpoints (especially conditional breakpoints), the debug console, and variable viewer.  

In MurderMystery.java, a blank method "isValidLoginID(String id)" is provided, which you can fill out to limit valid login IDs. 

If any changes are made to Mansion.java, be sure to update the line number answers in GameResults.java, for each corresponding code line question. Or set the number of these questions to zero in MurderMystery.java 

You can create a program for your autograding service, which iterates over all student answer files and uses GameResults (with the loginID the student submitted) to generate the correct answers. Your program can then compare and generate a grade/feedback for the student. You should confirm that each student submitted the correct loginID. 

The minimal answers for equal question are given below under "Question Types". 

 

How to Complete

Running

When the student runs the MurderMystery.java file, they will be asked via the terminal for their login ID. 

They will then be asked if they want to print an intro. This intro has a title screen, as well as the characters' names for the mystery.

If no breakpoints are set, the game immediately ends and prints a game over screen. It then says the outcome (# survivors / if the murderer won). 

The student will then be asked a series of questions via the terminal, which they can type the answers to. These answers are printed to a “Answers.out” file, which the student can submit (the student's login ID is printed as the first line in the file, for submission verification reasons). 

Debugging

To find the answers to the given questions, students should investigate the Mansion.java file, where the game is created, stored, and run.

Students will be almost exclusively debugging the Mansion nextTurn() method, which simulates one single turn (five minutes in-game). This method gets repeatedly called by the Driver, which makes the game run.

The five set questions can be solved using a single breakpoint. Many random questions can be solved with a single conditional breakpoint, but some will require up to 4 to cover all possible cases (specifically in the logic for items being picked up / dropped). Code line questions require no breakpoints, just investigating the unmodified Mansion.java file.

Examples of breakpoint conditions:

- (droppedItem.getItemName().equals("Frying Pan"))

- (victim.getName().equals("Monsieur Verde"))

- (pickedUpItem.getItemName().equals("Wrench") || pickedUpItem.getItemName().equals("Piano Wire"))

- (player.getItemName().equals("Revolver"))

- (time == 95 || time == 230)

 

Question Types

By default, the game asks 10 questions. 5 set questions (which are the same for everyone), 3 random game questions, and 2 questions about line numbers for certain code functions. 

The code comes including 21 questions, including the 5 set questions, plus 9 possible random questions and 7 possible code line number questions. 

The 5 set questions are:

- Who was the murderer?

- How many items were spawned?

- How many rooms are in the mansion?

- Who moved first on each turn?

- How many murder weapons were used? 

The 9 possible random questions are:

- When did itemName get dropped last?

- When did itemName get picked up first?

- Where did itemName get dropped first?

- Where did itemName get picked up last?

- Where was playerName at XX:YYpm?

- What time/room did playerName get murdered? (2 Questions)

- How many players were dead / alive at XX:YYpm? (2 Questions) 

The 7 possible code line number questions are:

- What line number in the Mansion nextTurn() method decides how many moves a player gets?

- What line number in Mansion.java decides the cooldown when a murderer kills someone?

- What line number in the Mansion nextTurn() method increments the time at the end of each turn?

- What line number in Mansion.java changes the current player's location attribute after they move?

- What line number in Mansion.java returns false if the murderer wins?

- What line number in the Mansion constructor calls the createMansion method?

- What line number in the Mansion constructor sets the StdRandom seed with the calculated loginID hash?

 

To answer the questions minimally;

One breakpoint at line 105 in Mansion.java. Check 1) Murderer Name 2) Num Items 3) Num Rooms 4) Who Moves First 

One conditional breakpoint at line 143 in Mansion.java if any information is needed about a player's murdered (time of death, place of death, etc..). The condition should use "peopleInRoom.get(p)" to access the murdered player and then check their name. 

If information about an item drop is needed, place conditional breakpoints on lines 191, 195, 217, and 228. The conditions should use "player.getItemName()" to check if they are dropping the required item. 

If information about an item pick up is needed, place conditional breakpoints on lines 204, 219, and 227. The conditions should use "room.getItemName()" to check if they are picking up the required item. 

One conditional breakpoint should be placed on line 236 to check questions which ask about information at a specific time. You can use the condition "time == X" to check a certain time, where X is a int, in minutes past 6pm. Note: time increments at the end of the turn for the next turn. So we place the breakpoint before "time+=5" happens. 

After the game ends, the number of players who died will be the number of murder weapons.  

 

Modifying the Game

While the provided game is complete, it is also modifiable to adjust difficulty. The GameResults.java class will adapt to these following changes. 

In MurderMystery.java:

In res/Questions.in:

In Mansion.java: