Course:CPSC312-2023/The Oregon Trail

From UBC Wiki

What is the problem?

The Oregon Trail is a text-based strategy game where the player guides a group of settlers while making decisions about resource management and the route to take while encountering random events such as storms or disease. We want to investigate whether logic programming is suitable for implementing this game, since one of the strengths of logic programming is tracking complex relations between different entities, for example how certain choices in the game will be predicated on the resources or skills that the party has or how different outcomes can only happen due to some branching paths.

The player starts by choosing their profession, naming their party members, and then purchasing supplies before setting off on their journey. The path has multiple segments, each ending at a landmark that presents several choices to the player. In between landmarks, there may be random events that impact the state of the game and have future consequences. The goal of the game is to reach the end of the trail before it is winter and conditions make it too harsh to continue, so the game ends when the party has reached their final destination or all members of the party have died.

What is the something extra?

The original Oregon Trail has several choices that the player selects by number but this form of interaction is fairly limited and repetitive. We instead leverage Prolog to have a natural language interface that would for example allow the player to say "Buy 2 oxen, 3 food and 2 ammunition" rather than having to choose what to buy and choose the amount using just numbers. Additionally, since the parser has normal English rules, we can match a wide range of similar commands with optional determiners for example or with alternate verbs such as "purchase" or "get" instead of "buy".

What did we learn from doing this?

We think that logic programming is definitely suitable for parts of making a game but it fell a bit short in other parts. The natural language interface was one part where it really shone since we could essentially just write grammar rules in a high level way using DCG and it would produce a more efficient version using difference lists which was quite nice. Another place we found it to be quite suitable is with how flexible the pattern matching is since it allows us to really concisely check if certain conditions are met. For example, we can check if a party member is sick just using party_member(_, sick, _). One place we found it to be not quite suitable is when you want a linear series of events where you only want one outcome, such as when following the events that happen through time in the game. We found ourselves having to add many cases for if something happened or if it didn't, having to continuously retract and assert, which is kind of like using global state, and trying to reason about what the backtracking behaviour is. Perhaps some of this could be mitigated with more advanced features like cuts, but we think Prolog applications that are meant to find multiple results definitely seem more natural due to backtracking being built-in.

Links to code etc

https://github.students.cs.ubc.ca/iris413/The-Oregon-Trail