This specification is broken into four parts:
[[TOC]]
- Tue 28 Jun 11:30am - Correct descriptions for
tick
overloads in interface, add note about keeping branches when squashing and fix formatting in link, add setup images - Tue 28 Jun 6pm - Replace
gameMode
parameter withconfigName
in new game method i.e.newGame(String dungeonName, String configName)
- Tue 28 Jun 8:00pm - Fix two battle calculation tests in
ExampleTests
- Wed 29 Jun 9:30pm - Fix front-end config selector in starter code
- Thu 30 Jun 10:30pm - Add
player
to dungeon input entities - Sat 2 Jul 12pm - Allies provide attack/defence bonuses
- Sat 2 Jul 12:30pm - Add coverage extraction
- Mon 4 Jul 9pm - Clarify square blast radius for bombs and mercenary bribing
- Mon 4 Jul 11pm - Nesting of compound goals
- Tue 5 Jul 7pm - Fix wording of complex goals in 3.7.2
- Tue 5 Jul 10pm - Fix provided config files for allies
- Mon 11 Jul 1pm - Fix
getEntitiesStream
inTestUtils
to check prefixes instead of entire entity type - Sun 10 Jul 9am - Fix confusing exception and add precondiction in the JavaDoc for
FileLoader.loadResourceFile()
- Tue 12 Jul 4pm - Fix sample battle test to have positive delta instead of negative for health in
RoundResponse
- Tue 12 Jul 6pm - Clarify
isInteractable
behaviour with allies, zombie toast spawner behaviour if there's no open square and removal of items from inventory - Tue 12 Jul 8pm - If a spider is stuck between two boulders in its movement path, it should remain still
- Tue 12 Jul 10pm - Improve wording of effects of bows in battles
- Wed 13 Jul 9am - Fix the typo in the example battle test
- Thu 14 Jul 6am - Add image for green portal
- Thu 14 Jul 10pm - Fix triggering interactions multiple times from the front-end
- Sat 16 Jul 9am - Add error tolerant to battle calculation
- Mon 18 Jul 8am - Add Milestone 3 (search for đź’€ to find all product/technical spec changes)
- Tue 19 Jul 9pm - Fix section 4.1.1 by adding boss entities
- Tue 19 Jul 10pm - Fix M3 spec Typos
- Wed 20 Jul 12am - Fix description for
midnight_armour_defence
and durability for midnight armour in the spec. - Wed 20 Jul 6pm - Removed redundant
hydra_spawn_rate
config field from the spec because hydra will not spawn from a spawner. - Wed 20 Jul 11pm - Fix description for
buildable
fields inDungeonResponse
- Wed 20 Jul 11pm - Fix description for building
midnight_armour
- Thu 21 Jul 10pm - Clarify adjacent as being cardinally adjacent in description for logical entities
- Fri 22 Jul 8am - Remove stale
gameMode
parameter fromgenerateDungeon
- Fri 22 Jul 3pm - Add rewind buttons for
time_turner
to frontend - Fri 22 Jul 3pm - Add dungeon generation to frontend and fix method signature for
generateDungeon
- Tue 26 Jul 5pm - Remove
switch_door
from logic images - Fri 22 Jul 5pm - Clarify Sun Stone and Sceptre.
- Sat 23 Jul 12pm - Time travel clarifications
- Sat 23 Jul 9pm - Clarify dungeon generation and time travel behaviour
- Sun 24 Jul 9am - Fix description for exceptions in
interact()
and description for sun stone - Sun 24 Jul 9pm - Clarify dungeon state after time travel
- Sun 24 Jul 11pm - Revert bad spec update and clarify
hydra_health_increase_rate
- Tue 26 Jul 11pm - Clarify logical entity input
- Wed 27 Jul 8am - (Important) Update exit location of player out of time portal
- Thu 28 Jul 9am - Clarify time turner vs time portal travelling back
- Apply software design principles and patterns to create well-maintained software solutions
- Synthesise and adapt to changes in requirements
- Practice software design and development in a dynamic team environment using Agile principles
- Work with the Java Programming Language and Java Class Libraries
- Build medium-scale persistent web applications from scratch
- Appreciate issues in the design and development of software
For many years, Penguin Pty Ltd (a small software business run by Atilla Brungs) has dominated the native application gaming market with hit games. However in recent years, advancements in web technologies mean that the new generation of consumers don't want to download and run a native application, but instead want to play games online. To adapt to the ever-changing market, Penguin Pty Ltd has decided to take users back to the 1980s and develop a new game called Dungeon Mania, but with a modern twist - designed as a web application.
Penguin Pty Ltd has sub-contracted two software firms:
- BlueBottle Pty Ltd to develop a web-based frontend to the game
- YourTeam Pty Ltd (a team of talented misfits completing COMP2511 in 22T2), who will build the backend Java application.
Furthermore, there is a rival company called Spheniscidae Pty Ltd which has already produced a solution which you can refer to as a possible sample solution.
In Dungeon Mania you control a Player and have to complete various goals within a series of dungeons to complete the game!
The simplest form of such a puzzle is a maze, where the Player must find their way from the starting point to the exit.
More advanced puzzles may contain things like boulders that need to be pushed onto floor switches,
enemies that need to be fought with weapons, or collectables like potions and treasure.
The Player, can be moved up, down, left and right into cardinally adjacent squares, provided another entity doesn't stop them (e.g. a wall). The Player begins the game with a set amount of health and attack damage. The Player spawns at a set 'entry location' at the beginning of a game.
The game contains the following static entities.
In addition to the Player, the game contains the following moving entities.
All enemy entities can be created as part of the initial dungeon. Each tick, all enemies move according to their respective behaviour.
Entity | Image | Description |
---|---|---|
Spider | Spiders spawn at random locations in the dungeon from the beginning of the game. When the spider spawns, they immediately move the 1 square upwards (towards the top of the screen) and then begin 'circling' their spawn spot (see a visual example here). Spiders are able to traverse through walls, doors, switches, portals, exits (which have no effect), but not boulders, in which case it will reverse direction (see a visual example here). When it comes to spawning spiders, since the map is technically infinite you can spawn them anywhere - however for better gameplay we suggest you make an assumption and pick a four co-ordinate box to spawn spiders in. If a spider is stuck between two boulders in its movement path, it should remain still. | |
Zombie Toast | Zombies spawn at zombie spawners and move in random directions. Zombies are limited by the same movement constraints as the Player, except portals have no effect on them. | |
Mercenary | Mercenaries do not spawn; they are only present if created as part of the dungeon. They constantly move towards the Player, stopping only if they cannot move any closer (they are able to move around walls). Mercenaries are limited by the same movement constraints as the Player. All mercenaries are considered hostile, unless the Player can bribe them with a certain amount of gold; in which case they become allies. Mercenaries must be within a certain radius of the player in order to be bribed, which is formed by the diagonally and cardinally adjacent cells in a "square" fashion, akin to the blast radius for bombs. As an ally, once it reaches the Player it simply follows the Player around, occupying the square the player was previously in. |
Bosses are moving entities which are harder to defeat/conquer than normal enemies.
Entity | Image | Description |
---|---|---|
Assassin | Assassins are exceptionally powerful mercenaries which deal significantly more damage. When bribing an Assassin, there is a certain chance that the bribe will fail; the gold will be wasted and the Assassin will remain hostile. Assassins are also capable of seeing and moving towards the Player when they are invisible, if they are within a certain radius. | |
Hydra | Hydras are generally considered to be a special creatures similar to Zombies. Hydras are limited by the same movement constraints as Zombies. When a hydra is attacked by the player, there is a certain chance that its health will increase rather than decrease by the given amount, as two heads have grown back when one is cut off. |
It is possible for a player to use another potion while the effects of an existing potion are still lasting (can be of the same or a different type of potion). In this case, the effects are not registered immediately but are instead 'queued' and will take place the tick following the previous potion wearing of. For example, on tick 0 the Player consumes an invinsibility potion that lasts for 5 ticks and becomes invisible to enemies moving that tick, on tick 3 they use an invincibility potion, at the end of tick 4 (after all enemy movements) the player becomes visible again and becomes invincible.
In Milestone 3, the following collectable entities have been added:
Some entities can be built using a 'recipe' by the player, where entities are combined to form more complex and useful entities. Once a buildable item has been constructed, it is stored in a player's inventory. For all buildable entities, once the item is constructed the materials used in that construction have been consumed and disappear from the player's inventory.
In Milestone 3, the following buildable entities have been added:
A battle takes place when the Player and an enemy are in the same cell at any point within a single tick. The conditions for a battle occurring are the same regardless of whether the player moves onto the same tile as the enemy, or vice versa.
A 'round' of a battle occurs as follows:
Player Health = Player Health - (Enemy Attack Damage / 10)
Enemy Health = Enemy Health - (Player Attack Damage / 5)
If the Player's health is <= 0, then the Player dies, is removed from the game and the game is over. If the enemy's health is <= 0, then the enemy dies and is removed from the game. If after the above 'round', neither the Player nor the enemy is dead, the round repeats until either the Player or enemy is dead.
In battles, allies provide an attack and defence bonus to the player.
An example of a bow, sword and shield being used in battle is as follows:
player health = 10
player base attack damage = 5
bow attack damage = 2
sword attack damage = 1
shield defence = 2
enemy health = 10
enemy attack damage = 5
Battle occurs:
- Round 1 enemy health = 10 - ((2 * (5 + 1)) / 5) = 7.6
player health = 10 - ((5 - 2) / 10) = 9.7
- Round 2 enemy health = 7.6 - ((2 * (5 + 1)) / 5) = 5.2
player health = 9.7 - ((5 - 2) / 10) = 9.4
- Round 3 ...
All additive/reductive bonuses from weapons are processed before multiplicative bonuses.
In addition to its layout, each dungeon also has a goal that defines what must be achieved by the player for the dungeon to be considered complete. Basic goals are:
- Getting to an exit;
- Destroying a certain number of enemies (or more) AND all spawners;
- Having a boulder on all floor switches;
- Collecting a certain number of treasure items (or more);
Goals are only evaluated after the first tick. If getting to an exit is one of a conjunction of conditions, it must be done last. For example, if the condition is to destroy all enemies AND get to an exit, the player must destroy the enemies THEN get to the exit.
More complex goals can be built by logically composing goals. For example:
- Destroying a certain number of enemies and spawners AND getting to an exit
- Collecting a certain number of treasure OR having a boulder on all floor switches
- Getting to an exit AND (destroying all enemies OR collecting all treasure)
All compound goals are binary (they contain two and only two subgoals).
If getting to an exit is one of a conjunction of conditions, it must be done last. For example, if the condition is to collect 3 treasure AND get to an exit, the player must collect at least 3 treasures THEN get to the exit. It is possible for a subgoal to become un-achieved, for example if the dungeon goal is boulders AND exit
and all boulders are pushed onto switches, then the boulders subgoal becomes complete. However, if a boulder is then moved off a switch, the boulders subgoal is no longer complete.
The game is won when all the goals are achieved. The game is lost when the player dies and is removed from the map.
During the development process the engineering team discovered issues in the requirements of the movement of mercenaries and decided that they should follow a specific path to move towards the player.
In this Milestone, the movement of mercenaries (and by extension assassins) must follow a Djikstra's algorithm to take the shortest path towards the player.
You can view pseudocode for the algorithm here.
Note: This is not necessarily optimal (A* is probably a better algorithm for our common maze like dungeons), but since this is a design course and not an algorithms course, this is fine.
function Dijkstras(grid, source):
let dist be a Map<Position, Double>
let prev be a Map<Position, Position>
for each Position p in grid:
dist[p] := infinity
previous[p] := null
dist[source] := 0
let queue be a Queue<Position> of every position in grid
while queue is not empty:
u := next node in queue with the smallest dist
for each cardinal neighbour v of u:
if dist[u] + cost(u, v) < dist[v]:
dist[v] := dist[u] + cost(u, v)
previous[v] := u
return previous
As part of this, you will need to extend your solution to accomodate the idea of a swamp tile. These are tiles that have an x
and y
position and remain fixed throughout the entire game. They slow the movement of all entities through them, except for the player. Each swamp file has a movement factor which is a multiplying factor of the number of ticks it takes to traverse the tile. For example, let us say the movement factor for a swamp tile is 2:
- Tick 1: Move onto the swamp tile;
- Tick 2: Stuck on the swamp tile;
- Tick 3: Still stuck on the swamp tile;
- Tick 4: Move off the swamp tile.
Entity | Image |
---|---|
Swamp Tile |
Your implementation of Djikstra's will need to accomodate for the fact that swamp tiles slow the enemies down. There will be one autotest that checks that portals have an effect on your implementation of Djikstra's.
At any point during the game, the game should be able to be saved into a local persistence layer such that if the application is terminated, the user can reboot the application, select the game from a list of saved games and continue playing from where they left off, as if nothing had changed at all.
To pass the more basic tests, you will simply need to preserve the position of entities on the map. To pass more complex ones, you will need to consider persistence of items like potions, bribing/mind-control, etc.
This part of the extension includes the following new entity:
Entity | Image |
---|---|
Time Turner |
If the player has collected a time turner, then two rewind buttons will appear on the frontend. When clicked, these buttons move the state of the game back one tick and 5 ticks respectively and "transport" the current player back to those game states in a time travelling fashion.
This part of the extension includes the following new entity:
Entity | Image |
---|---|
Time Travelling Portal |
If a player travels through a time travelling portal, they end up on the same square as the portal, except the dungeon state is that of 30 ticks previously. If less than 30 ticks have passed, then the dungeon state is simply the initial dungeon state.
When a character has time travelled, either by the rewind buttons or via a time travelling portal:
- Their 'older self' still exists in the dungeon as its own entity. If they encounter their older self and either are carrying a sun stone or are wearing midnight armour, or they are invisible, then nothing happens. If not, then a battle ensues.
- Their 'older self' should take the same path as was taken initially, and unless they encounter their 'current self' (they character being controlled), should eventually travel through the time portal and disappear from the map.
- The player's inventory persists across time travelling. This means that if a player picks up a sword then travels through a time portal, the sword remains in their inventory as well as being back on the map available to pick up.
Only the character can travel through time travel portals.
The older player should still collect items and play out all tick
and interact
movements with those items as they did before. Time travel takes the player to after the tick takes place, e.g. if on tick 30 the player travels through a portal it arrives out of the other side after tick 0 has taken place. Note that for time turners, this isn't the same as rewind
operations do not class as a tick
.
Implementation Hint
The design of this extension is up to you, however we recommend you treat time travel as moving backwards in a series of game states that are being stored (the state of the dungeon at tick X). When time travel occurs, the player is transported to that state, and all tick
and interact
functions are "played" out in the same order for the older player, not the current player.
This also means that when the older player reaches the tick during which they time travelled (either by using a time turner or through a portal), they should be removed from the map.
In this extension, instead of specifying an existing dungeon to play, players can choose specify a dungeon to be automatically generated when creating a new game.
As part of this, you will need to be able to automatically generate dungeons. Furthermore it's important that you have an exit at the end position and that you have exit goals setup for this created dungeon.
You will need to generate dungeons according to the following maze generation algorithm (which is just a randomised version of Prim's).
Note: You should enforce a border of walls around the maze.
function RandomizedPrims(width, height, start, end):
let maze be a 2D array of booleans (of size width and height) default false
// false representing a wall and true representing empty space
maze[start] = empty
let options be a list of positions
add to options all neighbours of 'start' not on boundary that are of distance 2 away and are walls
while options is not empty:
let next = remove random from options
let neighbours = each neighbour of distance 2 from next not on boundary that are empty
if neighbours is not empty:
let neighbour = random from neighbours
maze[ next ] = empty (i.e. true)
maze[ position inbetween next and neighbour ] = empty (i.e. true)
maze[ neighbour ] = empty (i.e. true)
add to options all neighbours of 'next' not on boundary that are of distance 2 away and are walls
// at the end there is still a case where our end position isn't connected to the map
// we don't necessarily need this, you can just keep randomly generating maps (was original intention)
// but this will make it consistently have a pathway between the two.
if maze[end] is a wall:
maze[end] = empty
let neighbours = neighbours not on boundary of distance 1 from maze[end]
if there are no cells in neighbours that are empty:
// let's connect it to the grid
let neighbour = random from neighbours
maze[neighbour] = empty
Or, in a more wordy fashion;
- Given a grid that consists of a 2D array of states (Wall/Empty) initialised to only walls
- Set the start position to empty spaces
- Add to a list of positions to process the neighbours of start (that are walls)
- Given that there are still positions to process:
- Pick a random position from the list and a random cardinal neighbour of distance 2 that isn't on the boundary and is empty (not a wall)
- Pick a random neighbour that is a wall and connect the two via 2 empty spaces
- Compute all cardinal positions that are walls for the random neighbour and add it to the list of positions to process.
- At the end fix-up the maze given that the end cell is still a wall
- Mark it as not a wall
- If it has atleast one neighbour that is a empty cell then don't do anything else (it's connected)
- Otherwise, mark one of it's cardinal neighbours as a empty cell as well.
There are two new entities in this extension:
All entities which interact via switches (doors, bombs, and light bulbs), as well as switches themselves can become "logical" entities, where one of the following rules is adopted:
- AND - the entity will be only activated if there are 2 or more cardinally adjacent activated entities (switches with boulders on them or active wires). If there are more than two switches adjacent, all must be activated.
- OR - the entity will be activated if there are 1 or more cardinally adjacent activated entities
- XOR - the entity will be activated if there is 1 and only 1 cardinally adjacent activated entity
- CO_AND - the entity will only be activated if there are 2 or more activated entities cardinally adjacent, which are both activated on the same tick (i.e. a boulder is pushed onto them at the same time).
If a switch cardinally adjacent to a wire is activated, all the other interactable entities cardinally adjacent to the wire are activated. This allows for the creation of dungeons with logic gates. For example:
You can find setting up instructions here.
Dungeon maps consist of JSON files which contain the following:
entities
, an array of entities in the map when the game starts; andgoal-condition
, a specification of the goals for winning the dungeon.
There will be no other fields present in the JSON.
All maps are infinite in all directions. Moving left/right is a decrease/increase in the x co-ordinate of an entity respectively, moving up/down is a decrease/increase in the y co-ordinate of an entity respectively.
Each entry in the entities
JSON Array will be a JSON Object with the following fields:
x
- the x-position of the entity in the dungeon when the game starts;y
- the y-position of the entity in the dungeon when the game starts; andtype
- the type of the entity.
The type
field will be a string that starts with one of the following prefixes. For automarking purposes, all entities passed in will have a type in the following table.
Entity | JSON Prefix | Creatable in Dungeon Map? |
---|---|---|
Player | player |
Yes |
Wall | wall |
Yes |
Exit | exit |
Yes |
Boulder | boulder |
Yes |
Floor Switch | switch |
Yes |
Door | door |
Yes |
Portal | portal |
Yes |
Zombie Toast Spawner | zombie_toast_spawner |
Yes |
Spider | spider |
Yes |
Zombie Toast | zombie_toast |
Yes |
Mercenary | mercenary |
Yes |
Treasure | treasure |
Yes |
Key | key |
Yes |
Invincibility Potion | invincibility_potion |
Yes |
Invisibility Potion | invisibility_potion |
Yes |
Wood | wood |
Yes |
Arrows | arrow |
Yes |
Bomb | bomb |
Yes |
Sword | sword |
Yes |
Bow | bow |
No, since this entity must be built by the player. |
Shield | shield |
No, since this entity must be built by the player. |
Entity | JSON Prefix | Creatable in Dungeon Map? |
---|---|---|
Assassin | assassin |
Yes |
Hydra | hydra |
Yes |
Swamp Tile | swamp_tile |
Yes |
Sun Stone | sun_stone |
Yes |
Sceptre | sceptre |
No, since this entity must be built by the player. |
Midnight Armour | midnight_armour |
No, since this entity must be built by the player. |
Time Turner | time_turner |
Yes |
Time Travelling Portal | time_travelling_portal |
Yes |
Light Bulb (off) | light_bulb_off |
Yes |
Light Bulb (on) | light_bulb_on |
No, since light bulbs will always be created off. |
Wire | wire |
Yes |
Switch Door | switch_door |
Yes |
Older Player | older_player |
No, since these will only appear when the player has time travelled. |
Some entities will contain additional fields in their JSON entry, namely:
- All entities of type
portal
will have a fieldcolour
. Two portals which have the samecolour
are linked (travelling through one portal takes you to the other). We will never provide a dungeon which has more than two portals of the same colour, and all portals will have a counterpart of the same colour in the dungeon. - All entities of type
door
andkey
will have akey
field which, in the case of thekey
is the identifier of the key, and in the case of thedoor
the id of the key which fits that door.
- All logical entities will be created with the field
logic
which will be one ofand
,or
,xor
, orco_and
. Milestone 2 entities (bombs, switches) that do not have a logic field cannot be activated by wires and act as they did in Milestone 2. Milestone 3 logical entities (light bulbs, switch doors) will always be created with a logic field. Regular doors will never be created with a logic field. - All swamp tiles will be created with a field
movement_factor
which will be the tile's movement factor, an integer >= 0. - Switch doors will also have keys.
A basic goal is represented in the dungeon as:
"goal-condition": {
"goal": <goal>
}
Where <goal>
is one of "enemies"
, "boulders"
, "treasure"
or "exit"
.
A complex goal is represented in the dungeon as:
"goal-condition": {
"goal": <supergoal>,
"subgoals": [
{"goal": <goal>},
{"goal": <goal>}
]
}
Where <goal>
is one of "enemies"
, "boulders"
, "treasure"
, "exit"
, or another nested goal conjunction/disjunction itself, and <supergoal>
is one of "AND"
or "OR"
.
In config_template.json
we have specified the template for a configuration file. This file is important as it specifies internal game mechanics which will affect the external behaviour of your application. Rather than hard coding these constants into your classes, you must instead read in these values from the specified file when the game is created.
During automarking, we will be providing our own configuration files with each test dungeon - this allows our tests to set parameters that should ensure behaviours are produced without ambiguity. For this reason, if you do not read in the values correctly, you will likely fail a large number of our autotests.
JSON Format | Description |
---|---|
ally_attack |
Attack bonus each ally gives to the player. |
ally_defence |
Reduction in effect of enemy attack damage each ally gives to the player. |
bribe_radius |
Radius in which a mercenary can be bribed. |
bribe_amount |
Amount of gold required to bribe a mercenary. |
bomb_radius |
Blast radius of bomb. |
bow_durability |
The number of battles that the bow lasts for. |
player_health |
Health of the character. |
player_attack |
Attack damage of the character. |
enemy_goal |
At least x enemies must be killed to complete the enemy goal |
invincibility_potion_duration |
The effects of the potion only last for x ticks. |
invisibility_potion_duration |
The effects of the potion only last for x ticks. |
mercenary_attack |
Attack damage of the mercenary. |
mercenary_health |
Health of the mercenary. |
spider_attack |
Attack damage of the spider. |
spider_health |
Health of the spider. |
spider_spawn_rate |
Spiders spawn every x ticks, starting from the x'th tick. Spawn rate of 0 means that spiders will never spawn in the game. |
shield_durability |
The number of battles that the shield lasts for. |
shield_defence |
The reduction in the effect of the attack damage of the enemy as a result of the shield. |
sword_attack |
Amount of damage added to a players' attack damage when they use a sword in battle. |
sword_durability |
The number of battles that the sword lasts for. |
treasure_goal |
At least x treasure must be collected to complete the treasure goal |
zombie_attack |
Attack damage of the zombie toast. |
zombie_health |
Health of the zombie toast. |
zombie_spawn_rate |
Zombies spawn every x ticks from each spawner, starting from the x'th tick. Spawn rate of 0 means that zombies will never spawn in the game. |
In Milestone 3, the following configuration fields have been added.
JSON Format | Description |
---|---|
assassin_attack |
Attack damage of the assassin. |
assassin_bribe_amount |
The amount of gold required to perform an attampt to bribe an assassin. |
assassin_bribe_fail_rate |
The chance that the bribe on an assassin will fail. The value of this field should be always inclusively between 0 and 1. |
assassin_health |
Health of the assassin. |
assassin_recon_radius |
The radius within which an assassin can see and move towards the player even when they are invisible. |
hydra_attack |
Attack damage of the hydra. |
hydra_health |
Health of the hydra. |
hydra_health_increase_rate |
The chance that the health of a Hydra increases when it gets attacked each round. The value of this field should be always inclusively between 0 and 1. |
hydra_health_increase_amount |
The increment on the health of a Hydra increases when it gets attacked. |
mind_control_duration |
The amount of time mind controlling via a sceptre lasts for. |
midnight_armour_attack |
Attack bonus wearing midnight armour gives to the player. |
midnight_armour_defence |
Defence bonus wearing midnight armour gives to the player. |
All of the Milestone 2 configuration files (in the provided config files, and in our autotests) do not currently contain the fields listed in Section 4.1.2. Rather than retroactively adding these fields to the existing configuraiton files, you will need to design your implementation to accomodate for this and maintain backwards compatibility. All Milestone 3 configuration files will contain all values from both Milestones.
The layer of abstraction is at the level of the controller. In the starter code, we have provided a class DungeonManiaController
.
The controller methods interact with a HTTP layer in the form of a web server, which we have written for you.
We have provided the following interface data types for you inside response/models
. Similarly as for the assignment, you will need to create objects of these types for the controller to return and communicate information to the server layer.
In case you are interested, The server layer then wraps these objects inside a GenericResponseWrapper
, a generic type we have made for you, and converts these objects to JSON using a libary called gson
to allow them to be communicated to the frontend via a HTTP response.
Constructor Prototype | Description |
---|---|
public DungeonResponse(String dungeonId,
String dungeonName,
List<EntityResponse> entities,
List<ItemResponse> inventory,
List<BattleResponse> battles,
List<String> buildables,
String goals) |
|
public BattleResponse(String enemy,
List<RoundResponse> rounds,
double initialPlayerHealth,
double initialEnemyHealth) |
|
public RoundResponse(double deltaPlayerHealth,
double deltaEnemyHealth,
List<ItemResponse> weaponryUsed) |
|
public EntityResponse(String id,
String type,
Position position,
boolean isInteractable) |
|
public ItemResponse(String id, String type) |
|
public Position(int x, int y, int layer) |
|
public enum Direction {
UP(0, -1),
DOWN(0, 1),
LEFT(-1, 0),
RIGHT(1, 0);
} |
Direction of movement for the player. |
Note: there is also an
AnimationQueue
object and constructor that you can find here but this isn't likely to be until the latter parts of Milestone 2 (and Milestone 3).
Method Prototype | Description | Exceptions |
---|---|---|
public DungeonResponse newGame(String dungeonName,
String configName)
throws IllegalArgumentException |
Creates a new game, where dungeonName is the name of the dungeon map (corresponding to a JSON file stored in the model) and configName is the name of the configuration file.
|
IllegalArgumentException:
|
public DungeonResponse getDungeonResponseModel() |
Return the dungeon response for the current state of the game without any side effects on the game. | N/A |
public DungeonResponse tick(String itemUsedId) throws
InvalidActionException |
Ticks the game state when the player uses/attempts to use an item. The player's action (attempts/using an item) must be carried out first, then enemy movement. As soon as the item is used, it is removed from the inventory. |
IllegalArgumentException:
|
public DungeonResponse tick(Direction movementDirection) |
Ticks the game state when the player moves in the specified direction **one** square. The player's movement must be carried out first, then enemy movement. | N/A |
public DungeonResponse build(String buildable)
throws InvalidActionException |
đź’€ Builds the given entity, where buildable is one of bow , shield , sceptre , or midnight_armour .
|
IllegalArgumentException:
|
public DungeonResponse interact(String entityId)
throws InvalidActionException |
đź’€ Interacts with a mercenary (where the Player bribes/mind controls the mercenary) or a zombie spawner, where the Player destroys the spawner. |
IllegalArgumentException:
|
Method Prototype | Description | Exceptions |
---|---|---|
public DungeonResponse saveGame(String gameName) |
Saves the current game state with the given name so that if the application is terminated, the current game state can be reloaded and play can continue from where it left off. | N/A |
public DungeonResponse loadGame(String gameName) |
Loads the game with the given name from the existing games saved. |
IllegalArgumentException:
|
public List<String> allGames() |
Returns a list containing all the saved games that are currently stored. |
N/A |
Method Prototype | Description | Exceptions |
---|---|---|
public DungeonResponse rewind(int ticks) |
Rewinds the game state a specified number of ticks. |
|
Method Prototype | Description | Exceptions |
---|---|---|
public DungeonResponse generateDungeon(int xStart, int yStart, int xEnd, int yEnd, String configName) |
Generates a dungeon surrounded by walls in a rectangular grid from the start to the end position on the map, where the start position is the top left corner and the exit is the bottom right corner. An exit will need to be at (xEnd, yEnd)
|
IllegalArgumentException:
configName is not a configuration that exists |
If you are completing Extension Tasks 1 + 2, you will need to add code to App.java
which sets up a HTTP endpoint that receives a web request from the frontend to call this API method. The request will be of the following format:
Route Name | HTTP Method | Data Types |
---|---|---|
|
POST |
Parameters: { ticks: int }
Return Type: |
|
POST |
Parameters: { xStart: int, yStart: int, xEnd: int, yEnd: int, configName: String }
Return Type: |
We have handled potential concurrency issues by synchronising all endpoints - you will simply need to need to wrap your function call in the endpoint you create using callUsingSessionAndArgument
. The existing endpoints are a good place to start when writing this code.
The only two exceptions throwable by the Controller are:
IllegalArgumentException
(an builtin unchecked exception) on the specified conditions; andInvalidActionException
(a custom-defined checked exception insidesrc/main/java/dungeonmania/exceptions
).
You can throw them in any order you like, we will not test any input that would fit multiple exceptions at the same time.
You can find more information here.
File | Path | Description | Should you need to modify this? |
---|---|---|---|
|
|
Contains one method for each command you need to implement. | Yes. |
|
|
Runs a server for Dungeon Mania. | No. |
|
|
See Section 6.1. | No - do not modify these as we will rely on them being the same in automarking. |
|
|
See Section 6.1. |
No. |
|
|
Contains a small custom built wrapper around Spark-Java for running a web server. When run it automatically opens a web browser. | No. |
|
|
A checked exception to throw when an invalid action is attempted (See Section 6.3). | No - do not modify this class as we will be relying on it during automarking. |
As you develop your solution you will undoubtedly come across scenarios where the behaviour is not defined by the rules of the specification. In these cases you should make a post on the Assumptions Megathread in the forum asking the Course Staff whether you are able to make an assumption about the behaviour in this case. We will either a) approve the assumption and add it to our list of approved assumptions, which will be listed under the forum post, b) update the specification if appropriate, or c) respond explaining how the behaviour is defined in the scope of the specification.
Any ambiguities/assumptions that we have listed as approved we will not be testing in automarking. However, in many cases your solution will need to implement a particular behaviour (and make an assumption). This will need to be documented, and you will need to write tests for that assumed behaviour where appropriate.
Put your documentation inside a file named assumptions.pdf
in the root directory of this repository.
A possible sample implementation has been released.
It is intentionally incomplete and is intended to give you an idea of the functionality more so than a reference for your development.
In this Milestone, you are expected to:
- Plan for the sequencing of completion of work of the project; and
- Produce an initial domain model for the backend component of your project in the form of a conceptual UML class diagram.
In deciding on your design, you should follow the practices and design principles covered in the course.
Your UML diagram does not need to include any fields or methods for this Milestone. Your UML diagram will need to contain the standard elements such as agregation/composition relationships, cardinalities and inheritance relationships. You do not need to include getters and setters in the UML diagram.
Put your design in a file named design.pdf
in the root directory of this repository.
Based on your initial detailed design you will need to map out as a team the work to complete in Milestone 2.
-
Using the Gitlab Kanban Taskboard, break your design down into a series of tickets/tasks to be completed. Each task should correspond to a unit of functionality (e.g. "Zombies") that on completion of the ticket delivers business value (moves you towards a working software product). Multiple aspects of the same component (e.g. writing tests for Zombies) should not be split across tickets.
-
Once you have done this, you will need to estimate a number of Story Points for each of your tickets (a relative quantification of the amount of work required to complete that ticket). You will also need to allocate a priority to each ticket. If you need a refresher on these concepts you can watch this video (explanation for a minute or two at 39:51).
-
Map out all of the dependencies between tasks visually. How you choose to do this is up to you and there is no strict format. Here is an example of the visualisation from a different project:
You may also wish to allocate due dates for each task and assign team members, though this will not be assessed.
Put all of your planning documentation in a file named planning.pdf
in the root directory of this repository.
This milestone will be submitted in conjunction with Milestone 2. However, you are welcome to submit your UML diagram and assumptions to your tutor for some formative feedback. You may submit any initial work by Week 6, Monday to guarantee feedback from your tutor. Otherwise, you can seek feedback informally up until the Milestone 2 deadline, including during your Week 7 Project Check-in.
In this milestone, you are expected to, based on your initial domain model:
- Produce a complete domain model for the backend component of your project in the form of an updated UML class diagram; and
- Use Test-Driven Development to implement the backend.
Based on feedback and any other changes to your design, update your UML diagram.
For this milestone, your design will need to make use of at least three of the following patterns:
- Strategy Pattern
- State Pattern
- Observer Pattern
- Composite Pattern
- Factory Pattern / Abstract Factory Pattern
You are welcome to use other design patterns in addition if you wish, though any patterns that are forced on and make the design worse rather than better will lose marks for design.
Design patterns you make use of in your test design can also contribute to this tally.
Fields and methods are required on the UML diagram for this milestone. Your UML diagram needs to be consitent with your code and clearly indicate where you're using the design patterns (use labels).
It is a good idea to invest time into your design in this milestone, as a poor design in this Milestone will mean you aren't able to easily adapt your code for Milestone 3 when the requirements evolve. You will be assessed in Milestone 3 on how well you adapted to the changes in requirements and how appropriately you extended and reused your Milestone 2 code.
During your demonstration you will be asked to explain your design choices.
You will need to write:
- Unit and integration tests that ensure the correctness of individual aspects of your model;
- System tests, tests on the controller methods to ensure the backend works correctly at the level of abstraction. Note that investing time into writing these tests is a good idea, as we will be automarking your server via our own tests on your on controller;
- You will need to write your code test-first and have git commits which show evidence of this;
- Coverage will be assessed. We require that your code has 85% branch coverage for full marks.
- You will also likely want to usability test your code (run the game on the frontend and play it).
Prior to starting development you will need to create a testing plan which explains how you will incorporate the different types of tests specified and how this work will be completed in conjunction with your other development work.
You are also encouraged to use include mock tests and mock objects in your test suite - this will reduce dependency between different team members to have functionality completed - however we don't require that you use it.
Put your testing plan inside a file named testing.pdf
in the root directory of this repository.
In this project, we will be emphasising how you deliver your software rather than how you manage your project.
We want you to complete the project in small increments according to the dependency chart you created in Milestone 1. Incremental changes, where at each point you have a working piece of software that you could demonstrate will ensure that even if all work isn't completed, you will still have something to show come the deadline.
To facilitate this you will need to follow this lifecycle for completing each task/ticket:
- Analyse the ticket requirements, including the technical and product specifications.
- Using your high level design (UML diagram) from Milestone 1, on a piece of paper sketch out a detailed design for the ticket. This should include:
- What fields/methods you will need to add/change in a class
- What new classes/packages you will need to create
- Have someone else in your team review the Detailed Design before you start work. One approach is to have, for each ticket, an Assignee (the person who works on the task) and a Reporter (someone who doesn't do the actual work but understands what's going on, and acts as a reviewer).
- Go back and iterate on the design if needed.
- Once the design is approved, write a test list (a list of all the tests you will write) for the ticket. Map out each of the conceptual cases you want to test. This can just be written in a document, or if you want make function stubs for JUnit tests and put up a Merge Request.
- Have someone else in your team review the test list to make sure the test cases all make sense and cover the input space.
- Stub out anything you need to with class/method prototypes.
- Write the tests, which should be failing assertions currently since the functionality hasn't been implemented.
- Implement the functionality so that your tests pass.
- Run a usability test (check your functionality works on the frontend).
- Where needed, refactor your code to improve the style and design while keeping the tests passing.
- Put up a merge request with your changes into
master
. The CI should be passing. The merge request should have a meaningful title and contain a description of the changes you have made. In most cases you should just be able to link them to your design/test list documents. - At least one other person in your team need to review and approve your merge request before you merge your branch into
master
. - Update your collective UML diagram with your detailed design.
- Repeat for the next ticket.
During your demonstration you will need to show evidence of following this process. For one or two tickets prepare some evidence of each step to display to your tutor.
- We will not be assessing your commit messages, though for the sake of good practice you should write meaningful commits.
- Instead, when you merge a branch into master select the Squash Commits option. This will squash all of your branch-specific commits into a single commit during merge. Make sure to uncheck the delete branch option so that your branch is preserved.
- The
master
branch should always remain stable - the pipeline should always be passing. You are welcome to comment out some of the example tests we have provided until you can get them working locally. - When putting up Merge Requests, all changes in the diff should be relevant to the task which they relate to (not polluted with irrelevant changes, as this makes it difficult for reviewers);
- Code reviews should occur as comments on Merge Requests - if you are doing the code review synchronously leave comments on the MR as your minutes/action items
We require you have the following documentation as part of your submission:
design.pdf
with your UML diagram;planning.pdf
with your task sequencing;testing.pdf
with your test plan;assumptions.pdf
with your assumptions documentation;- Your GitLab Kanban Taskboard with your tickets, story points and priorities; and
- Your Merge Request history on GitLab, with comments and discussion.
You are welcome to include additional documentation as part of your submission - meeting minutes, further planning and design and anything else you wish to add which will be looked at and marked, however it is not mandatory. However, documentation will be reviewed if there is a discrepancy in team member contribution, so meeting minutes and other evidence in this situation is helpful.
To submit, make a tag to show that your code at the current commit is ready for your submission using the command:
$ git tag -fa submission -m "milestone2-submission"
$ git push -f origin submission
Or, you can create one via the GitLab website by going to Repository > Tags > New Tag.
Criteria | Description |
---|---|
Software Correctness (35%) |
This section will be entirely automarked. See Section 14. |
Software Testing (15%) |
Code Coverage (9%)
Usability Testing (6%)
|
Software Design (40%) |
General:
Test Design:
|
Software Delivery (10%) |
|
Like any real-world software engineering scenario, the requirements you need to develop your solution to will evolve.
In this Milestone, you will be expected to:
- Adjust your domain model as needed to suit the updated requirements, and as per any feedback on your Milestone 2 design; and
- Extend your backend accordingly, and completing anything leftover from Milestone 2.
- Make customisations to the frontend, to make it your own game.
- If you have time, complete extension tasks.
There is no sample implementation or provided tests for Milestone 3.
This specification document has been updated with the new requirements. To make it easy for you, all places where Milestone 3 Requirements have been added in the product and technical specification have been marked with a đź’€ emoji.
You will need to update your dependency chart with your Milestone 3 tasks once you have done your High Level Design.
As part of this Milestone there is a small component which involves you making customisations via your backend to make use of the animation tools available and in doing so customise the User Experience of your game. The instructions in FRONTEND.md will assist you with this. You are not required to write or modify any frontend code.
Based on feedback and any other changes to your design, update your UML diagram.
For this milestone, your design will need to make use of at least four of the following patterns:
- Strategy Pattern
- State Pattern
- Observer Pattern
- Composite Pattern
- Factory Pattern / Abstract Factory Pattern
- Decorator Pattern
- Singleton Pattern
- Iterator Pattern
- Template Pattern
- Visitor Pattern
The three design patterns you used in Milestone 2 count towards this tally.
You are welcome to use other design patterns in addition if you wish, though any patterns that are forced on and make the design worse rather than better will lose marks for design.
Design patterns you make use of in your test design can also contribute to this tally.
Fields and methods are required on the UML diagram for this milestone. Your UML diagram needs to be consitent with your code and clearly indicate where you're using the design patterns (use labels).
During your demonstration you will be asked to explain your design choices.
Is as per Milestone 2, see Section 12.2 and 12.3.
We require you have the following documentation as part of your submission:
design.pdf
with your updated UML diagram;planning.pdf
with your task sequencing, updated for Milestone 3;testing.pdf
with your test plan, with any updates made;assumptions.pdf
with your updated assumptions documentation;- Your GitLab Kanban Taskboard with your tickets, story points and priorities; and
- Your Merge Request history on GitLab, with comments and discussion.
You are welcome to include additional documentation as part of your submission - meeting minutes, further planning and design and anything else you wish to add which will be looked at and marked, however it is not mandatory. However, documentation will be reviewed if there is a discrepancy in team member contribution, so meeting minutes and other evidence in this situation is helpful.
To submit, make a tag to show that your code at the current commit is ready for your submission using the command:
$ git tag -fa submission -m "milestone3-submission"
$ git push -f origin submission
Or, you can create one via the GitLab website by going to Repository > Tags > New Tag.
Make sure to push to master as well as making the submission tag as we will take this for automarking.
Criteria | Description |
---|---|
Software Correctness (35%) |
This section will be entirely automarked. See Section 14. |
Software Testing (15%) |
Code Coverage (7%)
Usability Testing (8%)
|
Software Design (40%) |
General:
Test Design:
|
Software Delivery (10%) |
|
To test the breadth and depth of your implementation we will be running a series of autotests against your code.
Each section of the product specification is worth a different amount of marks according to its relative complexity. The testing breakdown is as follows:
- Player movement (10 marks)
- Interface methods (success and exception conditions) (10 marks)
- Boulders (10 marks)
- Doors & Keys (20 marks)
- Buildables (10 marks)
- Potions (20 marks)
- Portals (20 marks)
- Bombs (20 marks)
- Spiders (20 marks)
- Zombies (15 marks)
- Battles (40 marks)
- Mercenaries (20 marks)
- Basic Goals (20 marks)
- Complex Goals (25 marks)
Note that some tests will by the nature of the functionality they are testing be integration tests (rely on multiple features to be implemented in order for the test to pass). For example, tests related to goals will inherently also test the functionality related to each part of the goal (e.g. enemies).
The overall automark is out of 260 marks in Milestone 2.
The Milestone 3 automarking will test on a completed interface for Milestone 2. This means that you will be rewarded for finishing off any leftover functionality from Milestone 2.
In addition to the tests listed in Section 14.1, the testing breakdown is as follows:
- Bosses (20 marks)
- Swamp Tiles & Pathfinding (20 marks)
- Further Collectable & Buildable Entities (15 marks)
- Persistence (40 marks)
- Time Travel (50 marks)
- Dungeon Generation (15 marks)
- Logic Switches (30 marks)
The overall automark is out of 450 marks in Milestone 3.
The automark calculation is based on the following rules:
- To achieve a pass (50% of the automark), your solution needs to pass 70 marks worth of tests
- To achieve a credit (65% of the automark), your solution needs to pass 100 marks worth of tests
- To achieve a distinction (75% of the automark), your solution needs to pass 160 marks worth of tests
- To achieve a high distinction (85% of the automark), your solution needs to 195 marks worth of tests
- To achieve full marks (100% of the automark), your solution needs to pass 235 marks worth of tests
- For an extra bonus of up to 5% in the remainder of the overall project, your solution needs to pass all tests.
This marking scheme is designed to make it easy to pass the project and more challenging to achieve a higher mark.
The automark calculation is based on the following rules:
- To achieve a pass (50% of the automark), your solution needs to pass 135 marks worth of tests
- To achieve a credit (65% of the automark), your solution needs to pass 180 marks worth of tests
- To achieve a distinction (75% of the automark), your solution needs to pass 270 marks worth of tests
- To achieve a high distinction (85% of the automark), your solution needs to 340 marks worth of tests
- To achieve full marks (100% of the automark), your solution needs to pass 400 marks worth of tests
- For an extra bonus of up to 5% in the remainder of the overall project, your solution needs to pass all tests.
We have provided you with several example tests to act as a dryrun and ensure that your code doesn't have anything wildly wrong with it that would cause every test to fail. This is intentionally a minimal subset to give you a small leg-up as you are expected to write your own tests to ensure the correctness of your solution.
On Thursday 14th July (Week 7) and Thursday 28th July (Week 9) at 8am we will take the latest commit on your master
branch and run that against our autotest suite. By 6pm that night, we will provide you with a set of results that contain:
- For a subset (a) of our tests, the name of the test, whether you passed or failed it, and if you failed what the error was;
- For another subset (b) of our tests, whether you passed or failed, and if you failed what the error was. The test name will be redacted to "Hidden test", though the section under which it is testing will be made available
- For another subset (c) of our tests, whether you passed or failed, and if you failed what the error was, with no test name or which section it is in.
- The autotest mark you would receive if that was your submission.
There will not be more than one feedback run prior to the deadline for each submission.
In some cases we may update our autotests between the initial feedback run before the deadline and the actual marking of your submissions, as our tests may contain some small errors due to the nature and scale of the project. If this occurs we will post on the forum informing which tests are changing and how they have been changed/corrected.
The autotests will be run against groups' submissions for Milestone 2 Marking on Monday of Week 8 following the deadline. Results of the above format will be released to groups' repositories, except that subset (b) will be provided along with test names and subset (c) will be provided along with the sections they are testing (no names still).
If you are unsure why you are failing a specific test, review your code and the specification, and if you are still unsure please post on the forum and we will be able to provide you with some support.
Following the release of automarks, groups may request a re-run if the group has failed more than 30% of the autotests due to one or two minor issues in their code. The group can make a patch of up to 20 lines difference and push this patch to a branch where it will be rerun at a 20% penalty to the final automark. Diffs of more than 20 lines need to be approved by the Course Authority. All requests for re-runs must be made via the Course Forum. Groups that have not failed more than 30% of the autotests, or have failed due to multiple issues / non-minor issues are not elegible for a re-run. If you are not sure whether you are elegible for a re-run please post on the Course Forum.
Milestone | Due date | Demonstration to tutor(s) | Assessment weighting of project (%) |
---|---|---|---|
1 + 2 | 9pm Sunday 17th July (Week 7) | In YOUR Week 8 project check-in | 50% |
3 | 9pm Sunday 31st July (Week 9) | In YOUR Week 10 project check-in | 50% |
There is no late penalty, as we do not accept late submissions. You will be assessed on the most recent version of your work at the due date and time listed. We will automatically collect and the code that is tagged with the respective submission tag before the deadline. If you do not make a submission tag, we will simply take your last commit on master
before the deadline.
When you demonstrate this Milestone in your lab time, it will consist of a 20 minute Q&A either in front of your tutor and some other students in your tutorial. For online classes, webcams should be on during this Q&A (your phone is a good alternative if your laptop/desktop doesn't have a webcam).
Since there are no extensions for the project, in cases where there are extenuating circumstances that are either approved by Special Consideration, or where a student has an Equitable Learning Plan, we will apply leniency in marking the student's entire group. This will occur during marking and in tandem with any other adjustments of individual marks by the tutor and Course Authority. In all cases please email cs2511@cse.unsw.edu.au.
While it is up to you as a team to decide how work is distributed between you, for the purpose of assessment there are certain key criteria all members must attain:
- Code contribution;
- Non-code contribution;
- Usage of Git/GitLab;
- Attendance at project check-ins;
- Participation in project demonstrations;
- Individual blog posts; and
- Academic conduct.
The details of each of these is below.
While, in general, all team members will receive the same mark (a sum of the marks for each Milestone), if you as an individual fail to meet these criteria your final project mark may be scaled down.
IMPORTANT: If you believe a member of your group is not contributing as they should contribute, you must inform your tutor at the end of that corresponding week. For example, if a group member has not contributed in week 7, you need to report this before the end of week 7. You must not wait beyond this. If you fail to report in time, we may not be able to address the issue and/or apply redistribution of marks.
During your lab time, in weeks without project demonstrations, you and your team will have a short check-in with your tutor. This gives you time to ask questions about the project, and for you to update your tutor on your progress, any issues being faced and receive feedback on ideas/performance in previous Milestones.
Project check-ins are also excellent opportunities for your tutor to provide you with both technical and non-technical guidance.
Your mark for each submission is given to you individually. Your individual mark is determined by your tutor, with your group mark as a reference point. Your tutor will look at your code contribution, documentation contribution, your individual blog posts, any other issues raised by group members throughout term, and your attendance at project check-ins and demonstrations.
While this project is completed in groups, we want you to take the time to reflect individually - on your own contribution as well as your progress as a team. For each submission (Milestones 1 + 2, and Milestone 3) you will need to need to write at least two brief (1-2 paragraph) blog posts. We will give you prompts on the Learning Dashboard for when to make these posts.
If you feel comfortable and aren't sharing anything that could be considered plagarism, make them public and post them in the Blogging Megathread on the forum.
In your blog posts you will also need to describe your contribution for that week to the team, what you have achieved and any challenges you are facing. This will be used to help determine your individual mark for each Milestone.
All team members must contribute code to the project to a generally similar degree. Tutors will assess the degree to which you have contributed by looking at your git history and analysing lines of code, number of commits, timing of commits, etc. If you contribute significantly less code than your team members, your work will be closely examined to determine what scaling needs to be applied.
All team members must contribute documentation and other non-code elements to the project to a generally similar degree. Tutors will assess the degree to which you have contributed by looking at your git history, task board and by asking questions (essentially interviewing you) during your demonstration.
Note that contributing more documentation is not a substitute for not contributing code. Everyone should have the opportunity to work on most, if not all elements of the project.
It is generally assumed that all team members will be present at the demonstrations and at weekly check-ins. If you are absent for more than 80% of the weekly check-ins or any of the demonstrations, your mark may be scaled down.
If, due to exceptional circumstances, you are unable to attend your lab for a demonstration, please apply for special consideration.
The work you and your group submit must be your own work. Submission of work partially or completely derived from any other person or jointly written with any other person is not permitted. The penalties for such an offence may include negative marks, automatic failure of the course and possibly other academic discipline. Assignment submissions will be examined both automatically and manually for such submissions.
The use of code synthesis tools, such as GitHub Copilot, is not permitted on this project.
Relevant scholarship authorities will be informed if students holding scholarships are involved in an incident of plagiarism or other misconduct.
Do not provide or show your project work to any other person, except for your group and the teaching staff of COMP2511. 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.
Note, you will not be penalised if your work has the potential to be taken without your consent or knowledge.
Most assets were taken from public domain sources, but a few require explicit referencing/credits. You can find the credits here.