Assignment 10

Due: Wednesday, May 6, 2014 at noon 100 pts.

Instructions: For this assignment you will submit multiple files, but not quite in the usual way. These files will contain a c++ program that you have named appropriately with appropriate extensions. You should have a file for your main, a header for each class definition, an implementation file for each class. Submit using the cssubmit script. For this final project, you are going to be allowed to work in groups of 0 to 2; that means 0, 1, or 2. We encourage you to work with someone, but discourage you from an uneven distribution of workload. NO SPONGERS! A group of 0 is suboptimal. Since we are allowing you to work in groups, you will submit only under one name for the group. Be sure to put all group members' names on every file.

Remember: This program will represent 10% of your final grade.

Background: The background for this assignment is pretty much what you have learned about forensics during the course of this class and its assignments. You are going to start with the classes that you developed in hw #9. If you are unfamiliar with hw #9, it's the one just after hw #8 and just before this one. But you are going to modify them and add other class(es).

Before enumerating the changes/additions in detail, let's briefly discuss the purpose of this program. The idea here is that your program will simulate the actions of a group of people who interact with one another on a daily basis. You will have an array of people; you could imagine they all live in, say, an apartment building. They meet in pairs in a room (the crime_room) that might be, say, a laundry room or commons room or restroom or utility room. Two meet in the morning, another two meet at noon, another two at 3:00, and another pair in the evening. The pairs of residents to meet are chosen randomly, not in order of the array. But, as personal interactions / business deals / friendships / love triangles go, once in a while someone gets upset and .... well ... kills the other one. So, in your simulation, for each meeting there is a small probability this unfortunate outcome happens. Of course, the next person in the room discovers the body and it is announced that a murder has taken place. Meetings stop, and you introduce a CSI agent who will try to solve the crime by gathering "mildly corrupted" forensic data of the killer, followed by trying to matching it to the personal data of all the other people for possible identification of the murderer. If a certain level of qualifying match is not reached, he/she goes back to the crime room to regather data (that is mildly corrupted in a mildly different way) and repeat the matching exercise until a (qualifying) match is found. The dead guy is removed from the line up of course, and the perpetrator will be sentenced by a judge.

This whole process is repeated! The remaining people (in the apartment...or whatever) start their daily meetings again and this continues until everyone is gone or just one remains (in the case an odd number of people begin this fateful journey), and in this case, they are declared "mayor" or "winner" or "last man standing" or whatever moniker you think works for you.

Specifications: Modifications first...

The resident class has the following changes/additions:

  1. A resident will no longer have a member variable just for hair color; remove that. In its place, every person will have a forensic_data member variable that keeps information about them. This introduces a new struct/class described below. The values for this member are assigned in the default constructor for a person object (as described below).

  2. Remove the hair_color_change() function. In its place, you will have a drop_evidence() function that will return a copy of that resident's forensic data. Note: when this function returns a copy, it must be a true copy. That means that your code here will have to declare another forensic_data object and copy element-by-element the data of the resident to be returned. This is a public function.

The crime_room class:

  1. Remove the hair member variable and replace it with a forensic_data object. This will not represent the data of the room (because it's a room, not a person), but the forensic_data of the murderer. Think of it this way: the room is holding the data of the perp after the crime is committed.

  2. In the constructor, remove initialization of the (nonexistent) hair member and don't worry about initializing the forensic_data member. It has no meaning until something happens anyway, at which time it's value will be updated to meaningful info.

  3. In the meeting() function, the most significant change is that hair color is not copied, but the forensic_data of the murderererer is copied (dropped) into the forensic_data member of the room. Arguably, a more important change is the chance of a murder happening. Since we like to think that we live a more civilized culture, let's decrease the chance of a murder from the horribly high 50% chance to a more reasonable and acceptable 10% chance. So, on average, you should expect a murder every 2 1/2 days.

  4. And, of course, change the murder() accordingly.

  5. The check_room() function will only return a bool; it will NOT make the announcement that a murder has occured.

  6. A getEvidence() function that returns a true copy of the forensic_data member (much like described in the resident's drop_evidence() function.

The forensic_data structure/class:

  1. A member for hair color; values from 1 -> 10. Randomly assigned in your resident constructor.

  2. A member for dna which is a array of 128 characters. Again, randomly assign the characters using the same probabilities as in hw 8 (which comes before hw 9 and after hw 7) in your resident constructor.

  3. A member for finger_print. This is yet another structure....as described next....with values randomly assign in the (residents' ) constructor.

The finger_print struct:

  1. A 8x8 character array (here you can refer to the link in hw 9 for 2-D arrays) with the characters being either space ( ' ' ) or star ('*'). You will scatter randomly exactly 40 stars (not a chance or percentage).

  2. Three integers, loops, arches, and whirls. The values are randomly assigned 0 -> 5.

The CSI_agent class:

  1. Member variable for his/her name.

  2. Member variable for forensic_data. But this is not his/hers, it is for the murderer he/she is trying to identify. You could call it something like the_evidence.

  3. A constructor that takes a string or ntca for the object's name (you get to name your agent when you declare him/her). Use this name in outputs.

  4. A visit_crime_scene() function that is passed a crime_room object. The agent will gather_info() from the room. This function will obtain a corrupted version of the forensic_data stored by the room.

  5. The gather_info() function will call the crime_room's getEvidence() function, and will corrupt data by

    • randomly add a value from -2 to +2 to the hair value of the data (maintaining value boundaries)

    • in the dna, randomly change exactly 15 characters to '-'.

    • in the finger print, randomly flip exactly 5 cells (from star to space, space to start); the three int values randomly incremented or decremented or unchanged (keeping within bounds).

  6. A perp_search() function that is passed a resident object and returns a bool. The function will look for a match between the forensic_data the agent collected from the room and the forensic_data of the resident passed. If the comparison reaches a 'score' of 90% (or .9, however you wish to build it), then it returns a true indicating match found; false otherwise. The 'score' is as follows

    • score = dna_score * 0.6 + fingerprint_score * 0.3 + hair_score * 0.1.

    • dna_score = percentage of matching characters

    • fingerprint_score = 0.7 * percentage of matching stars only + 0.1 if #loops is within 1 of a match + 0.1 if #arches is within 1 of a match + 0.1 if #whirls is within 1 of a match.

    • hair_score = 0.8 if values are identical; 0.6 if values are off by 1; 0.5 if values are off by 2; 0 otherwise.

The judicial class:

  1. A member for the name of the judge.

  2. A member for the judge's conviction rate, conv_rate, an integer representing a percentage 0 -> 100.

  3. A constructor that has a parameter for name and the conviction rate(defaulted to 95). Thus you may name your judge and his level of convictions (meanness?) upon creation. Ex: judicial judge("Judy", 90); would create a judge who convicts 90% of the time.

  4. A member function judgement() that has as a parameter a resident object, and returns nothing. The function will, with a probability determined by the second parameter of your constructor, execute the perpetrator of the crime by calling its kill() function and then announcing that "The accused, <name>, has been sentenced to death!"... or some such statement. In the event the bad guy is not executed, make up some other statement to announce.

Now, your main function should declare a crime_room, and an array of 25 residents and a judicial we'll call the judge. You should have a loop that will, 4 times a day, randomly choose two residents to meet in a crime room. As this simulation progresses, after each meeting of residents, the checkroom function will trigger the output of the meeting of two innocents ("John and Mary met"), or the occurrence of a murder ("******Ahhhhhh, a murder is committed and Frank is dead!*******"). This should also trigger the end of that loop, and the declaration of a CSI agent to investigate the crime. To accomplish the investigation, you should have an investigation() function to which you will pass the agent and the array of residents and the crime room. It will have the agent visit the crime scene and then walk down the array looking for a match of forensic data. If no qualifying match is found after looking at every remaining resident, the process of visiting the room and looking for a match is repeated, but no more than 10 times (if this occurs - very unlikely - output "So sorry guys, but this one got away"). When a qualifying match is found, output how many visits to the crime scene it took and something like "-----------I got my perp and they are <perp's name>." Remove both victim and perp from the array of residents. (Think carefully how to do this. Think carefully how to ask questions, too.) The judge will call its judgement() function, being passed the perp. Your main should then continue the meetings until everyone is gone or one is remaining. Identify that last remaining resident with all appropriate fanfare.

So, your output could look like this:

...........Fun and games at the Mickey Mouse Apartments................

day 1: 8:00 Bob and Frank meet

12:00 Joe and Mary meet

3:00 Adolf and Barney meet

7:00 Larry and Moe meet

day 2: 8:00 ************A MURDER HAS OCCURED ......and now Betty Boop is dead!!***********

---------- Action Jackson, the indomitable CSI agent, is on it ----------------

.....and after 4 visits to the crime room, he got his perp and it's Beavis! who killed Betty with a grass carp1.

etc

1Optionals: You must fulfill the above requirements. But, you can add to this program in any number of fun and interesting ways. For example, have a file of 20 weapons that you will randomly choose from when you have identified your killer. Then the output would be something like "***********Bob killed Mary using a door knob********* Now, if you add optional stuff, please put a comment block before main stating your additions. Sorry, no bonus marks for doing this. You will get a pat on the back for your efforts, though. We won't even give you the pat; find someone else to do that. There are many other things you can do, so be creative and enjoy yourselves.

Stuff: If you need more names, here are some good ones: Jeffrey Dahmer Barney Mr. Rogers Adolf Hitler Minnie Mouse Ted Bundy Little Bopeep John Wayne Gacy Jack DeRipper Little Pony

When you submit: just do it. NOTE: the due date/time is a hard deadline. That means NO LATE SUBMISSIONS.