COMP6991 23T1 — Solving Modern Programming Problems with Rust

COMP6991 – 23T1
Assignment Released (06/01/2023)
Assignment 1
AdventureRS
Change Log
mark_request now has a section for the reset key (07/03/2023)
Cargo Toml for termgame updated to “^1.2.0” (07/03/2023)
Please make sure your termgame version is set to “^1.2.0”
In this assignment, we will be calling back to the inspiration for many an introductory programming assignment, 2D
explorer games.
This assignment is in two parts. You will first implement an “adventure” style 2D game in the terminal. You will then
implement a “quests” system for the game, which will be designed to be re-usable. The goals of this assignment are:
1. Togetyoutopracticedesigningandstructuringalargerrustprogram.
2. Tofocusasmuchaspossibleonskillsanddesignpatternsthatwouldactuallybeusedwhensolvingmodern programming problems (i.e. writing a pull request, writing re-usable code, etc.)
3. Tohavefunmakinganaestheticandinterestingapplication.
We want to also be explicit about what the goals aren’t:
1. Toassessyourgamedesign(orgame-playing)skills-mechanicsyouimplementinthegamewillbeassessedsolely
on the technical skill they demonstrate.
2. Toassessyourabilitytowritelargeamountsofuselesscruftsolelyforustomarkyouon.Whereyou’rewritingcode,
we have a reason for it. Where you’re writing text, it’s because we want to genuinely understand your thinking.
What you will submit
At the end of this assignment, you will submit:
One crate, containing your game.
One crate, containing your quests system (if you made one).
A completed copy of mark_request.txt containing a list of features that you’ve completed; how to run your code;
and good/bad things about your code. This is basically a pull-request on GitHub; but in a text file.
Part 0: Getting Started
Starter Code
We have provided a small amount of starter code for this assignment; which you can access by downloading this tar file.
You can also run the following command to fetch the starter code:
$ 6991 fetch assignment 01
Reference Solution
To help you make stylistic decisions and see what we are looking for, you can use the command shown below to try our
version of Adventurers.
$ 6991 adventurers [map_file] [quest_name]
Where [map_file] is the path to one of the ron files in maps/ (in your starter code); and [quest_name] is one of q1, q2 or
While playing, use the arrow keys to move. The q key is used to show your progress in the quest; r will reset the quest;
and Ctrl+C will quit.
Part 1: Adventure Game Features
These features are the basic mechanics of the game.
While you must make sure that you implement these features, you do not need to implement tests, or write significant
documentation. You can feel free to write any tests or documenation that helps you; or helps us understand your code. You
can feel free to implement extra features if you so wish!
1. Implement a termgame controller, and display it. (0%)
As a first step, we have to show a picture of the map. To get this working, you just need to show something on the screen
using termgame. You should start by copying in the code from the example code on the main page of termgame’s
documentation.
To do this, we suggest that you make the key t (for test) display an ‘a’ in the top-left of the viewport; and a ‘z’ in the
bottom-right of the viewport. You do not need to do this, but it may help familiarise yourself with the termgame library.
Getting termgame working is made easy by consulting the termgame docs
No marks are awarded for this section (if it’s not complete, you won’t have started the assignment).
Termgame gives you access to an (effectively) infinite plane of characters. Obviously, it cannot display these all
the time, so it allows you to display at most an 78×22 rectangle of this infinite plane (the screen is 80×24 but
termgame adds a border on each edge). This area is called the “viewport”.
To store characters, Termgame uses a CharChunkMap, which stores a grid of it’s own internal representation of a
character on screen. You likely will not need to interact with that type directly at all. In other programs (like
workshop 4’s text editor), we used the fact you could swap CharChunkMaps in and out, but in this assignment
it’s not important to use them.
2. Implement Player Navigation (5%)
When your program starts, you should implement the ability to “walk around” with a player. There should be a player
character (We use U+265F, but any obvious character is fine). The player character should be able to move up, down, left
and right. The player character should start in the third row, third column.
A naive implementation of this feature would just have the viewport move every time the player does. To minimise the
movement of other objects on screen, full marks in this section require that the viewport only moves when the player is
close to going off screen.
For marks in this section, you will need to ensure three things:
A player icon is visible
The player always starts on the third row, in the third column of the map.
The player icon moves around the viewport, but is always on screen.
DESIGN EXCELLENCE:
Represent movement and coordinates via structs, using appropriate traits to implement movement.
3. Implement Different Coloured Block Types (5%)
It’s boring to walk around a world that’s all the same. You should add in different coloured “block types”, which look
different to the default block. You must have at least five. We suggest:
Grass (a green block)
Sand (a yellow block)
Rocks (a grey block)
Cinderblock (a light red block)
Flowers (a pink or magenta block)
For marks in this section, you should ensure two things:
All 5 coloured block types are implemented
When a player is standing on a block type, it is clear where in the viewport the player is standing, and the block type
they are standing on.
The documentation for the StyledCharacter struct may be useful.
The documentation for the set_screen_char method may be useful.
DESIGN EXCELLENCE:
Represent block types using enums, and use appropriate traits to convert the enum into a character that can be
shown on screen.
4. Parsing from a file (5%)
So far, you may have hard-coded where the block types are shown on the screen. Now, we want to store them separately.
You should implement a system so that the “map” is stored in a file; and loaded in at the beginning of the game.
We have provided two sample maps, which must work with your program, in the maps folder of your starter code.
For marks in this section, you just need to demonstrate that the files we have provided (in addition to others of your own
design, if you wish) control what is displayed to the user, and to control where on the screen things are. Your file should
ignore features you have not implemented yet.
DESIGN EXCELLENCE:
Use a library like serde to implement parsing.
For marks in this section, you just need to ensure there is a block-type that the player cannot pass through.
Games aren’t very interesting without obstacles! Let’s now implement a block type that the player cannot pass through. 5. Barriers (2%)
6. Water (3%)
Let’s add another obstacle – Water. Players can only hold their breath for 9 blocks in one go. In other words, after ten
blocks of water, the player should die from drowning.
For marks in this section, you will need to ensure three things:
The player can walk through water.
When the player walks over 10 blocks without stepping on another block, they die.
A player dying should end the game, and display a message.
DESIGN EXCELLENCE:
When the player dies, use termgame to display a message; and then exit the game when the player next moves.
Use your knowledge of rust to idiomatically represent these states in your game; and consider how they interact
with other states.
The documentation for the Message struct may be useful.
The documentation for the Game method may be useful.
7. Signs (5%)
Games need a story too – to help with this, please implement Signs. When a player walks over a sign, a message should
pop up for them. The message should disappear after the player moves again.
For marks in this section, you just need to ensure that when a player steps on a sign block, the appropriate message is
displayed; and when they step off it, the message disappears.
The documentation for the Message struct may be useful.
The documentation for the Game method may be useful.
8. Objects (5%)
The game should include objects (which could be any sensible unicode character) which appear on blocks. When a player
walks over the block, the character should disappear.
You do not need to implement objects on top of coloured block types; each location will either be coloured or an object,
never both.
For marks in this section, you just need to ensure that when a player steps on an object, the object disappears.
Part 2: Quest System Features
The second part of this assignment is designed to test your ability to write a piece of code that is high-quality,
understandable and re-usable. You will be asked to implement a “quest” system, where the developer can set the user
tasks to complete; and the system keeps track of their completion of those tasks. You will need to at least write one test
for each quest (or write enough unit tests to prove that the three provided quests should work). You will also need to
provide documentation where appropriate.
Importantly: we have provided a seperate crate to allow you to create a system which could be re-used, and be
designed such that other students (or indeed other games) could re-use it. During design marking, we will consider
how easy it would be for a future developer to specify new quests.
What should go in which crate is entirely up to you, and there are different approaches which could work well. You should
consider which parts of the system are unique to your application; and which are “general” to any quest system. For
example, the concept of “joining two quests together” might be general, but the exact list of events your quest system can
handle, and the order parts of a quest need to be completed is specific to your application.
The minimal implementation of this system would be having the quest trait in one crate; and everything else in the other
one. It’s likely, however, that you’ll find more functionality that can be abstracted away.
To help with re-usability (and to help as a starting point for the quests system), we have provided trait for you to
implement:
To be clear, you are welcome to extend the above trait if you wish. An extension trait might look like
pub trait ExtensionTrait: Quest + SomethingElse { … }. this trait is just a starting point.
Though we encourage using our trait, if you feel that the provided trait is too restrictive, you are welcome to implement
your own trait, or even, avoid using such a trait at all. If you choose to create an extension trait or, not use the trait at all,
you should justify these design decisions in your mark request.
Note that if you choose to not use the provided trait or, a trait at all and, your solution is less-extensible, then you
will lose marks for design excellence.
You should, at least, be able to play the following quests. For each, a key (preferably ‘q’) should show your progress in the
quest, and when the quest is complete, the game should end.
In the sample implementation, the r key triggers a reset. We also use reset as part of our program, in addition to its
debugging uses. You should also implement such functionality.
(quest 1 – 4%) “The player wins the game if they walk over 5 sand blocks”.
(quest 2 – 3%) “The player wins the game if they:”
“First, collect five objects called ‘x'”
“After finishing that, collect three objects called ‘y'”
(quest 3 – 3%) “The player wins the game if they do 2 of the following:”
“walk over 5 blocks of sand”, then “collect an ‘x’ object”.
“collect a ‘y’ object”, then “walk on grass”.
“walk over 9 blocks of water, 3 times”.
DESIGN EXCELLENCE:
Remember, however, that you should also support a future developer who wants to extend this system — it
should be easy to add in tasks or compose new quests!
5 marks are reserved for the style of your quests system, 10 marks are reserved for the implementation of your quests
system, and 15 marks are specifically reserved for the design of your quests system, so the maximum possible mark
without completing quests is 70%.
DESIGN EXCELLENCE:
There are at least two approaches that would demonstrate design excellence. One is to create primitive tasks,
and combinators (and, or, then) for those tasks. The other would be to write a state machine of some sort.
Part 3: Submit a Mark Request
When building modern software, you are expected to send in a pull request, explaining what you’ve done. In COMP6991,
you must submit a “mark request”. This is contained in mark_request.txt.
The mark request helps us mark you — we will use it to help us find out what to mark. It is not meant to take more than 10
minutes to write. No marks are awarded for the mark request specifically; but if it is very inaccurate, we reserve the right to
either request you resubmit it with a penalty; or mark using it as a basis (and therefore not mark things you’ve done).
Other Information
QandA / Clarifications
For any assignment related questions, refer to the Assignments category on the forum. The following are a list of brief
answers to common questions:
The reference solution looks different from the images on the assignment specification. Which colour scheme
should my solution match? Colours may vary from terminal to terminal depending on your terminal emulator’s
colour scheme. You do not need to have colours match exactly as long as they are distinguishable and the general
colourscheme matches the specification. That is, red-blocks are still red and not green.
Should signs re-appear once the player steps off them? Yes. Signs are not collectible items. Once you step off a
sign, it should remain on the map.
How much documentation are we required to write? If you are providing any form of public interface (e.g your
quest system), it needs to have documentation. The warn(missing_docs) attribute should warn you if you’ve not
written any documentation you need to. We do not expect documentation for any private implementations, however
you are free to write documentation for them if you wish.
Submission
How to Debug Termgame See the instructions down the bottom of the page.
Because termgame uses curses to control the terminal, regular println! debugging is not possble.
On unix-like systems, there are a few ways to make your life easier when debugging. One is to use the eprint! and
eprintln! macros, to print to standard error. You can then do stderr redirection into files, like so:
6991 cargo run 2> /tmp/adv_log
Debugging output can then be found in /tmp/adv-log. If you open a different terminal window, tail -f /tmp/adv-log will
show a live-updating view of that file, so you can correlate log messages with a particular action.
If you want to have more advanced debugging capabilities, you may find the -p argument to gdb useful.
Using Other Crates
We are happy for you to use any crate that has been published on crates.io under three conditions:
The crate must not have been authored by anyone else in the course.
The crate must have at least 1000 downloads, excluding the last 30 days.
The crate must not impose license restrictions which require you to share your own code.
If you are in doubt (or think these restrictions unfairly constrain you from using a reasonable crate), ask on the course
/// This is what a “quest” should do.
/// Note that all `Quests` implement `std::fmt::Display`
/// to show the current progress of the quest.
/// You do not have to use this trait but, this may be a useful place to start. pub trait Quest: std::fmt::Display {
/// Whenever something happens, you call “register_event” to tell the quest what’s happened.
fn register_event(&mut self, event: &Event) -> QuestStatus;
/// Reset the quest, so that players can restart.
fn reset(&mut self);
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum QuestStatus {
impl From for QuestStatus {
fn from(status: bool) -> Self {
match status {
true => QuestStatus::Complete,
false => QuestStatus::Ongoing,
impl From for bool {
fn from(status: QuestStatus) -> Self {
matches!(status, QuestStatus::Complete)
Marking Scheme
There are 3 things on which you will be marked:
Mechanical Style
Functional Correctness
Idiomatic Design
You can see how the marks break down here:
Mechanical Style
Adventure Game 10%
Quests System 5%
1. Mechanical Style (10% + 5%): And a detailed analysis is shown below:
We will look at your crates, and make sure they:
Compile, with no warnings or errors.
Raise no issues with 6991 cargo clippy
Are formatted with rustfmt
Have any tests written for them pass
Functional Correctness
Idiomatic Design
(for quests only) have tests which encompass the three quests.
(for quests only) have all public interfaces documented (i.e. no warnings generated with #[warn(missing_docs)]).
(for quests only) have implemented at least one quest (otherwise submitting an empty file would get you free marks).
If they do all of the above, you get full. Otherwise, we will award partial marks. This is meant to be the “easy marks” of
programming.
2. Functional Correctness (30% + 10%):
Your code should do what we describe. We will run the code through some obvious tests to make sure it behaves as we
expect. For example, we will likely do the following:
Trying to start your program.
Testing the behaviour we stated below.
Trying out walking around a bunch, and trying to go off the map.
Modifying your map slightly.
The marks available of each section of the assignment is shown next to the title of the section above.
You must complete the checklist and the “How to Run My Program” section of the mark_request faithfully. We will only
test things which you say you have done. In other words, if you do not fill in the file, we will not be able to give you any
marks. If you do fill in the mark_request and you clearly have not done the work, we may ask you to re-complete it at a
penalty before we do marking.
30% of your final mark will come from functional correctness of your adventure game. 10% of your final mark will come
from functional correctness of the quests system.
3. Idiomatic Design (30% + 15%):
Your code should be well designed. This is where we will spend most of our time when marking. To help you, we have
provided “design excellence” suggestions, which are ideas to make your design really excellent. You don’t have to do
them, but they would be good ways of getting a great design.
The following list of properties will be marked in your program:
Code is abstracted appropriately.
Types are used appropriately to express data in the program.
The design does not impose unnecessary constraints on either the caller or callee through borrowing, lifetimes or
ownership.
Uses traits sensibly to add expressiveness and avoid unnecessary code.
Data structures used are appropriate to store data.
Functions perform error handling; cases that are expected do not panic. (see the hint below as of 20/10)
Code is sensibly organised, and split into appropriate modules.
Documentation, where provided, is correct and readable.
(optional) Uses external crates effectively to achieve the above goals.
(optional) Where code is designed in a sub-optimal way, comments about how to improve it are made under “Design
Limitations”.
Your mark will be calculated based on the feedback you have received:
100% of Very little negative feedback is given on the above criteria; and multiple design excellence available suggestions are implemented (or your own ideas which we consider equivalently excellent). marks
Some minor comments are made about some of the above criteria. Above this mark, at least one
design excellence feature was implemented (or your own idea is considered equivalently excellent).
Major comments are made about three or more criteria.
75% of Major comments are made about one or two criteria, with multiple small comments in different areas. available
50% of Many areas have major comments made. available
below 50% of
and design patterns.
Assignments in this category are likely written as “translations from C”, and ignore many Rust features
30% of your final mark will come from the design of your adventure game. 15% of your final mark will come from the
design of the quests system.
Note that the following penalties apply to your total mark for plagiarism:
0 for the Submitting any other persons work. This includes joint work.
assignment
What constituted “good” error handling? Basically, the way we see it is that there are three “levels” to how we’ll
mark error handling.
Level 1: Using panics is explicitly bad design, except where it’s obvious that you can manually verify the program
will never crash. We would mark you down for using them, for breaking the guideline that functions perform error
handling; cases that are expected do not panic.”
Level 2: Returning a Box could be fine design, if the expected outcome is just that you’ll ignore those
errors; take some action no matter what the error is; or that you’ll bubble up the error and just print out what it is.
If you rely on what the error was, then you should encode that explicitly in the type system. If you don’t, we’d
comment under the guideline that “Types are used appropriately to express data in the program.”
Level 3: explicitly making types for all your errors, or even using external libraries that make types for your errors
easier (a good example is the anyhow library) is excellent design, and would be rewarded under “design
excellence” or “using crates”.
Formal Stuff
Assignment Conditions
Joint work is not permitted on this assignment.
This is an individual assignment.
The work you submit must be entirely your own work. Submission of any work even partly written by any other person
is not permitted.
The only exception being if you use small amounts (< 10 lines) of general purpose code (not specific to the assignment) obtained from a site such as Stack Overflow or other publicly available resources. You should attribute the source of this code clearly in an accompanying comment. Assignment submissions will be examined, both automatically and manually for work written by others. Do not request help from anyone other than the teaching staff of COMP6991. Do not post your assignment code to the course forum. Rationale: this assignment is an individual piece of work. It is designed to develop the skills needed to produce an entire working program. Using code written by or taken from other people will stop you learning these skills. The use of code-synthesis tools is permitted on this assignment, however beware -- the code it creates can be subtly broken or introduce design flaws. It is your job to figure out what code is good. Rationale: this assignment is intended to mimic the real world. These tools are available in the real world. Sharing, publishing, distributing your assignment work is not permitted. Do not provide or show your assignment work to any other person, other than the teaching staff of COMP6991. For example, do not share your work with friends. Do not publish your assignment code via the internet. For example, do not place your assignment in a public GitHub repository. You can publish Workshops or Labs (after they are due), but assignments are large investments for the course and worth a significant amount; so publishing them makes it harder for us and tempts future students. Rationale: by publishing or sharing your work you are facilitating other students to use your work, which is not permitted. If they submit your work, you may become involved in an academic integrity investigation. Sharing, publishing, distributing your assignment work after the completion of COMP6991 is not permitted. For example, do not place your assignment in a public GitHub repository after COMP6991 is over. Rationale:COMP6991 sometimes reuses assignment themes, using similar concepts and content. If students in future terms can find your code and use it, which is not permitted, you may become involved in an academic integrity investigation. Violation of the above conditions may result in an academic integrity investigation with possible penalties, up to and including a mark of 0 in COMP6991 and exclusion from UNSW. Relevant scholarship authorities will be informed if students holding scholarships are involved in an incident of plagiarism or other misconduct. If you knowingly provide or show your assignment work to another person for any reason, and work derived from it is submitted - you may be penalised, even if the work was submitted without your knowledge or consent. This may apply even if your work is submitted by a third party unknown to you. If you have not shared your assignment, you will not be penalised if your work is taken without your consent or knowledge. For more information, read the UNSW Student Code , or contact the course account. When you are finished working on this exercise, you must submit your work by running give: This exercise cannot be submitted with 6991 give-crate. Instead, please package your crate(s) (along with all other files intended for submission) up into a tar file named crate.tar. Before tar'ing, please make sure you run 6991 cargo clean on all crates you intend to submit first in order to delete any unnecessary build cruft that may push you over the submission size limit. For example: $ tar cvf crate.tar
$ tar cvf crate.tar ./my_crate1/ ./my_crate2/
Finally, submit with the following command:
$ give cs6991 assign01_adventurers crate.tar
You must run give before Week 7 Wednesday 22:00:00 to obtain the marks for this exercise. Note that this is an
individual exercise; the work you submit with give must be entirely your own.
0 for the Knowingly providing your work to anyone and it is subsequently submitted (by anyone). assignment
0 FL for COMP6991 Paying another person to complete work. Submitting another persons work without their consent.
COMP6991 23T1: Solving Modern Programming Problems with Rust is brought to you by the School of Computer Science and Engineering
at the University of New South Wales, Sydney.
For all enquiries, please email the class account at
CRICOS Provider 00098G Login as tutor

Programming Help, Add QQ: 749389476