Assignment 2: Step
Monster High
Introduction
In this assignment, we’ll write Step code to select and execute content units. Our content units are plot points for a soap opera world called Monster High. In this world, students, who also happen to be monsters, engage in conflicts and romance.
The provided code sets up the framework for the assignment. You’ll be adding code to two of the files, Queries.step and PlotPoints.step, as well as potentially changing the initial state of the world in Students.step to test your code.
This code works by testing the state of the world to see which plot points are potentially applicable and then picking one to execute. Two entry points have been provided for testing the code. The task [Events] selects and executes six random plot points. The task [ShowPlotPointMenu] shows a menu of all the plot points available in the current story state. The user can select one, it executes, and a menu of plot points available in the new state is displayed. Plot points will be represented as tuples, so if you haven’t done the reading on tuples, do that now.
For example, we might represent the plot point that Jayden confesses their love to Tiana with the tuple: [confess_love jayden tiana]. However, this only makes sense if we know that Jayden has a crush on Tiana, otherwise, why would they confess? And it doesn’t make sense if the two are already dating. So you need to make sure that the confess_love plot point is only available when there’s an attraction that isn’t being acted on. When this plot point executes, it might be printed as “Jayden confesses their love to Tiana”.
We’re using fluents to represent the changing state of the world as plot points execute. Read more about fluents in tutorial 8.
Note also that we’ve provided you with a version of Mention that understands things like pronoun generation and capitalization of character names. You don’t need to do anything with it, just realize that it’s there. If you don’t know what Mention is, read part 6 of the tutorial on generating text in context.
Getting started
To begin with, drag the Monster High folder into the Documents/Step folder on your machine (the Step folder inside your Documents folder). Then, open the Monster High folder you just put inside the Step folder in Visual Studio Code.
Replace the earlier version of Step that you downloaded with the new version provided in the assignment zip archive. This new version of Step fixes a bug that affects the assignment.
Finally, start Step, and type “project Monster High”.
Optional: Making a student body
The file Students.step defines the student body, including what type of monster each student is, what clubs people are in, and who has crushes, is dating, and are friends. For the purposes of testing your code, you may want to create your own student body with a specific initial state. However, you don’t need to do this if you don’t want to.
Note that the Mention code we gave you will use they as the pronoun for all characters by default. If you prefer, you may optionally specify preferred pronouns for some or all of your characters. To do that, just add statements to your Students.step file of the form:
PreferredPronoun student pronoun.
Where student is the student you’re specifying a pronoun for, and pronoun is either he or she. You can specify they, but since that’s the default anyway, there’s no particular point in doing so. Anyone you don’t specify a pronoun for will be referred to using they.
Part one: Queries
The file Queries.Step defines predicate rules to infer interesting relations in the story world. Examples include:
UnrequitedLove ?a ?b (?a is crushing on ?b, but not vice versa) and,
CheatingOn ?cheater ?cheatee (?cheater is dating ?cheatee and is also dating someone else). Write predicate rules for each of the predicates specified in Queries.Step.
Part two: Plot Points
Here’s how plot point selection works. Calling [PlotPoint ?event] picks plot points at random to test and returns a binding for ?event for the first plot point it finds whose test is satisfied. For example, if the confess_love plot point between jayden and triana was the first plot point it tried whose test was satisfied, then [PlotPoint ?event] succeeds with ?event = [confess_love jayden triana].
PlotPoint is a predicate: PlotPoint ?event means that ?event is a plausible thing to happen in a Monster High episode given the characters and relationships specified in Students.step.
If you wanted to see all the plot points that are possible in the current story state, you can use: [FindUnique ?event [PlotPoint ?event] ?eventList]. ?eventList will be bound to a list of all the possible plot points.
We’ve defined two hot keys, Alt-e/Option-e, which executes six plot points in a row, and Alt-m/Option- m, which shows a menu of all the possible plot points, allowing you to pick one to execute (you then see a new menu).
For each plot point, you need to write a method for the PlotPoint task to test if a plot point is available in the current story state.
We represent plot points as tuples:
[confess_love ?a ?b]
means?aconfessestheirlovefor?b. Thiscanoccurwhen?ahasacrushon?bbuttheyaren’t already dating.[start_dating ?a ?b]
means ?a starts dating ?b. There are two different conditions in which ?a can start dating ?b:o ?a knows that ?b has a crush on them, there’s a mutual attraction, they are not currently dating each other, and they are not star crossed lovers.
o Same as the above, except that they are star crossed lovers, and ?a is confident.
[romantic_rejection ?rejector ?rejected]
means ?rejector romantically rejects ?rejected. This can occur when the ?rejector
knows that ?rejected has a crush on them, and the love is unrequited.
[fight ?attacker ?defender [triangle ?attacker ?defender
?loveInterest]]
means ?attacker has a fight with ?defender about the fact that ?attacker and ?defender have the same ?loveInterest. This can occur when ?attacker and ?defender are in a love triangle with ?loveInterest.[fight ?cheatee ?cheater [cheating ?cheater ?cheatee ?other]]
means that ?cheatee fights with ?cheater about ?cheater cheating on them with other. This can occur when ?cheater is cheating on ?cheatee with ?other.[fight ?cheatee ?other [cheating ?cheater ?cheatee ?other]]
means that ?cheatee fights with ?other about ?cheater cheating on ?cheatee with ?other. This can occur when ?cheater is cheating on ?cheatee with ?other.[breakup ?char1 ?char2]
means that ?char1 breaks up with ?char2. This can occur when ?char1 and ?char2 are dating and ?char1 had a fight with ?char2.[smoldering_look ?a ?b ?club]
means ?a gave ?b a smoldering look when they were together at ?club. This can occur when the characters are mutually attracted to each other and they both belong to the club.[star_crossed_lovers ?a ?atype ?b ?btype]
can only occur when ?a and ?b are star crossed lovers (see definition in Queries.step).[support_from_friend ?supporter ?supportee [star_crossed_lovers ?supportee ?supporteeType ?crush ?crushType]]
means that ?supporter supports ?supportee about ?supportee being star crossed lovers with ?crush. This can only occur if ?supportee is star crossed lovers with ?crush and ?supporter and ?supportee are friends.So for this part, you need to add methods for PlotPoint to the end of PlotPoints.step. The methods are going to look like:
PlotPoint [eventType other-information ...]: condition Where:
• eventType is the kind of event (e.g. confess_love, star_crossed_lovers, etc.)
other-information is the other information that appears in that kind of event: definitely the characters participating in it, but for some of them, there are things like the monster types or clubs the students belong to
condition is the information to determine whether this plot point is allowed in the current state of the story world.
only generate in plausible circumstances.
Testing plot points
You can test plot points in a few different ways:
Running: PlotPoint ?
That is, typing PlotPoint ? in the green box, and hitting return, will generate a completely random plot point and print it in tuple form.Running: PlotPoint [type args ...]
Will force it to try to generate a plot point of the specified type. For example:
o PlotPoint [confess_love ?a ?b]
Will find a character ?a for which they meet the conditions to confess their love to ?b.
o PlotPoint [confess_love cameron hailey]
Will test whether [confess_love cameron hailey] is a valid plot point. If it doesn’t print anything, it’s valid. If it prints Call Failed, then that’s not a valid plot point. This isn’t a valid plot point in the Students.step file we hand out because Cameron and Hailey are already dating. But it might be true in your story world.
Part three: Executing Plot Points
Now write methods for ExecutePlotPoint. These should take the form of: ExecutePlotPoint [eventType other-information ...]: text-to-print state-to-change
Where, eventType and other-information are as above, text-to-print is what to print to describe this kind of plot point, and state-to-change is code to make state changes caused by the plot point.
Here are the state changes the need to happen for each plot point.
[confess_love ?a ?b]
Now ?b knows that ?a has a crush on ?b.[start_dating ?a ?b]
Now ?a and ?b are dating, and ?a doesn’t know anymore about ?b’s crush on ?a (now that they’re dating, they are beyond worrying about crushes).
[romantic_rejection ?rejector ?rejected]
Now ?rejector doesn’t know anymore that ?rejected has a crush on them, ?rejected no longer has a crush on ?rejector, and ?rejected considers ?rejector an enemy.[fight ?attacker ?defender [triangle ?attacker ?defender ?loveInterest]]
[fight ?cheatee ?cheater [cheating ?cheater ?cheatee ?other]]
[fight ?cheatee ?other [cheating ?cheater ?cheatee ?other]]
In all three case of fight, now the two characters involved have had a fight. The text will be
different for three cases.
[breakup ?char1 ?char2]
Since the two characters aren’t dating anymore, now they haven’t had a fight (the fight is no longer relevant after the breakup), and neither has a crush on the other.[smoldering_look ?a ?b ?club] Only prints text. No state changes.
[star_crossed_lovers ?a ?atype ?b ?btype] Only prints text. No stage changes ?confessor confesses ?confessor/Possessive love to ?confessee. [now [Knows ?confessee [CrushOn ?confessor ?confessee]]]
[end]
One way to test ExecutePlotPoint is by using the menu of possible plot points activated with Alt- m/Option-m and selecting a plot point to execute. You can then manually check the state, or check if the next plot points that are available make sense given the intended state change.
There are methods defined in Mention.step to help with writing text for ExecutePlotPoint. The subsections below describe these.
Pronoun generation
As discussed above, if text uses a character’s name twice, it will generate pronouns to refer to them when appropriate. By default, it uses they as everyone’s pronoun, but you can specify pronouns for specific character using PreferredPronoun (see above). That’s purely up to you, though.
What you should pay attention to is whether it’s generating pronouns in the right case. If your code to print says something like:
I love ?who. ?who is just so great.
This will generate something like:
I like Jayden. They are so great.
Because the second use of ?who is the subject of a sentence, this is fine. We want it to say they rather than them. But if our code says:
I love ?who. I could just hug ?who.
Then we get something a little odd:
I like Jayden. I could just hug they.
Here we want to use them rather than they because the second use of ?who is the object of the verb
rather than the subject. This is easy to fix. Just change ?x to ?x/Obj: I love ?who. I could just hug ?who/Obj.
This will produce the correct text:
I like Jayden. I could just hug them.
When you see your code is generating pronouns in the wrong case, just change it as follows:
• ?x
Prints they/she/he
• ?x/Obj
Prints them/her/him
• ?x/Possessive Prints their/her/his
Verb conjugation
Hopefully this won’t affect you for this assignment. I didn’t have to use it for my reference solution, but you may want to generate more ambitious text than I did. As discussed in the reading, you sometimes want to generate different forms of verbs, depending on how the subject is in third person plural or not. We’ve provided you with the [Is] task from the reading, which prints “is” or “are”, depending on what’s appropriate, as well as [Has], which prints “has” or “have” as appropriate. For example:
?a [Is] going out with ?b
Will generate “bill is going out with jenny” or “he is going out with jenny”, but “they are going out with jenny” when ?who is realized with the pronoun they.
For regular verbs, you can add [s] at the end of the verb and it will add an -s or an -es, as appropriate. For example:
TestCongation ?who: I like ?who. ?who read[s] books.
Will generate:
I like Jayden. They read books.
If Jayden’s preferred pronoun is they, but:
I like Jayden. He reads books.
If Jayden’s preferred pronoun is he.
The magic [s] task only works for regular verbs. If you want to handle a different verb, then grab the code for Is from Mention.step and just change it for your verb.
Part four: Invent some more plot points
NowwritePlotPointandExecutePlotPointmethodsfortwomorekindsofplotpoints. Theycan be anything of your choosing, although they need to depend on the story world. Feel free to add new information to the story world if you like.
Some ideas:
Two characters have a heart-to-heart discussion while at their club. This would obviously only make sense when they’re in the same club.
Two characters become friends after a fight. For that, there’d need to be a reason for them to have the fight. And they probably shouldn’t be dating, since people who are dating should probably already be friends. Maybe they become friends because they have a shared friend.
A werewolf character does something on the full moon
A vampire character bites a human character
Turning it in
Save all your files, reload (control-R) to make sure everything really does load. Assuming everything seems okay, make a zip file of your Monster High directory and upload it to canvas.