COMP2511 Part Two: The Belly of the Beast
This page contains the tasks you¡¯ll need to complete for this assignment, and how you¡¯ll be assessed.
1. Getting Started
You can access your pair repository via the following URL:
Copyright By PowCoder代写 加微信 powcoder
https://gitlab.cse.unsw.edu.au/COMP2511/22T3/teams/YOUR_TEAM_NAME/assignment-ii
Replace YOUR_TEAM_NAME with your team name (e.g. M18A_BERYLLIUM )
Watch the following video which goes through approaching the codebase and some VSCode tips and tricks to help you out.
COMP2511 Assignment II: Dungeonmania – The Belly of the Beast
Tip: Explore and code along with the video to get the most out of it!
Task 1) Code Analysis and Refactoring (45 marks)
In this task, you will need to analyse the design of the monolith, including the patterns and smells present in the implementation, and apply refactoring techniques discussed in the course in order to improve the quality of the code.
For this assignment, you will need to make two sets of blog posts:
One which is a pair-completed blog post, which will contain your answers to questions in Task 1, designs for Task 2 and completion of Task 3.
One is your individual blog post/s. As for Assignment I we recommend you write 2-4 blog posts (they don¡¯t have to be long!) over the course of the assignment.
Put all of your answers to the following theory questions in your pair blog post.
For each refactoring change, before you start coding take some time to plan and write up a design in your pair blog post. This
should include:
What fields/methods you will need to add/change in a class What new classes/packages you will need to create
After you finish coding, make a Merge Request into the master branch of your repository with the following:
A meaningful PR title that encompasses the changes
A brief description which outlines the changes being made
Make sure to keep the PR as small as possible – don’t make any extra changes that aren¡¯t absolutely necessary. Try to keep the number of files the changes touch to a minimum.
Make sure all the Continuous Integration checks (regression tests, linting, coverage) remain passing. Your partner will need to code review and either:
Leave comments in the MR with things to fix (you can do code reviews sync or async), requiring you to iterate on the MR and resubmit for review; or
Approve the MR.
Once the MR is approved, copy and paste the link to your MR into your blog post. Then update your UML diagram with the design changes.
a) From DRY to Design Patterns (5 marks)
i. Look inside src/main/java/dungeonmania/entities/enemies . Where can you notice an instance of repeated code? Note down the particular offending lines/methods/fields.
ii. What Design Pattern could be used to improve the quality of the code and avoid repetition? Justify your choice by relating the scenario to the key characteristics of your chosen Design Pattern.
iii. Using your chosen Design Pattern, refactor the code to remove the repetition.
b) Observer Pattern (2 marks)
Identify one place where the Observer Pattern is present in the codebase, and outline how the implementation relates to the key
characteristics of the Observer Pattern. c) Law of Demeter (5 marks)
In the codebase, there is an area of code that does not comply with the Law of Demeter. The message chains code smell is present and indicates this underlying flaw in the design.
i. Find the offending file/packages and lines of code and note them down.
ii. Refactor the code to ensure compliance with the Law of Demeter, in doing so removing the smells.
d) State Pattern (5 marks)
Inside the entities/playerState package, the effects of potions (invisibility and invincibility) has been implemented using a State Pattern. However, the State Pattern hasn’t been used particularly effectively here and as a result there is poor design.
i. In your own terms, explain why the design is poor.
ii. Refactor the code to improve the quality of the design. Whether this means modifying the implementation of the State Pattern, or removing it entirely, is up to you.
e) Inheritance Design (5 marks)
Currently there is a significant flaw in the inheritance structure of entities. Consider the following three methods in the Exit entity class.
public void onOverlap(GameMap map, Entity entity) {
public void onMovedAway(GameMap map, Entity entity) {
11 @Override
12 public void onDestroy(GameMap gameMap) {
13 return;
Make sure to do this for each part of the question.
i. Name the code smell present in the above code. Identify all subclasses of Entity which have similar code smells that point towards the same root cause.
ii. Redesign the inheritance structure to solve the problem, in doing so remove the smells.
f) More Code Smells (5 marks)
The previous engineering team has left you with the following note:
Collectable entities are a big problem. We tried to change the way picking up items is handled, to be done at the player level instead of within the entity itself but found that we had to start making changes in heaps of different places for it to work, so we abandoned it.
i. What design smell is present in the above description?
ii. Refactor the code to resolve the smell and underlying problem causing it.
g) Open-Closed Goals (3 marks)
Look inside the goals package at the code provided.
i. Do you think the design is of good quality here? Do you think it complies with the open-closed principle? Do you think the design should
be changed?
ii. If you think the design is sufficient as it is, justify your decision. If you think the answer is no, pick a suitable Design Pattern that would improve the quality of the code and refactor the code accordingly.
h) Open Refactoring (15 marks)
Make any other refactoring improvements you see fit to the codebase. This can include resolving Design Smells, using Design Patterns discussed or any other general improvements to the health and quality of the code.
Task 2) Evolution of Requirements (50 marks core + 5 marks bonus)
Don’t make solutions to problems that don¡¯t exist yet! 🙂 Avoid over-engineering or over-abstracting in places where you might want to improve the design for some future change in requirements – instead improve the design of the current system. This will inherently make your software open-closed.
You¡¯ll also want to split this task into one MR for each refactoring change you make.
Software Delivery – Task Lifecycle
For each part of this task, you will need to undertake the following process:
1. Requirements Engineering. Analyse the task requirements, including the technical and product specifications. If you need to, make some assumptions and document these in your pair blog post.
2. Detailed Design. In your pair blog post, plan out a detailed design for the task. This should include: What fields/methods you will need to add/change in a class
What new classes/packages you will need to create
3. Design Review. Have your partner review the design, and go back and iterate on the design if needed.
4. Create a Test List. Once the design is approved, write a test list (a list of all the tests you will write) for the task. Map out each of
the conceptual cases you want to test. This can be written in your blog post, or if you want make function stubs for JUnit tests and put up a Merge Request (link in your blog).
5. Test List Review. Have someone else in your team review the test list to make sure the test cases all make sense and cover the input space.
a) Micro-Scale Evolutions (15 marks)
In this section you will need to make a series of small-scale changes and additions to the code based on the following new requirements.
You will need to write tests for the new functionality in an appropriate section of the test suite.
i) Enemies Goal (5 marks)
The following new goal has been introduced:
Destroying a certain number of enemies (or more) AND all spawners;
Other goal rules, including rules of conjunction/disjunction and exits must be completed last, still apply. ii) Allies (5 marks)
The movement of allies has changed from moving randomly to the following:
Allies that are not adjacent to the player should follow the player using Dijkstra algorithm to approach the player. Once it reaches the square adjacent to the player it occupies the square the player was previously in
There were no tests for this behaviour previously, so adding new changes should not break any existing tests. You will need to add new tests for the functionality.
iii) Bosses (5 marks)
Bosses are moving entities which are harder to defeat/conquer than normal enemies. For this task you need to implement one out of the following two bosses.
Image Description
If you’ve done Task 1 well and have a nice healthy codebase, this task should be relatively straightforward! If you’re finding parts of this task difficult to integrate with the existing design, that’s probably a sign you need to do some more refactoring 🙂
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. Battles still do not occur with an Assassin when the player is invisible.
6. Create the Skeleton. Stub out anything you need to with class/method prototypes.
7. Write the tests, which should be failing assertions currently since the functionality hasn’t been implemented.
8. Development. Implement the functionality so that your tests pass.
9. Run a usability test (check your functionality works on the frontend).
10. Where needed, refactor your code to improve the style and design while keeping the tests passing.
11. 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 blog.
12. Code Review from your partner, iterate where needed then they should approve the MR.
13. Documentation. Update the UML diagram with your final detailed design.
Feel free to split tasks further where you see fit, especially for larger tasks (e.g. Time Travel). Keep your Merge Requests small and make the iteration cycle short, incrementally building your MVP as you go.
Hydras are generally considered to be a special creatures similar to Zombies. Hydras are limited by the same movement constraints as Zombies. In each round, 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.
b) Macro-Scale Evolutions (40 marks)
i) Sun Stone & More Buildables (15 points)
i) a) Further Collectable Entities
In this task, the following collectable entities need to be added:
i) b) Further Buildable Entities
In this task, the following buildable entities have been added:
Description
A special form of treasure, hard and treasuable. It can be picked up by the player. Can be used to open doors, and can be used interchangeably with treasure or keys when building entities. But it cannot be used to bribe mercenaries or assassins. Since it is classed as treasure it counts towards the treasure goal. When used for opening doors, or when replacing another material such as a key or treasure in building entities, it is retained after use.
Can be crafted with (1 wood OR 2 arrows) + (1 key OR 1 treasure) + (1 sun stone). A character with a sceptre does not need to bribe mercenaries or assassins to become allies, as they can use the sceptre to control their minds without any distance constraint. But the effects only last for a certain number of ticks.
Midnight Armour
ii) Swamp Tile (20 points)
Description
Can be crafted with (1 sword + 1 sun stone) if there are no zombies currently in the dungeon. Midnight armour provides extra attack damage as well as protection, and it lasts forever.
As part of this, you will need to extend your solution to accommodate 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 and allies adjacent to 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.
Swamp Tile
iii) Persistence (40 points)
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 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.
iv) Time Travel (50 points) iv) a) Time Turner
This part of the extension includes the following new entity:
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.
iv) b) Time Travelling Portal
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.
iv) c) Time Travel Rules
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 player are carrying a sun stone or are wearing midnight armour, or they are invisible, then nothing happens. If not, then a battle ensues.
The 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.
The older self is in the enemy party and doesn¡¯t fight the enemies.
Mercenaries and assassins follow the current player, not the older player
The behaviour when time-travelling occurs more than once in a single game instance is undefined.
Only the player 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. Note that usage of a time turner (a rewind operation) is not the same as travelling through a time portal – the latter takes up a tick, whereas the former does not.
The following diagram should help you understand the state transitions for time travel.
Tick Diagram: Time Travel
v) Logic Switches (30 points)
There are three new entities in this extension:
Light Bulb
Light bulbs cannot be collected, but can be lit up by satisfying the logical condition if they are created as a logical entity. Otherwise they can be lit up by placing a boulder on an cardinally adjacent switch. Light bulbs will always be created off.
Wires cannot be collected, but form part of a circuit as a conductor and are connected to a switch and any entity that interacts via switches. Wires are not themselves logical entities. Any moveable entity can walk onto a wire.
Switch Door
Switch doors can be opened:
If created as a logical entity, by satisfying the logical condition Otherwise, by being connected to an active switch/circuit.
They cannot be opened with a key. The door should only remain open as long as its condition for opening is still true.
Image Description
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 circuits. For example:
Implementation Hint
The design of this task 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.
v) a) Logical Entities
Entities which interact via switches can become ¡°logical¡± entities with a specified configuration value:
Light Bulbs (see above)
Switch Doors (see above)
Bombs – a non-logical bomb behaves normally. A logical bomb only explodes when the logical condition is satisfied.
Switches are not logical entities, but instead activate cardinally adjacent entities when switched on. When placed next to another already activated entity, they behave akin to wires in a circuit (they act as a conductor). Light bulbs, switch doors and bombs do not act as conductors.
All switches will be created in inactive state as well as all the logical entities.
All other entities cannot be part of the circuit. They can be placed adjacent to the logical circuit but don¡¯t have any effects. v) b) Logical Rules
Entities will be logical according to one of the following rules:
AND – the entity can be activated if there are 2 or more cardinally adjacent activated conductors. If there are more than two conductors, all must be activated
OR – the entity will be activated if there is 1 or more cardinally adjacent conductor
XOR – the entity will be activated if there is 1 and only 1 cardinally adjacent activated conductor
CO_AND – the entity will only be activated if there are 2 or more activated conductors cardinally adjacent, which are both activated on the same tick, e.g. a switch activated two wires at the same time which are both cardinally adjacent to the entity.
vi) Dungeon Generation (20 points)
This task involves modifying the frontend code; if you’re interested in learning a bit of frontend and trying TypeScript then have a go!
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.
3.12.1 Generating a Dungeon – Randomized Prim’s Algorithm
You will need to generate dungeons according to the following maze generation algorithm (which is just a randomised version of Prim’s).
1 2 3 4 5 6 7
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
3.12.2 Frontend Code
In order to implement the frontend for this task you¡¯ll need to modify the TypeScript
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com