[SOLVED] 代写 R C++ C game GUI html Spark UML parallel compiler database graph software Go 2. Design Patterns

30 $

File Name: 代写_R_C++_C_game_GUI_html_Spark_UML_parallel_compiler_database_graph_software_Go_2._Design_Patterns.zip
File Size: 960.84 KB

SKU: 7562874499 Category: Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Or Upload Your Assignment Here:


2. Design Patterns
In developing the class design for the Dungeon Crawler game, the following the Design Patterns MUST be incorporated:
•Singleton (simple only)
•Builder
•Decorator
•Prototype
This section provides brief descriptions of each relevant design pattern in turn. For more information refer to the readings (and Lynda.com tutorials) provided on the course website and the book from which these summaries are derived:
Gamma, E, Helm, R, Johnson, R and Vlissides, J 1995, Design patterns : elements of reusable object-oriented software, Addison-Wesley, Boston, Massachussets.
Be aware that the C++ examples from the book are for an older version of C++. If using them for guidance, they must be updated to C++ 17.
For convenience, links to the readings and Lynda.com tutorials are provided below:
Singleton
•Singleton Pattern
•Singleton Pattern (Alternative Description)
•Lynda.com Singleton Pattern
Builder

•Builder (Alternative Description)
•Lynda.com Builder Pattern
Decorator

•Decorator (Alternative Description)
•Lynda.com Decorator Pattern
Prototype
•Prototype Pattern
•Prototype Pattern (Alternative Description)
•Lynda.com Prototype Pattern
2. Design Patterns
2.1. Singleton
The Singleton pattern addresses the problem of ensuring that a class has only one instance. Moreover, the one instance is easily accessible but in a controlled fashion. Such a pattern arises in situations where a single, globally accessible interface to a system or subsystem is required and, hence, is often used with other patterns such as Façade and Abstract Factory. An example of a singleton is an application wide configuration. Rather than parsing the configuration file multiple times and storing multiple copies in memory, the configuration file should be read once and stored once. Moreover, since various parts of the application may need to access different settings, the configuration should be globally accessible to ensure the configuration is accessible when needed. Other examples include: a single print spooler governing access to the printer resources, a single thread/connection pool handing out connections or threads to clients that request them, etc.
When to Use
The Singleton pattern should be applied to a class when:
•Exactly one instance of the class must exist, and
•A well-known access point to the instance is required
In general, the extensibility of a Singleton through subclassing should also be considered. It will not be required for this assignment; however, it is important to note as a common criticism of the Singleton pattern is that it becomes tied to implementation and makes testing difficult due to the inability to replace the singleton instance with a mock or stub (i.e., a test specific class that is not a complete implementation).
General Structure

A simple representation of the Singleton pattern includes only a Singleton class, i.e., the class that should be a Singleton, containing: a static member function instance() that returns the unique instance of the class, a hidden constructor, and a static data member to hold the unique instance of the class.
Note the ‘+’ indicates public accessibility and ‘-‘ indicates private accessibility. If considering extensibility of the Singleton through subclassing, the constructor should be protected rather than private.
Implementation Hints
In C++, the compiler may generate some constructors and operators for you. Ensure you prevent the Singleton from accidentally being copied or assigned in ways you do not intend by deleting any automatically generated members that you do not need. You MUST indicate in your diagram whether you have deleted any constructors/operators and what they are.
In C++, the static data member can be implemented in two different ways: within the scope of the class or within the scope of the function. Consider the consequences of each approach and justify your implementation choice in your comments.
2. Design Patterns
2.2. Builder
The purpose of the Builder pattern is to separate the representation of a complex object from the process used to construct it. Further, such separation allows different representations to be constructed from the same process. For example, a Parser using a Builder to construct a parse tree in different systems: the recognition of the syntax is handled by the parser, which calls the builder to create the appropriate parse nodes and retrieves the final parse tree from the Builder once the parsing is complete. The different representations may or may not be related, for example, an executable parse tree of the parsed syntax, a parse tree for another language (such as in code transformation), or a composition of widgets for visualising the text processed by the Parser.
An important aspect of the Builder pattern that differentiates it from other creational patterns is that it supports the creation of complex objects in a step-by-step process, rather than all-at-once.
When to Use
The Builder pattern should be a applied when:
•the construction process is, or should be, independent of the object, its parts, and the way that it is assembled, and
•the construction process should allow for different representations to be created.
Note that there does not always need to be multiple representations, only that multiple representations are possible. One of the motivations for good design is to support future change more easily.
General Structure

The Builder pattern contains several interacting classes, including:
•the Director, which represents the entity that needs a Product object to be constructed and ‘directs’ the Builder to construct it;
•the Builder, which specifies an abstract interface for constructing any Product object, this may include many different member functions for constructing different types of parts;
•one or more ConcreteBuilders, which create specific Products from its parts by implementing the abstract Builder interface and allows the Product to be retrieved once complete as it maintains the representation internally during construction;
•the Product class, which represents the complex object being created by a ConcreteBuilder as well as its parts.
Note: the Product box in the diagram does not mean the classes for the parts are encapsulated by the Product class, only that the diagram is simplified to not explicitly illustrate any of the Product’s parts. For example, if the Product were a ParseTree, it would be composed of many ParseNodes of different types.
Implementation Hints
If the representations being constructed by the different ConcreteBuilders are related, the abstract Builder may declare an appropriate getResult() member function as part of its interface.
The ConcreteBuilder object is not required to be supplied to the Director via a constructor, it could also be a parameter to a member function.
The interface should include several ‘build*()’ member functions that create the different components of the Product and connect them as required.
2.3. Decorator
The Decorator pattern is used to dynamically associate additional functionality or responsibilities to an object at runtime, rather than a class. The common exemplar is the addition of a border to GUI widgets: the widgets themselves may or may not have a border, scroll bar, etc., but can be wrapped in an object that understands how to draw a border around the widget, i.e., a decorator. This pattern is an example of favouring composition over inheritance, which results in greater flexibility. Consider using inheritance to add a border to a widget, displaying the widget would require a check for whether a border should be drawn then display the border followed by displaying the widget itself. Now consider that widgets can have a scroll-bar and a border, displaying the widget would have to check and display the border then check and display the scroll-bar. Most, if not all, widget classes would inherit this capability even though many instances of those widgets would not require it. By separating out these responsibilities into distinct classes that can be composed, the widget can worry about displaying itself, while the border decorator can focus on drawing a border and the scroll-bar decorator can focus on the scroll-bar. This has no impact on the calling code as the decorators conform to the same interface as widgets but delegate most function calls straight to their component, which may be another decorator. Apart from reuse, this pattern supports extensibility as new decorators can be added without affecting those already implemented.
When to Use
The Decorator pattern should be used when:
•responsibilities or functionality should be added to specific objects dynamically,
•such responsibilities may be removed dynamically, and
•the use of inheritance is impractical, e.g., supporting all combinations of responsibilities would become cumbersome.
Note: The decorator pattern is best applied when the shared base class is (or can be made) lightweight, with few data members, otherwise the overhead for having many objects may become a problem.
General Structure

The Decorator pattern includes several classes with responsibilities as follows:
•an abstract Component that defines the common interface for objects that support dynamically added responsibilities;
•the ConcreteComponent, which represents the specific types of object that can have responsibilities attached;
•the abstract Decorator that maintains compatibility to the Component interface by referring to a Component object and delegating the function calls to the underlying object;
•the ConcreteComponent, which represents the specific types of object that can have responsibilities attached;
•the abstract Decorator that maintains compatibility to the Component interface by referring to a Component object and delegating the function calls to the underlying object;
•the ConcereteDecorator classes, which add responsibilities to the Component object and may provide additional behaviour and/or state.
Implementation Hints
When implementing the decorator pattern, more than one operation of the component type can have their output modified by a decorator. For example, a border decorator might decorate the draw operation (to display the border) as well as the size operation (to add the border thickness to the reported size of the widget).
The abstract Decorator is conceptually abstract and must be displayed as such in the UML Class diagram. However, it may not be able to be defined as ‘abstract’ in any particular programming language. This is the case in C++ since the decorated operation(s) will have implementations on the abstract Decorator that delegate to its component and, hence, there may not be any member functions declared with no definition. Remember, a C++ class is only considered abstract if it has at least one declared member function without an implementation.

2.4. Prototype
A common problem in applications is the dynamic creation of types at runtime, rather than static definition and compilation at design time. The Prototype pattern is one of the ways to address this problem. It allows special instances (called prototypes) to be created that represent the type itself. These prototypes can be cloned (i.e., copied) to create the actual instances of the type. This makes the design more flexible and eliminates the need create a large number of classes at design time. It also makes the application more configurable, as the data for the prototype instances may come from a data source loaded at runtime, for example, rather than hard coded into the application.
A common example of the Prototype pattern is a graphical editor where the tools in the toolbar (e.g., circles, rectangles, etc.) are represented by prototype instances. Placing a shape onto the canvas clones/copies the prototype, thereby instantiating it on the canvas with all of the same values as the prototype. This also allows for configurable default values: changing the defaults actually changes the values of the prototype. In this example, there may still be a hierarchy of classes (e.g., Circle, Rectangle) to support specific behaviour of those shapes; however, it could be reduced further if the actual shape were separated from the graphical element, i.e., a simple ‘Protoype’ class contains the underlying shape object as part of its configuration.
When the number of prototypical objects is large and can change dynamically, it may also be appropriate to use a prototype manager, i.e., a class in which the prototype instances are registered, looked up, and copied. In the above example, the editor’s toolbar may act as prototype manager, where the different shape prototypes are registered and looked up and cloned when the user selects a particular shape in the GUI. The prototype manager exhibits similarities to the Factory family of patterns (Abstract Factory, Factory Method, etc.), but can be more dynamic.
When to Use
There are several situations in which the Prototype pattern is applicable. The situations most relevant to the assignment are when:
•the classes/types to be instantiated at run-time are dynamic,
•the number of different types is very large, and
•it is desirable to avoid building a large class hierarchy of entities to be instantiated and its parallel hierarchy of factories.

General Structure

The Prototype pattern includes several participants with the following responsibilities:
•the Prototype abstract class that defines the interface for cloning/copying the object;
•one or more ConcretePrototype classes, which implement the clone operation to create a copy of themselves; and,
•the Client class, which requires an object of the Protoype type and asks it to clone itself.
Note: some diagrams of the Prototype pattern illustrate a separation of the ‘Product’ interface from the ‘Prototype’ interface. Such an approach is good for separation of concerns and re-usability by maintaining a distinction between the ability for an object to clone itself and the behaviour of the object as a domain object. Such a separation is not required for this assignment, however, as you only need to apply the Prototype pattern to a single hierarchy.
Implementation Hints
When using a prototype manager the Client does not itself ask the Prototype to clone itself. Instead, the prototype manager asks the Prototype to clone itself, and the Client asks the prototype manager to find the desired Prototype and return a new clone of it.
When implementing the clone operation, consider whether it needs to be a deep-copy, i.e., where the copy becomes completely independent of the original by also copying/cloning its components, or a shallow-copy, i.e., where there copy shares common components with the original.

3. Task Description
Roguelike Dungeon Crawler games are a genre of game that exhibit features typically attributed to the 1980s computer game Rogue [https://en.wikipedia.org/wiki/Rogue_(video_game)]. In general, the goal of a Roguelike game is to clear a dungeon, level-by-level, until the final level is completed. Common features of a Roguelike game include:
•procedurally generated dungeons,
•randomised items and weapons,
•permanent death, and
•a variety of creatures to fight that get progressively more difficult deeper into the dungeon.
Within each level of a dungeon there typically exists distinct rooms where creatures are encountered and items are waiting to be looted.
In this assignment, you will design and implement a simple text-based Roguelike Dungeon Crawler game that fulfils the following specification. Unlike the original Rogue, text-based does not mean ASCII art but instead will be driven by a text-based menu interface inspired by another genre of text-based adventure game originating from Multi-User Dungeon (MUD) [https://en.wikipedia.org/wiki/MUD1]. Moreover, combat will be turn-based with only one opposing creature at a time.
The aim of the assignment is to allow you to practise creating an object-oriented design and implementing it in C++ using the features learnt so far, namely: class inheritance and polymorphism, dynamic memory allocation, and smart pointers. The focus of the assignment is on identifying and applying appropriate Design Patterns to help develop the game in such a way that components are easily reusable and extensible—remember the DRY (Do Not Repeat Yourself) principle.
In this first part of the assignment you will need to develop a class design using UML class diagramsbased on the requirements in the remainder of this specification and the initial UML Class Diagram that will be provided. A simple and free UML editor that can be used for this assignment is UMLet [http://umlet.com/]. The UML class diagram MUST include all classes, public and protected members (i.e., data members and member functions), and all associations between classes. The diagram may optionally display private member functions, but private data member MUST not be included.
Note: You will be provided with an initial diagram including the classes without their interfaces and associations defined, with some exceptions. The provided diagram may also indicate that for some classes you do not need to provide the public/protected members at all. Such classes will be clearly identified.
For this assignment the game has been simplified to a certain extent, e.g., dungeon creation is not completely procedural. Moreover, some of the underlying elements (such as the basic menu interface code) will be provided to get you started (the Qt Creator project will be provided alongside part 2 of this specification closer to the due date of the Class Diagram). The provided code will be incomplete and may need to be modified to fit your class design. Parts of the provided code that must not be modified will be marked as such. You will then need to implement the rest of the game according to the specifications and your design.
A brief example of how the game will be played is provided below. The remainder of the section describes the requirements of the game in more detail.
Note: the following conventions will be used when illustrating example output:
•a ‘>’ at the beginning of a line indicates the command line prompt
•bold orange text indicates input entered by the user
•user input surrounded by square brackets ‘[…]’ indicates a specific key press
•hitting [Enter] after other input is implied

3. Task Description
3.1. Work Plan
To complete the first part of this assignment, you will need to perform the following steps:
•Read the assignment specification carefully.
•Read the descriptions of the Design Patterns (both those within this document and the additional materials provided via LearnOnline).
•Download the provided UML Class Diagram.
•Identify which role each participating class plays within the identified Design Patterns. Be sure to clearly annotate the role in the diagram itself.
Note: some classes participate in more than one Design Pattern and, hence, will have one role per Pattern.
•Connect the classes using associations to complete the structure of the Design Patterns.
•Add the interfaces to each class related to the Design Patterns, the names of the operations (member functions) should be guided by those used in the patterns but made specific to this application.
•Add any annotations you think are required, justifying certain decisions or providing an example of your intention.
•Add additional classes, inheritance, and behavioural interfaces to the classes that you think will be required to make the application functional based on the high-level requirements provided in this document.
The last aspect does not have to be complete or 100% correct at this point in time. It will give you the opportunity to think about the structure and flow of the application before starting the implementation. You can revise it later as the you progress through the implementation, for example, you may realise you are missing some arguments to a member function or missing an entire function. The marking of this aspect will focus the appropriate assignment of responsibilities, separation of concerns, good naming, etc.
At this point you do not need to differentiate between the use of pointers or not. This is a conceptual design, choice of pointer type is an implementation decision specific to the implementation language (C++ in this case).
After completing the design, generate a PNG or PDF version of the diagram and submit it to LearnOnline.
3.2. UML Class Diagram
You will use the provided UML Class diagram as the basis for your design. It includes the classes that have been identified in the specification and that will appear in the skeleton code provided as part two of the assignment (the implementation).
You may include additional classes if you desire and can justify their inclusion: the most appropriate design will require a limited number of new classes, for example, some generalisations (abstract classes) can be introduced to improve reuse and limit duplication. Provided classes that you MUST NOT modify will be identified as such. Otherwise, you are free to adapt provided classes to fit the Design Patterns and requirements.
The classes are annotated with the Design Pattern(s) in which they participate. You will be required to do the following:
•identify which role each class plays within those patterns and label the roles in the diagram;
•relate the classes to one another according to the Design Patterns in terms of associations, composition/aggregation, and dependency links;
•provide the interfaces (i.e., the set of member functions/methods that allow the objects to fulfil their function) in accordance with the patterns;
•structure the classes into appropriate inheritance hierarchies (the Design Patterns will only get you part of the way there); and
•provide the behavioural interfaces related to the responsibilities of each class in the application beyond that which is required by their Design Patterns.
For example, the class that plays the role of Prototype in the Prototype Pattern will require a clone()operation as described by the pattern, but will also require additional behaviour related to the nature of the class itself and the responsibilities it is assigned within the Dungeon Crawler application.
This assignment aims to give you practice using inheritance and polymorphism as key elements of creating Object-Oriented applications. Care should be taken in identifying appropriate abstractions and make use of abstract classes  (and interfaces) to create a good design. Remember the principle ‘Program to an Interface and not an Implementation’.
The initial UML Class Diagram is shown below. You will need to download the source file[https://lo.unisa.edu.au/pluginfile.php/2393310/mod_book/chapter/237205/dungeon_crawler_class_diagram.uxf]: you will need UMLet [http://umlet.com/] to open the file.
If the download link above opens a new page rather than a download file, right-click on the page that opened and select “Save Page As…”, then browse to the desired location on your computer and save the file. Be sure to remove the ‘.xml’ extension on the file name if one has been added.

Appendix A of the course textbook includes a brief review of UML Class Diagrams if you cannot remember the notation. Note that we abuse the notation for stereotypes to annotate the classes with the Design Pattern(s) in which they take part. You may do the same to label the roles of each class within the Design Patterns.

3.3. General Gameplay and Requirements
The gameplay state will be controlled by a Game object. There can only ever be one game in play at one time, i.e., it is a Singleton.
The game allows a player character (Character) to explore a dungeon of the user’s choice, room-by-room. Along the way they may encounter creatures that they will have to defeat before they can continue exploring (unless they can find a way around them). They will also come across weapons to loot that will help them defeat the creatures they encounter. The last room in the dungeon typically has a more powerful monster (a ‘boss’ monster) that needs to be defeated for the exit to reveal itself, but it is not required.
There are two types of dungeon that the user can explore: a “basic” dungeon (BasicDungeon), and a “magical” dungeon (MagicalDungeon). Each dungeon type will be populated with their own sets of room types (Room and its class hierarchy), creature types (Creature and its class hierarchy), and weapon types (Weapon and its class hierarchy).  Each of these elements will require descriptions that are displayed to the user as they traverse the dungeon and encounter them. There may be some overlap between what appears in the different dungeon types. For example, some creatures may appear only in basic dungeons, magical dungeons, or in both.
In general, the user will be able to perform a number of different actions each ’round’, including:
•Move the character to the next room: North, South, East, or West
•Move the character to the previous room (whether this is North, South, East, or West depends on the door the user “came through”)
•Pick up an item/weapon
•Compare the weapon/item in the room with that currently held by the character
•Attack the creature
•Use the weapon’s special ability
•Return to the main menu

3.4. Menu
User interaction with the game will be performed through the MenuInterface class. This class has the sole responsibility of commandline IO in the application, i.e., it handles the display of the menu options and processes the inputs from the user. The basic structure of the MenuInterface class and its interface will be provided for you. As the number of member functions is quite large, you will not be required to include them in the design diagram.
When it comes to implementation, you will need to implement the transitions between menus and the interactions with the Game class, which is responsible for maintaining and updating game state.
Further details of the menu (e.g., key bindings) will be provided in the specification for part 2 of the assignment.
3.5. Player Character
The player character is represented by the Character class. This class will maintain the state regarding the player’s character as well as define behaviours appropriate to the character (i.e., update the game state as appropriate based on the character’s actions).
A character has a name (provided by the player), properties that may impact the gameplay and the character’s actions, and a weapon. These are collectively referred to as the player’s “stats”. When the player chooses the option, the character’s stats must be displayed.
There are three basic properties that are defined at character creation (based on choices made by the user) and are not changed during gameplay, including:
•Strength: allowable values 1-6, each value > 1 contributes to the damage of the character
•Dexterity: allowable values 1-6, each value > 1 contributes to the dodge chance of the character
•Wisdom: allowable values 1-6, each value > 1 contributes to the effects of magical items
There are also three dynamic properties that may change during gameplay or based on the above basic properties:
•Health points: starts at 50 and is reduced by taking damage from creatures (whole numbers only). Once it reaches zero (or less) the game is over. Various items and special abilities may increase the amount of health, but not above the original value.
•Damage: calculated from the current weapon and Strength. The strength bonus is equal to 2×(Strength−1)2×(Strength−1). That is, each point of Strength above 1 adds twice as much to the damage.
•Dodge chance: percentage, used to determine whether the character will get hit by a creature when it attacks. 100% means the character will dodge every attack. Calculated as: 100÷5×(Dexterity−1)100÷5×(Dexterity−1)
That is, each Dexterity point above 1 adds 20% to the dodge chance.
When the game is first started the user must create their character. They will be required to enter the name of their character and allocate a limited number of points to the three basic stats (Strength, Dexterity, and Wisdom). A new character is always created with the ‘Fists’ weapon type.
3.6. Dungeon (Rooms, Walls, Doors)
A dungeon level consists of a connected set of rooms and are to be represented by the Dungeon class. Each room of a dungeon (represented by the Room class) must be identifiable by a number (integer) so that they can be retrieved from the dungeon object using the numeric identifier. Each room has 4 directions: North, South, East, and West. In each of these directions, there may be a wall (the Wall class) or a door (the Door class). Doors are connected to adjacent rooms via a door in the opposing direction. For example, if a room has a door to the north, the northern room has a door to the south.
Most doors are connected to each other to allow movement between rooms in both directions. There are two exceptions: the entrance to the dungeon level, and the exit. Your design will need to consider how the entrance and exit are represented. When the user chooses to go through the dungeon entrance, they will be returned to the main menu as if they chose the option to return to the main menu, that is they will lose their progress and the dungeon and character will have to be recreated. When the user chooses to go through the exit door, they will be returned to the main menu ready to continue to the next dungeon level.
Each room may contain a creature (Creature), a weapon (Weapon), or both. If both are present in the room, the weapon cannot be picked up by the user and will “appear” after the user defeats the creature.
When the user enters a room, a description of that room must be provided to the user. The description includes what the room “looks like” (this is up to you, or you can use the text of the examples) and what the character “sees”, that is, where the doors are located, whether a creature or item is present. Descriptions of walls may be included.
When a dungeon level is being created, various elements must be selected randomly, including: the type of room, the type of creature (if present), and the type of item/weapon (including enchantments, if present). We will use the Builder Pattern to control the dungeon creation.
Note: for simplicity, the size of the dungeon (i.e., the number of rooms) and the connections between rooms will not be randomly generated for this assignment. Moreover, it is not requiredto do any complex registration of types: a simple switch statement will be acceptable, for example. More details will be provided in part 2.
The game will include two dungeon types: a basic dungeon (BasicDungeon class), and a magical dungeon (MagicalDungeon class). Each dungeon type can contain different types of rooms, walls, doors, creatures, and/or weapons. Refer to sections Creatures and Weapons & Enchantments for details of the creatures and items, respectively. The supported combinations of dungeon elements are listed in the following table.
Note: the constraints below do not have to be encoded into the design as hard restrictions. They can be knowledge that the builders have about what components are allowed to be combined, which would be represented simply as dependencies. It is important not to over-constrain the design at this point. Imagine, for example, if a new dungeon type is created that mixes Rock Chambers and Enchanted Library room-types, you do not want to need to modify all the strict associations that enforce the original combinations. Make appropriate use of abstractions and interfaces.

3.7. Creatures
Dungeons, specifically rooms, can be inhabited by numerous foul creatures. There can be at most one creature per room and a creature never leaves the room in which it is created. All creatures must derive from the class Creature and conform to the Prototype Pattern, as the creature types will be loaded from a data source at runtime. When the user encounters a creature in a room they must defeat it in combat before moving on or picking up an item (if present). Alternatively they can return the way they came and attempt to find a way around it. Each type of creature has different stats, but otherwise has the same types of stats as the player character. These stats are:
•Strength
•Dexterity
•Wisdom
•Health
•Damage
•Dodge chance
The bonuses provided by the basic stats are calculated in the same manner as that of the player character and then halved. If a creature is a ‘boss’ (i.e., it is in the room with the exit door) the penalty is not applied.
In this assignment, the creature types will be loaded from a CSV (comma separated values) file. You will be required to implement a simple CSV parser in the CsvFile class. The interface for the CsvFile class will be provided, along with a set of Unit Tests, to which you must implement a conforming solution. For the design, you will need to identify the best place for the CsvFile class to be used, its associations, and dependencies. Remember the principles of loose coupling, minimising dependencies, and separation of concerns.
The CSV file used by the application will be generated by the class. There will be a ‘database’ module on LearnOnline in which you can enter the details of a Creature type (if each student enters 1 creature type there will be 160+ types in the game). You will then be able to download the CSV file from LearnOnline to be used by the application at runtime.
All creatures will attack using a weapon in the same manner as the player character. If the weapon has a special ability, the creature may choose to use the weapon’s special ability rather than a standard attack. Refer to the section on Weapons & Enchantments for details.
3.8. Weapons & Enchantments
The game allows characters and creatures to carry a weapon (only 1 weapon, and always 1 weapon), which they use in combat or at any time to affect their environment. In addition, weapons can be enchanted to give them extra bonuses or special effects for the character to use. Special effects may have an arbitrary effect on the game state. Creatures that have weapons can attack with them or use their special ability (if they have one). The weapon enchantments will be handled using the Decorator Pattern, which allows additional behaviour of the enchantment to be dynamically added to the basic behaviour of the underlying weapon.
Weapons (represented by the Weapon class) have a name, a short description (used on the character details display), a long description (used on the weapon specific display), and a damage stat (minimum and maximum value). Their primary use is for attacking a creature (or the character if owned by a creature) during combat. Some weapons may also have a special ability that the character (or creature) may use during combat, while some special abilities may also be usable outside of combat (character only).
Weapons can be enchanted (represented by the Enchantment class), which add bonuses and/or special abilities to the weapon on which they are placed. Each weapon may have up to two enchantments. Enchantments change the reported name of the item and can be either ‘prefix’ enchantments—add a term (or terms) to the beginning of the name—or ‘suffix’ enchantments—add a term or terms to the end of the name. Only one of each type may enchant a weapon at the same time, i.e., if there are two enchantments on a weapon then one will be a prefix and one will be a suffix. For example, the ‘Flaming short sword of healing’ is a short sword weapon with a prefix enchantment named ‘flaming’ and a suffix enchantment named ‘of healing’.
Enchantments on a weapon may change the standard damage of the weapon when it is used to attack, or it may add a special ability to the weapon. Special abilities added by an enchantment follow the same rules as special abilities directly of the weapon. When a weapon with an enchantment has its details displayed, the display must include the additional details of the enchantment(s).
Note: you do not have to worry about both an enchantment and the weapon providing a special ability. The allowed combinations preclude that from occurring.
The following weapons and enchantments MUST be included in the game (more details to be provided in part 2 of the specification):
Fists
The standard weapon type all characters are created with. No enchantments allowed.
Boomerang
A weapon type common to both dungeon types. No special abilities.
Short Sword
A small weapon with no innate special abilities. Basic Dungeon only.
Battle Axe
A large weapon with no innate special abilities. Basic Dungeon only.
Wizard’s Staff
A magical weapon that can shoot ‘Fireballs’ (special ability). Magical Dungeon only.
Magic Wand
A magical weapon that can ‘Heal’ its user (special ability). Magical Dungeon only.
Flaming …
An enchantment that applies additional (fire) damage on attack.
Electrified …
An enchantment that applies additional (lightning) damage on attack.
… of Healing
An enchantment that allows the user to ‘Heal’ themselves (special ability).
… of Vampirism
An enchantment that heals the user the when damage is dealt from (normal) attacks. Does not trigger for special abilities (e.g., ‘Fireball’ or ‘Heal’).
Note: while it is possible to apply the Prototype Pattern to weapons in the same way as it is applied to creatures, we will not do so. The purpose of not using the Prototype Pattern for weapons is to force the use of inheritance and polymorphism. If designed correctly, each subclass should require minimal additional implementation.
3.9. Combat
From the perspective of the Design, the complete rules of the combat (which are effectively business rules) are not required to be known. However, the basic concepts need to be considered to define appropriate behaviour interfaces for the classes involved and determine the impact on the overall design. These interfaces can be refined later as you perform your implementation in part 2 of the assignment. In real applications it is important to be able to identify when a business rule impacts the design of the application and when it is an implementation detail. For example, the actual calculation of damage is an implementation detail, while the fact the calculation needs to be performed (and could potentially be performed in different ways, now or in the future) will impact the design itself.
Combat between a character and a creature will be performed in rounds. Each round the user will choose their action and then the creature will perform an attack or use the special ability of their weapon (if present). The user actions include: attack, use special ability, and return the way you came. If the last option is chosen the creature does not get to take its turn. The result of combat will update the character, creature, and/or game states, for which appropriate behaviour needs to be defined.
Each time an action is performed (whether it be the player or the creature) an appropriate message and the action’s description will be displayed to the user. However, only the MenuInterface class is to handle IO and, therefore, only the MenuInterface class can access std::cout. You will need to consider how the textual descriptions are provided to the MenuInterface for display, taking into account the effect an enchantment may have on the description. For example, if an enchantment deals additional damage over that of the underlying weapon, the description must include additional text indicating the extra damage dealt and its source.
If an attack succeeds—i.e., if the target character or creature does not dodge it—the target’s health is reduced by the damage amount as determined by the weapon’s damage properties and the bonus provided by the strength stat of the character or creature performing the attack. If a special ability is used that deals damage, the target’s health is reduced by the damage amount, if the ability has a healing effect then the health of weapon’s user is increased by the healing amount (as defined by the weapon or enchantment).
When the creature’s health reaches zero or below, a “win” message must be displayed to the user and the creature must be removed from the room. When the player’s health reaches zero or below, the user is returned to the main menu and the character is destroyed.

In this second part of the assignment you will need to implement the game in C++ based on the requirements in the remainder of this specification and the design you created in the first part of the assignment. Strict adherence to your initial design is not required, but it is good practice to follow a design when performing your implementation and to maintain it to be consistent with your code if you determine changes need to be made. Additionally, you should review your design against the rubric for the UML Class Diagram, which will be released after the due date of the UML Class Diagram component. The rubric will provide you with indicators of how your design can be improved to help you perform your implementation. Once the marking of the first part is complete, you may want to incorporate the feedback to further improve your design and implementation.
You will be provided with an initial Dungeon Crawler Qt Creator Project  containing skeletons of the original classes with some provided functions matching what was illustrated in the provided UML Class Diagram. Some of the underlying elements (such as the basic menu interface code) is provided to get you started; however, much of the provided code will be incomplete and needs to be modified to fit your class design. Parts of the provided code that must not be modified will be marked as such.
For this assignment the game has been simplified to a certain extent, e.g., dungeon creation is not completely procedural. A brief example of how the game will be played is provided below. For additional examples, please play through the Dungeon Crawler Reference Implementation  provided. The text descriptions of your implementation do not have to exactly match the reference implementation, but you may use it as a guide to see how the user interaction works and the game plays out. The remainder of the section describes the requirements of the game in more detail.
Note: the following conventions will be used when illustrating example output:
•a ‘>’ at the beginning of a line indicates the command line prompt
•bold orange text indicates input entered by the user
•user input surrounded by square brackets ‘[…]’ indicates a specific key press
•hitting [Enter] after other input is implied

2.1. Work Plan
Important: All classes and functionality that relate only to the Magical Dungeon type are optional, including the builder class, rooms, walls, weapons, etc. They are not required to complete this assignment. Some bonus marks are assigned if the Magical Dungeon type and its components are implemented. See section Dungeon Types for the table of classes and to which dungeon type they relate.
To complete the second part of this assignment, you will need to perform the following steps:
•Read the assignment specification carefully.
•Read the Implementation Rules and Hints Section again.
•Familiarise yourself with the provided Dungeon Crawler Qt Creator Project .
•Initialise a Git repository within the project folder.
•Implement character generation—refer to section Player Character
•Implement the basic dungeon classes, including their creation according to the standardised layout: walls and doors only, no creatures nor weapons—refer to section Dungeon (Rooms, Walls, Doors) for component structure and sections Dungeon Types and Standard Dungeon Layout for their construction.
•Implement dungeon navigation: at this point you should be able to play the game and transition between rooms and dungeon levels without combat—refer to sections Dungeon (Rooms, Walls, Doors) and General Gameplay
•Add weapons and weapon pickups focusing on those required for Basic Dungeon only—refer to sections Weapons & Enchantments and General Gameplay.
Suggestion: Start with the core weapon components then add enchantments later.
•Implement the CsvFile class according to the provided test cases—see sections Creatures and Loading Data From CSV.
•Implement creatures and populate the dungeon with creatures according to the standardised layout, no combat yet—refer to sections Creatures and Loading Data from CSV.
•Implement combat interactions: you should now be able to play the game with all general gameplay requirements/features complete (except the second dungeon type)—refer to section Combat.
•(Optional) Implement the second dungeon type: Magical Dungeon and all of its components—refer to section Dungeon (Rooms, Walls, Doors) ; also see Weapons & Enchantments and Creatures, if you have not yet implemented the dungeon type specific elements of those sections.
•Generate Doxygen-based HTML documentation.
Important: As you implement the functionality you should tick, highlight, or otherwise mark the requirements that you have completed. This will help you keep track of your progress and ensure you have addressed all of the requirements in your submission. If you are unsure of a requirement, ask and/or use the reference implementation for guidance.
After completing the implementation (or even earlier) be sure to generate your HTML documentation from your Doxygen comments included in your project files. You will then need to gather your entire project, including the git repository, and submit it to LearnOnline. See section Submission Details for the full requirements of submission.
Note: The above sequence of tasks is a suggestion that will lead you through a logical progression of incremental functionality until you have a completed game. It is highly recommended that you follow the suggestion to maximise your marks, as marking is allocated based on functional completeness. For example, completing all of the structural elements for all classes (i.e., data members and constructors) without any game functionality will receive less marks than having some game functionality that only incorporates the structural implementation necessary to achieve that functionality.

2. Task Description
2.2. General Gameplay: Overview
The gameplay state will be controlled by a Game object. There can only ever be one game in play at one time, i.e., it is a Singleton. The user interaction will be performed through the MenuInterface class. Many of the general requirements describe the functionality in terms of the user interaction, you will need to implement both the menu interactions and the actions that they trigger. Be sure to keep the responsibilities in the correct location, i.e., gameplay state is managed by Game and IO is handled by MenuInterface. Most of the interactions will result in delegating to the Game object. Some constraints of the menu interface are detailed in the Menu section.
When the term ‘game’ is used in lower-case, we are referring generically to the application, while Game is explicitly referring to the class.
The game allows the user to create a player character (Character) and to explore a dungeon of the user’s choice, room-by-room. Along the way they may encounter creatures that they will have to defeat before they can continue exploring (unless they can find a way around them). They will also come across weapons to loot that will help them defeat the creatures they encounter. The last room in the dungeon typically has a more powerful monster (a ‘boss’ monster) that needs to be defeated for the exit to reveal itself.
There are two types of dungeon that the user can explore: a “basic” dungeon (BasicDungeon), and a “magical” dungeon (MagicalDungeon). Each dungeon type will be populated with their own sets of room types (Room and its class hierarchy), creature types (Creature and its class hierarchy), and weapon types (Weapon and its class hierarchy).  Each of these elements will require descriptions that are displayed to the user as they traverse the dungeon and encounter them.
2.3. General Gameplay: Starting a Game
When the game is first started, a welcome message will be displayed and the user will be given the option to play the game or quit from the main menu.
Note: You must specify the values of AUTHOR and TITLE at the top of main.cpp to give your game a name and say by whom it has been developed. You do not need to modify anything else in main.cpp.
If the user chooses to quit, the game will prompt the user to confirm that they want to quit:
•If the user selects ‘yes’, the game will end
•If the user selects ‘no’, the game will return to the main menu
If the user chooses to play the game (from the main menu), the game will prompt the user to create character. Refer to section Player Character for details of character creation.
After the user has created their character, the game will prompt the user for the type of dungeon they would like to explore. There must be three options: a “basic” dungeon, and a “magical” dungeon, or “go back”. Refer to section Dungeon (Rooms, Walls, and Doors) for details of the types of dungeon and their construction.
•If the user chooses “basic”, the game must create a BasicDungeon object according to the standardised layout
•If the user chooses “magical”, the game must create a BasicDungeon object according to the standardised layout
•If the user chooses “go back”, the game will return to the main menu.
If a dungeon is created, the game must place the character in the first room, display that room’s description, and prompt the user for the next action.
2.4. General Gamplay: Playing the Game
To play the game, the user must be able to take one of several actions in each ‘turn’. The exact options that are available depends on the configuration of the room (i.e., which sides have doors), whether a creature and/or item is present, and the weapon the character currently possesses. The user must be able to select from the following actions as appropriate:
•Move the character in a given direction: North, South, East, or West
•Move the character “back” to the previous room (whether this is North, South, East, or West depends on the door the user “came through”)
•Pick up a weapon
•Compare the weapon in the room with that currently held by the character
•Attack the creature
•Use the weapon’s special ability
•Return to the main menu
1. If the user chooses to move North, South, East, or West, and there is a traversable door in that direction: the current room will be updated to the room that was selected, the new room’s description will be displayed, and the user prompted for the next action. If there is no door in the selected direction, nothing happens and a message may be displayed to the user.
2. If the user chooses to return to the previous room, the current room will be updated to the previous room, the room’s description will be displayed, and the user prompted for the next action.
3. If the user chooses to pick up a weapon, the game will prompt the user to confirm as it will replace their existing weapon. If the user says ‘no’, nothing happens; if the user says ‘yes’, the character’s current weapon is removed and replaced with the item from the room: the room will no longer have an item.
4. If the user chooses to compare weapons, the description and stats (minimum and maximum damage) of both weapons will be displayed. It must be clear which weapon is currently owned by the character and which is present in the room.
5. If the user chooses to attack the creature the rules for combat will be applied. Please refer to the Combat section for details.
6. If the user chooses to use the weapon’s special ability, the ability’s effect will be applied. Refer to section Weapons & Enchantments for details of each special ability.
7. If the user chooses to return to the main menu, the game will prompt the user for confirmation warning that the action will lose all progress for the character.
•If the user says ‘no’, the user will be prompted to take an action.
•If the user says ‘yes’, the number of dungeon levels successfully completed must be displayed followed by the main menu, and the current dungeon and character must be made unavailable (i.e., choosing to play the game again will behave as describe in ‘Starting a Game’ above).
Restrictions on Actions
There are several restrictions on what actions can be taken in what context, summarised in the table below. You can handle these restrictions by hiding the actions from the menu or by displaying an appropriate ‘failure’ message if the user attempts to perform an action that is not allowed.
Note that the disabling condition overrides any enabling conditions. E.g., if a weapon and creature is present in a room, the weapon actions are disabled.

2.5. General Gameplay: Ending a Level and Other Considerations
Once the user reaches the final room of the dungeon level (i.e., the room with the exit door), the user will be able to finish the level by selecting the direction (NORTH, SOUTH, EAST, or WEST) at which the exit door is positioned in the room.
If the user selects the direction of the exit door, the game will update the number of levels the character has successfully completed and return to the main menu. The character must remain available to play additional dungeon levels.
From the main menu, if a valid character exists and the user chooses to play the game (again), the game must create a new dungeon level (which may be constructed using the standardised layout) of the previously selected type, position the existing character in the first room, display the room’s description, and prompt the user for the next action.
If the character is in the first room of the dungeon level (i.e., the room containing the entrance door) and the user chooses the direction of the entrance door, the game will return to the main menu as if the user had selected the ‘return to main menu’ action.
During the game, if the character’s current health stat drops to zero (or below), the game will display a ‘game over’ message, the number of dungeon levels that were successfully completed, and return to the main menu. This will make the current character and dungeon level unavailable as if the user has selected the ‘return to main menu’ action.
Other Considerations
At any time that a valid character exists, the user must be able to select an option to view the character’s details (stats, weapon, etc.). If the user chooses to view the character details, the game will display the character stats as described in section Player Character: Details Display, then prompt for another action from the same menu as prior to viewing the character details. For example, if the user chooses to view the character details from the main menu, the main menu options will be redisplayed afterwards.
All user inputs must be validated. If an invalid input is given, a warning must be displayed to the user and menu options redisplayed.
Note that the MenuInterface class already provides some helper functions to assist with input validation.
All classes must have appropriate constructors and destructors, even if they are only the default implementations. Take particular care of destructors when dealing with polymorphic classes, i.e., those classes with virtual functions, and those classes that use pointers (particularly bare pointers).
All objects that can be described must overload the output stream operator <<. This will facilitate the display of objects by the MenuInterface class.2.6. MenuUser interaction with the game will be performed through the MenuInterface class. This class has the sole responsibility of commandline IO in the application, i.e., it handles the display of the menu options and processes the inputs from the user. The basic structure of the MenuInterface class and its interface will be provided for you; you will need to implement the transitions between menus and the interactions with the Game class, which is responsible for maintaining and updating game state.While the descriptions of menu items do not have to exactly match the samples provided, the keys typed to select a particular action must conform to the table below for consistency across implementations. Note that it should not matter if the typed character is uppercase or lowercase. If in doubt, refer to the reference implementation of follow its example.2.7. Player CharacterThe player character is represented by the Character class. This class will maintain the state regarding the player’s character as well as define behaviours appropriate to the character (i.e., update the game state as appropriate based on the character’s actions).A character has a name (provided by the player), properties that may impact the gameplay and the character’s actions, and a weapon. These are collectively referred to as the player’s “stats”. When the player chooses the option, the character’s stats must be displayed.There are three basic properties that are defined at character creation (based on choices made by the user) and are not changed during gameplay, including:•Strength: allowable values 1-6, each value > 1 contributes to the damage of the character
•Dexterity: allowable values 1-6, each value > 1 contributes to the dodge chance of the character
•Wisdom: allowable values 1-6, each value > 1 contributes to the effects of magical items
There are also three dynamic properties that may change during gameplay or based on the above basic properties:
•Health points: starts at 50 and is reduced by taking damage from creatures (whole numbers only). Once it reaches zero (or less) the game is over. Various items and special abilities may increase the amount of health, but not above the original value.
•Damage: calculated from the current weapon and Strength. The strength bonus is equal to 2×(Strength−1)2×(Strength−1). That is, each point of Strength above 1 adds twice as much to the damage.
•Dodge chance: percentage, used to determine whether the character will get hit by a creature when it attacks. 100% means the character will dodge every attack. Calculated as: 100÷5×(Dexterity−1)100÷5×(Dexterity−1)
That is, each Dexterity point above 1 adds 20% to the dodge chance.
When the game is first started the user must create their character following the character creation process described in the next section.
2.8. Player Character: Character Creation
The user must make a few choices to create their character. This section describes the character creation process.
When the user chooses and option which requires a new character to be created, the game will prompt the user to enter the character’s name.
After the user as entered a name, the game will prompt the user to allocate points to the three basic properties (Strength, Dexterity, and Wisdom) according to the following rules:
•The user will start with 6 available points to allocate
•The user will select the number of points to allocate to each property in turn: 1) Strength, 2) Dexterity, 3) Wisdom
•The selected number of points will be added to the base value of 1; the resulting value will be assigned to the matching property of the character:
•The selected number of points must not exceed the current number of available points
•The selected number of points must not exceed 5 to prevent the total points for the stat from exceeding 6.
•The selected number of points must not be a negative number.
•The select number of points may be zero, i.e., no points will be added to the stat’s base value of 1
•After the user selects a valid number of points, the selected number will be removed from the number of available points
•The user may leave some points unallocated
•The game must not allow a base property to exceed the value 6
After point allocation is complete, the game must display the character description and stats to the user. This is the same description that would be displayed if the user chose to display their character details from the menu.
When a character is created it must start with the ‘Fists’ weapon type (refer to section Weapons & Enchantments).
It is important that you do not stumble at the first hurdle. If you have difficulty implementing the character creation process, hard-code the instantiation of a Character object and continue with another step in the assignment.

2.9. Player Character: Details Display
When displaying the character details, the following information must be included:
•The character’s name
•Strength
•Dexterity
•Wisdom
•Health: current and maximum (original value)
•Damage, calculated as described in the Player Character section
•Dodge Chance, calculated as described in the Player Character section
•The character’s weapon, short description only (refer to section Weapons & Enchantments)
For example, the character details may appear as follows (the exact layout is not a requirement):

2.10. Dungeon (Rooms, Walls, Doors)
A dungeon level consists of a connected set of rooms and are to be represented by the Dungeon class. Each room of a dungeon (represented by the Room class) must be identifiable by a number (integer) so that they can be retrieved from the dungeon object using the numeric identifier. Each room has 4 directions: North, South, East, and West. In each of these directions, there may be a wall (the Wall class) or a door (the Door class). Doors are connected to adjacent rooms via a door in the opposing direction. For example, if a room has a door to the north, the northern room has another door to the south and these doors are connected to one another.
Door objects must be connected to one another using bare pointers in the C++ implementation.
Most doors are connected to each other to allow movement between rooms in both directions. There are two exceptions: the entrance to the dungeon level, and the exit. Your design/implementation will need to consider how the entrance and exit are represented. When the user chooses to go through the dungeon entrance or exit they will be returned to the main menu as describe in section General Gameplay: Ending a Level.
Each room may contain a creature (Creature), a weapon (Weapon), or both. If both are present in the room, the description should not indicate the presence of the weapon until after the user defeats the creature, “revealing” the weapon.
When the user enters a room, a description of that room must be provided to the user. The description includes what the room “looks like” (this is up to you, or you can use the text of the examples) and what the character “sees”, that is, where the doors are located, whether a creature or item is present. Descriptions of walls may be included. An example description for a RockChamber with an entrance to the North, and OpenDoorways to the South and East may look like the following:
Looking around you see… a dark and empty chamber
To the NORTH you see the entrance by which you came in.
To the SOUTH you see you see an opening to another chamber
To the EAST you see you see an opening to another chamber
When a dungeon level is being created, various elements must be selected randomly, including: the type of room, the type of creature (if present), and the type of weapon (including enchantments, if present). We will use the Builder Pattern to control the dungeon creation.
Note: for simplicity, the size of the dungeon (i.e., the number of rooms) and the connections between rooms will not be randomly generated for this assignment. Moreover, it is not requiredto do any complex registration of types: a simple switch statement will be acceptable, for example.
2.11. Dungeon Types
The game will include two dungeon types: a basic dungeon (BasicDungeon class), and a magical dungeon (MagicalDungeon class). Each dungeon type can contain different types of rooms, walls, doors, creatures, and/or weapons. (Refer to sections Creatures and Weapons & Enchantments for details of the creatures and items, respectively.)
Each dungeon type will have its own concrete builder class (BasicDungeonBuiler and MagicalDungeonBuilder, respectively) that manages the creation of the dungeon object and each of its components. The Game will need to instruct the builder on what type of component to build in a general sense (i.e., dungeon, room, door, creature, or weapon), along with any information needed to put the component in the correct location (e.g., weapon in a room) or connect them together (e.g., the rooms to be connected by doors). The builder will then use the provided information to instantiate an appropriate object (according to the allowable combinations below), insert the object where it belongs, and connect the objects as required.
Note: For components that have a choice (e.g., room type), the builder can simply choose one at random. For weapons, you could use a weighting of 50% for a basic weapon, 30% for a weapon with 1 enchantment, and 20% for a weapon with 2 enchantments.
The supported combinations of dungeon elements are listed in the following table.
Note: the constraints below do not have to be encoded into the design as hard restrictions. They can be knowledge that the builders have about what components are allowed to be combined, which would be represented simply as dependencies. It is important not to over-constrain the design at this point. Imagine, for example, if a new dungeon type is created that mixes Rock Chambers and Enchanted Library room-types, you do not want to need to modify all the strict associations that enforce the original combinations. Make appropriate use of abstractions and interfaces.

2.12. Standard Dungeon Layout
Dungeon levels would normally be randomly generated; however, to simplify the assignment and make it easier to test and mark, you are not required to implement randomly generated dungeon levels. However, your design and implementation should allow such a change in the future. Some elements of the dungeon are still randomised, for example, the type of each room, the type of creature (if present), and the type of item (if present).
The structure of the (first) dungeon level must conform to the standard structure defined below. There is no constraint on the structure of dungeon levels after the first.

The layout diagram uses the following symbols:
•Large green rectangles represent rooms with the numbers indicating their ID
•Small blue bars joining rooms represent connected pairs of doors
•Entrance and Exit are labelled blue bars and indicated by a directional arrow
•Orange smiley faces represent creature locations
•Yellow suns represent weapon locations
2.13. Creatures
Dungeons, specifically rooms, can be inhabited by numerous foul creatures. There can be at most one creature per room and a creature never leaves the room in which it is created. All creatures must derive from the class Creature and conform to the Prototype Pattern, as the creature types will be loaded from a data source at runtime. When the user encounters a creature in a room they must defeat it in combat before moving on or picking up an item (if present). Alternatively they can return the way they came and attempt to find a way around it. Each type of creature has different stats, but otherwise has the same types of stats as the player character. These stats are:
•Strength
•Dexterity
•Wisdom
•Health
•Damage
•Dodge chance
The bonuses provided by the basic stats are calculated in the same manner as that of the player character and then halved. If a creature is a ‘boss’ (i.e., it is in the room with the exit door) they receive the full bonus the same as the player character.
In contrast to the player character, creatures also have a long description which is displayed when the creature is encountered in a room. For example, encountering a ‘Goblin’ in a room may display as follows:
Blocking your path you see a Goblin: a small nimble creature who favours the short sword
This follows the pattern:
Blocking your path you see a :
All creatures will attack using a weapon in the same manner as the player character. If the weapon has a special ability, the creature may choose to use the weapon’s special ability rather than a standard attack. Refer to the section on Weapons & Enchantments for details.
The specific types of creature, that is, the creature prototypes (since we are using the prototype pattern) will be defined in a data file and loaded by the application at runtime. Details of the file format are given in the next section.
When instantiating creature prototypes from the data file, defensive programming should be used to ensure you are not loading invalid data that may corrupt the program. Therefore, you must ensure the following:
•A name is provided: if not you should discard the creature type;
•A description is provided: if not you could just add ‘ ‘ or similar rather than discarding the creature type entirely;
•Maximum Health stat is within the range 1 – 100 (inclusive);
•Strength stat is within the range 1 – 6 (inclusive);
•Dexterity stat is within the range 1 – 6 (inclusive);
•Wisdom stat is within the range 1 – 6 (inclusive);
•A Weapon Type is defined: if not you can discard the creature type or give it a default weapon of some type, e.g. Fists;
•A Dungeon Type is defined: if not you can discard the creature type or make it applicable to all dungeon types;
You cannot always trust that your data files will not be modified by a malicious user (or just trying to cheat), so you must always be careful when loading data from file.

2.14. Loading Creatures from CSV
In this assignment, the creature types will be loaded from a CSV (comma separated values) file. You are required to implement a simple CSV parser in the CsvFile class. The interface for the CsvFile class is provided, along with a set of Unit Tests, to which you must implement a conforming solution. Refer to the documentation in the CsvFile and Testing classes (csvfile.h and testing.h, respectively).
The CSV file used by the application will be generated by the class. There is a ‘database’ module on LearnOnline in which you can enter the details of a Creature type (if each student enters 1 creature type there will be 160+ types in the game). You will then be able to download the CSV file from LearnOnline to be used by the application at runtime.
Go to the Creature Types Database to contribute your own creature to the growing collection or export the CSV file.
The Qt Creator project is configured with an initial CSV file ‘creature_types.csv’ that will be copied into the output directory when the project is built. When reading this file into the game, you may hard-code the filename directly. If you download an updated CSV file from the Creatures Types database, simply overwrite the existing file in your project folder with the new one (it should be version controlled so you should always be able to revert if desired).
For the design, you will need to identify the best place for the CsvFile class to be used, its associations, and dependencies. Remember the principles of loose coupling, minimising dependencies, and separation of concerns. It is suggested you load the data file as close as possible to where you need to process its contents to instantiate the creature prototype instances.
For the implementation, you can refer to the IETF RFC 4180, which distils the format of the CSV file down to about 7 common rules. In this assignment, we make a slight modification to number 6: you do not need to worry about real linebreaks occurring within a quoted field. Instead, the text sequence “
” (i.e., backslash followed by ‘n’ as two characters and not an escape sequence meaning a single newline character) may appear within a quoted field and you must convert it into a proper linebreak character. This allows you to simply process each line of text as a row of data, instead of worrying about a row of data spanning multiple lines.
There are several ways for you to implement the parsing of the CSV file format including delimiter based or character-by-character parsing. You may use functions such as std::getline, the overloaded input operator >> of the input stream classes, or any other method(s) you think are necessary. However, you must use C++ streams and not old-style C IO functions.
Be aware of any manipulators that may impact your parsing, e.g., the default for streams is to skip whitespace on input, so you may need to configure your stream appropriately using the noskipws manipulator.
Remember the different types of streams such as file streams (which give you access to file content) and string streams (which you can use as temporary buffers that you manipulate internally without affecting the any other stream).
Refer to the lecture slides, and online reference material (e.g., cppreference.com) for information on streams and manipulators.
The provided tests are also a good place to determine what the supported format is and how to use the CsvFile class according to its interface. This is a common thing, particularly in modern open source projects, where the Unit Tests are considered the documentation on how to use a class.
It is important that you do not get stuck trying to perfectly parse the CSV files. If you have difficulty implementing the parsing you have a couple of options depending on where you get stuck.
If you get stuck once your implementation reaches the more difficult aspect of handling quoted fields, then run your application using a modified data file that ensures no quoted fields exist. An easy solution for that is to take the initial sample file and remove the ‘Evil Wizard’ creature type as that is the only row that requires quoted fields (due to a comma in its description field).
If you get stuck trying to parse the file format altogether, revert to hard-coding a creature prototype instance and use that to instantiate new creatures within the dungeon and continue to a step you think you can achieve.

2.15. Weapons & Enchantments
The game allows characters and creatures to carry a weapon (only 1 weapon, and always 1 weapon), which they use in combat or at any time to affect their environment. In addition, weapons can be enchanted to give them extra bonuses or special effects for the character to use. Special effects may have an arbitrary effect on the game state. Creatures that have weapons can attack with them or use their special ability (if they have one). The weapon enchantments will be handled using the Decorator Pattern, which allows additional behaviour of the enchantment to be dynamically added to the basic behaviour of the underlying weapon.
Weapons (represented by the Weapon class) have a name, a short description (used on the character details display), a long description (used on the weapon specific display), and a damage stat (minimum and maximum value). Their primary use is for attacking a creature (or the character if owned by a creature) during combat. Some weapons may also have a special ability that the character (or creature) may use during combat, while some special abilities may also be usable outside of combat (character only).
When displaying the details of a weapon (either when viewing the character details or when comparing two weapons) the display must include:
•name
•long description
•damage range (min. and max. values)
•description of the special ability, if present
For example, the details of the ‘Fists’ weapon may appear as follows (the exact formatting is not mandatory):
“Fists”
Min. Damage:4
Max. Damage:4
Fists are the weapon of choice for someone who has nothing else
Weapons can be enchanted (represented by the Enchantment class), which add bonuses and/or special abilities to the weapon on which they are placed. Each weapon may have up to two enchantments. Enchantments change the reported name of the item and can be either ‘prefix’ enchantments—add a term (or terms) to the beginning of the name—or ‘suffix’ enchantments—add a term or terms to the end of the name. Only one of each type may enchant a weapon at the same time, i.e., if there are two enchantments on a weapon then one will be a prefix and one will be a suffix. For example, the ‘Flaming short sword of healing’ is a short sword weapon with a prefix enchantment named ‘flaming’ and a suffix enchantment named ‘of healing’.
Enchantments on a weapon may change the standard damage of the weapon when it is used to attack, or it may add a special ability to the weapon. Special abilities added by an enchantment follow the same rules as special abilities directly of the weapon. When a weapon with an enchantment has its details displayed, the display must include the additional details of the enchantment(s).
Note: you do not have to worry about both an enchantment and the weapon providing a special ability. The allowed combinations preclude that from occurring.
The following section will provide the details of each weapon and enchantment type that must appear in the game.
2.16. Weapon & Enchantments: Properties
The following weapons and enchantments MUST be included in the game:
Fists
The standard weapon type all characters are created with. Should never be constructed with enchantments.
Property
Value
Short Description
you look down at your fists and shrug, “these will do”
Long Description
Fists are the weapon of choice for someone who has nothing else.
Damage (Min. – Max.)
4 – 4
Special Ability
None
Boomerang
A weapon type common to both dungeon types. No special abilities.
Property
Value
Short Description
an effective ranged weapon that returns to your hand when used
Long Description
You scratch your head struggling to understand how this weapon can return even *after* it hits its target?
Damage (Min. – Max.)
6 – 8
Special Ability
None
Short Sword
A small weapon with no innate special abilities. Basic Dungeon only.
Property
Value
Short Description
a sharp and pointy instrument, good for stabbing
Long Description
Not very large, but with a sharp point. Short swords are designed more for stabbing than for slicing. The hilt is surprisingly ornate for such an inconspicuous weapon.
Damage (Min. – Max.)
5 – 10
Special Ability
None
Battle Axe
A large weapon with no innate special abilities. Basic Dungeon only.
Property
Value
Short Description
heavy, but effective
Long Description
A large and heavy weapon. The battle axe must be wielded with two hands but even then you are almost as likely to cut off your own limbs as those of an enemy.
Damage (Min. – Max.)
10 – 15
Special Ability
None
Wizard’s Staff
A magical weapon that can shoot ‘Fireballs’ (special ability). Magical Dungeon only.
Property
Value
Short Description
it would break if you leant on it, but it shoots fireballs so that’s something
Long Description
Not a very sturdy staff, but the swirl of magical fire around its top belies a magical secret: it shoots fireballs!
Damage (Min. – Max.)
1 – 2
Special Ability
Fireball: deals 10 – 20 damage to the opponent (plus the bonus from the creature or character’s Wisdom stat). Always hits, regardless of dodge chance.
Magic Wand
A magical weapon that can ‘Heal’ its user (special ability). Magical Dungeon only.
Property
Value
Short Description
birch with angel’s feather core and rubberised leather grip
Long Description
Apparently, there is no other wand like this one in existence. The angel’s feather at its core allows the bearer to perform unbelievable feats of healing.
Damage (Min. – Max.)
5 – 10
Special Ability
Healing: returns character to full health.
Flaming …
An enchantment that applies additional (fire) damage on attack.
Property
Value
Prefix/Suffix
prefix
Long Description
Holding it feels warm to the touch and sparks leap out when it makes contact with something.
Effect
Deals an extra 5 damage when the weapon is used to attack (if the attack hits).
Can appear on
Boomerang, Short Sword, Battle Axe, Wizard’s Staff, and Magic Wand
Electrified …
An enchantment that applies additional (lightning) damage on attack.
Property
Value
Prefix/Suffix
prefix
Long Description
The air crackles around it making the hairs on your arm stand on end.
Effect
Deals an extra 5 damage when the weapon is used to attack (if the attack hits).
Can appear on
Boomerang, Short Sword, Battle Axe, Wizard’s Staff, and Magic Wand
… of Healing
An enchantment that allows the user to ‘Heal’ themselves (special ability).
Property
Value
Prefix/Suffix
Suffix
Long Description
Just being near it makes you feel all warm and fuzzy inside.
Effect
Special ability: heals the owner for 5 health points.
Can appear on
Boomerang, Short Sword, Battle Axe
… of Vampirism
An enchantment that heals the user the when damage is dealt from (normal) attacks. Does not trigger for special abilities (e.g., ‘Fireball’ or ‘Heal’).
Property
Value
Prefix/Suffix
Suffix
Long Description
Occasionally drops of blood appear on the surface but you are unsure from whence they came.
Effect
Half of the damage dealt during an attack is given back to the owner as an increase in health points.
Can appear on
Boomerang, Short Sword, Battle Axe, Wizard’s Staff, and Magic Wand

Note: while it is possible to apply the Prototype Pattern to weapons in the same way as it is applied to creatures, we will not do so. The purpose of doing it without the Prototype Pattern for weapons is to force the use of inheritance and polymorphism. If designed correctly, each subclass should require minimal additional implementation.
2.17. Combat
Combat between a character and a creature will be performed in rounds. Each round the user will choose their action and then the creature will perform an attack or use the special ability of their weapon (if present). The user actions include:
•attack: will perform an attack using the owner’s (character or creature) weapon dealing damage if the opponent does not dodge the attack;
•use special ability (if available): weapon’s special ability effect will be applied, which could affect the owner (character or creature) or opponent (character or creature) depending on the ability; and
•return the way you came: will leave the room through the door by which the character entered ending up in the room from which the character came (no other door can be used by a character while a creature is in the room).
If options 1 or 2 are chosen, the creature will take its turn after the effect of the user’s action is applied. If option 3 is chosen, the creature does not get to take its turn and the creature must not follow through the door, i.e., it stays in the room. The result of combat will update the character, creature, and/or game states, for which appropriate behaviour needs to be defined.
Each time an action is performed (whether it be the player or the creature) an appropriate message and the action’s description will be displayed to the user. However, only the MenuInterface class is to handle IO and, therefore, only the MenuInterface class can access std::cout. You will need to consider how the textual descriptions are provided to the MenuInterface for display, taking into account the effect an enchantment may have on the description. For example, if an enchantment deals additional damage over that of the underlying weapon, the description must include additional text indicating the extra damage dealt and its source.
There are any number of ways in which this can be implemented. Some examples include:
•using return values (may have problems if there is more than one value that needs to be returned, but could use a std::tuple in that case)
•passing in an object of an existing type that can collect the results, e.g., a std::vector
•using one or more ‘out’ parameters, i.e., reference parameters that are modified within the function so that the caller can access the value once the caller completes (similar to the previous but with different implications)
•creating a new helper class to track the action events and results and pass it to the behaviour or return it from the behaviour to build the final result
If an attack succeeds—i.e., if the target character or creature does not dodge it—the target’s health is reduced by the damage amount as determined by the weapon’s damage properties and the bonus provided by the Strength stat of the character or creature performing the attack. Since weapons have a damage range, the damage incurred by an attack must be calculated by first generating a random number between the minimum and maximum damage values (inclusive) of the weapon.
Whether a creature or character dodges an attack is determined randomly based on their percentage Dodge Chance stat. This can be determined by representing the Dodge Chance as a real number (float or double) and by generating a random real number between 0 and 1: if the randomly generated number is less than the Dodge Chance, the character or creature dodges the attack. For example, if a character has a 60% dodge chance, 0.6 as double, and the random number 0.4 were generated then the character would dodge the attack; if 0.63 were generated, the character would take damage.
If a special ability is used that deals damage, the target’s health is reduced by the damage amount as determined by the special ability’s definition and the bonus provided by the Wisdom stat of the character or creature using the ability. If the item specifies a damage range for the special ability, the actual damage value of the ability will be determined by obtaining a random value within the range (inclusive).
If the ability has a healing effect then the health of weapon’s user (character or creature) is increased by the healing amount (as defined by the weapon or enchantment) and the bonus provided by the Wisdom stat of the character or creature using the ability. If the item specifies a healing range for the special ability, the actual heal amount of the ability will be determined by obtaining a random value within the range (inclusive).
When the creature’s health reaches zero or below, a “win” message must be displayed to the user and the creature must be removed from the room.
When the player’s health reaches zero or below, the user is returned to the main menu and the character is destroyed, as per the General Gameplay rules.

2.18. Documentation
Your code must be documented appropriately using Doxygen comments. Read pages 48-53 of the course textbook for guidelines on good commenting, as well as the style guide. Document as you go, not all at the end. Document sparingly: most of the marks are for implementation not comments.
Comment blocks must be used in your header file to document your classes and class members.
Private members should also be documented when it is not obvious for what they are used—but first check if the code can be improved as clean code is better than comments.
Use comments sparingly in source files, document blocks of code (switch statements, if else groups, loops, etc.) rather than individual statements: do not comment individual statements, unless the outcome of the statement is not obvious.
Optionally, you can add comments to ‘main.cpp’ to document the ‘main page’ of the generated HTML.
2.20. Version Control
You must use version control to keep track of your progress during implementation, using git. You should perform regular commits as you implement features and fix errors. Your commit comments should reflect the context of the changes that were made in each commit—a fellow developer can always diff the contents to see exactly what changed but that does not provide the context. You should try to ensure each commit comment contains a short subject line.
Your submission will comprise your entire version control repository, so it should be specific to the assignment. For example, if you use git, you must create the git repository in the root directory for your assignment. Do not commit your assignment to a repository created in a parent folder or any other location. Your repository must contain all source files required to compile and run your program (including a Doxygen config file) but must not include any generated or extraneous files.
You can ensure a clean folder for submission by cloning your assignment and zipping the new folder. This will not modify your working directory while providing all committed files and their version history.
You do not have to use an online version control repository such as GitHub. If you do use an online repository, ensure that the assignment is private, i.e., cannot be seen by people other than yourself.
3. Implementation Rules and Hints
! You must consider when and where it is appropriate to use smart pointers vs. bare pointers and the effect this choice may have on constructors, destructors, etc. In most cases the choice is up to you with the exception of the connection between two doors, doors must be connected via bare pointers.
! Be sure to check for null pointers (nullptr) before attempting to use an object through a pointer and reset pointers to null where appropriate.
! Smart Pointers – the Dungeon class uses the smart pointer std::shared_ptr to store and retrieve the rooms (among other things). You must use the std::make_shared () template function to create the rooms to pass to the function Dungeon::addRoom. The below code snippet is an example of adding a room to a dungeon:
Dungeon d = Dungeon{};
d.addRoom(std::make_shared (/* constructor arguments go here */));
! The Dungeon and Room classes may not be the only occurrence of smart pointers in your implementation.
! The provided project uses namespaces. Be careful to ensure you are accessing classes with appropriate scopes. Remember to use the scope operator :: , e.g., core::dungeon::BasicDungeon .
! The game will need to keep track of (at least) the current room, the character, and the previous room/door.
! Casts – in your code, casts should only need to be performed between a base class pointer and a derived class. When doing so, a dynamic cast should be performed (using dynamic_pointer_cast ). For example, to cast an Weapon shared pointer to a Enchantment pointer you would use the following code snippet:
std::shared_ptr weapon = …; // Wherever the value comes from
std::shared_ptr enchantment = std::dynamic_pointer_cast (weapon);
! Remember, if the cast is successful, the pointer will be non-nullptr.
! It is recommended that you test individual components as you go, rather than trying to test the whole application through the menu-driven interface. Writing code to test specific elements will speed up development as you will not need to constantly enter data through the menu interface.
! You may change the descriptions of items, creatures, actions, etc., if you like.
! Type defines – if you know what you are doing, you may define type aliases for the shared pointer types for use in the MenuInterface and your classes. Alternatively use appropriate using declarations.

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] 代写 R C++ C game GUI html Spark UML parallel compiler database graph software Go 2. Design Patterns
30 $