实现一个 RPG 游戏,操控战士。
![RPG](https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Screenshot-
Falcons-Eye.png/220px-Screenshot-Falcons-Eye.png)
Introduction
For this project you will simulate a game where different characters interact
on a 2-dimensional grid and where each cell in the grid can contain zero, one
or multiple pieces. A game playout continues for n iterations or until a
victor emerges. During each of the iterations all cells of the grid are
updated synchronously according to the rules stipulated in Section 3. There
are six main classes of pieces: Warrior, Healer, Potion, Weapon, Water, and
Magic Crystal pieces. The details relating to each piece’s function and
characteristics is defined in Section 2. As the game progresses, the warriors
battle one another and interact with other pieces on the grid; your program
should print visualisation information after each iteration in the game and
produce warrior statistics once the game has terminated.
The piece classes
Warriors
The warrior pieces are the main characters of the game and begin the playout
with an allocation of 6 different attributes; as the game progresses these
warriors are matched against one another in battle until a victor emerges.
- Age - This is in terms of iterations, each time another iteration of the game playout occurs this age increases by 1.
- Health - This is a percentage measure representing how well the player is doing in the game.
- Movements - Each warrior has a list of movements which they perform, one per iteration.
- Offense Power - This value represents the amount of heath they remove from another warrior in battle.
- defence Strength - This is a measure of the effectiveness of a warrior’s defensive skills.
- Weapon Inventory - Warriors have an inventory size which allows them to hold a maximum of w weapons at any one time; each weapon possessed by the warrior increases the player’s offensive power during battle.
There are four types of warriors: Stone Warriors, Flame Warriors, Water
Warriors and Air Warriors. Each type of warrior has a unique special ability
as defined in Section 3.9.
Healers
Healer pieces are those that bring order and peace to the world around them,
the game has two defined types of healer pieces namely the Restorer and the
Peacemaker, their roles are defined in Section 3.10.
Other Pieces
Potion
Drinking an unknown potion can be a gamble for a warrior, unknowing what the
affect of the potion might be. The game has three types of potions, each with
their own affect on a warrior.
- Trance Causing Mixture - This type of potion causes the warrior who drank it to become confused and perform the inverted movements to those which they otherwise would have performed. This trance lasts up until they drink a Trance Healing Mixture.
- Trance Healing Mixture - This potion has no affect on warriors that have not been effected by the Trance Causing Mixture; for those warriors in a trance it heals them of their confusion and they again perform movements as originally specified.
- Invisibility Mixture - This type of potion causes the warrior to become invisible to other warrior and healer pieces for i iterations of the game. When invisible, the warriors still perform their movements as normal but they do not enter battle with any other warriors and so remain unharmed. They do however make themselves known to Restorer pieces when in contact with them so that they can be healed and increase their health attribute.
Weapon
Weapon objects can be positioned in a cell on the grid or be held in the
inventory of a warrior. If held in the inventory of a warrior, the weapon adds
offense power to the warrior according to the weapon specific value specified
in the game setup file; each weapon is configured at the beginning of the game
with an offense power benefit.
Water
Water flows around the grid and benefits each warrior according to the rules
in Section 3.12.
Magic Crystal
A maximum of 1 magic crystal may be present in the game and when activated,
the crystal causes all warriors except for those four that activated the
crystal to be removed from the game; see Section 3.13 for the rules relating
to this piece.
The Rules
Neighbourhood of a piece
The neighbourhood of a piece is defined as the 8 closest cells to the piece.
In Figures 1,2 and 3 the blue cell represents the current piece and the green
cells represent the neighbourhood of that piece. In a situation in which the
current cell is on the edge of the grid, the neighbourhood wraps around to the
opposite edge of the grid.
Game Playout
Each game playout is made up of n iterations (n is defined in the program
setup files) and for each iteration, every cell in the grid is updated
according to its neighbourhood. Each cell is updated synchronously, relying
only on data from that iteration and not any updates made during the
transition to the next iteration.
Movement/Overlapping
Each warrior is able to move around the grid according to their individual-
specific sequence of moves, executed one position per iteration. Since each
list of moves is of finite length, when the end of the list is reached then
the player should `wrap’ the moves around and start from the beginning of the
list again. For example: If a warrior has the list “wassdq” as their moves
list, then for 8 iterations they would perform the moves “wassdqwa”, one per
iteration. See Section 5.0.1 for explanation of what direction each movement
character represents.
A maximum of 1 healer, 1 potion, 1 magic crystal, 1 weapon and 1 water piece
may together be present on a cell; warrior pieces however can occur with
multiple pieces at a cell at any one time with the constraint that a maximum
of 10 warrior pieces will occur on the same cell, see Section 5.1.3 for
exception handling for situations where this rule is violated.
Board Wrapping
When warrior cells move off the edge/corner of the grid, they wrap around to
the opposite edge/corner of the grid.
Warrior Health
High levels of health indicate that the player will likely be able to continue
in the game for quite a few iterations while low levels of health indicate
that the warrior might soon leave the game. If the warrior experiences a drop
in health equal to or below 0%, the warrior loses the game and is removed from
the grid (this removal comes into effect in the following iteration). Your
program should then immediately print “A warrior has left the game!”.
For each iteration and each warrior, the health of the warrior must be updated
according to the pieces that are present in the warrior’s neighbourhood for
that iteration. Note that the cell that the warrior occupies is not included
in its neighbourhood and the warrior does not interact with pieces present at
this cell unless explicitly specified by a rule.
Warrior Battle
During an iteration, each warrior is in battle with and can only be affected
by those warriors which are in their neighbourhood. A comparison must be made
between the defence strength of the current warrior and that of each of its
neighbour warriors: if the current warrior’s defence strength is greater or
equal to that of the neighbouring warrior then the current warrior does not
incur a reduction in health; if the current warrior’s defence strength is less
than that of the neighbouring warrior then the current warrior incurs a
reduction in health equal to that ofthe neighbouring warrior’s offense power.
Please make careful note of Section 3.14 point 3 when implementing warrior
battles.
In the situation where multiple warriors are present on the same cell on the
grid then for each warrior on the cell, their defence strength is increases by
2% for each additional warrior of the same type also on the cell (this change
remains after the iteration i.e. it does not only apply to the iteration at
which the overlapping occurs). This is due to the warriors sharing battle
skill information.
Age
If the age of a warrior is above 15, their defence strength strength must not
be above 70%. If the age of a warrior is above 25, their defence strength must
not be above 50%. If the age of a warrior is above 50, their defence strength
must not be above 30%.
Weapon Inventory
Each weapon has an allocated amount of offense power that it adds to the
warrior that carries it. When a warrior piece occupies the same cell as a
weapon piece, the warrior puts the weapon in their inventory; after which the
weapon is no longer on the grid. If multiple warrior pieces are present on a
cell as well as a weapon piece then the warrior with the highest offense power
acquires the weapon. In a situation where multiple warriors tie with the
highest offense power then the warrior with the lowest ID value obtains the
weapon.
Each warrior is only capable of holding a certain number limit, L, of weapons
at a given time but since warriors never refuse to pick up new weapons, the
warriors drop some weapons when they exceed L. This dropping takes place in
first-in-first-out order i.e. the weapon least recently picked up is the
weapon dropped. If a warrior has a full inventory then it is guaranteed that
they will, for the rest of the game have a full inventory since each time they
pick up a weapon they will drop the one least recently obtained. Note that
when a weapon is dropped, its offense benefit it reversed.
In the situation where two or more warriors are present at the same cell where
this cell also contains a weapon piece, then if a warrior picks this weapon up
and due to a full inventory also drops a weapon then the dropped weapon may
not again be picked up until the next iteration (i.e. the weapon cannot be
picked up in the same iteration in which it was dropped).
If a warrior loses and is removed from the grid then all the weapons in their
inventory are removed from the game with them.
Special Abilities
Each warrior has a special ability which they activate in a situation where
their health is below or equal to 10%. The ability is effective from the
iteration at which the ability was performed (i.e. the number of iterations
count includes the iteration at which the ability was performed as one of the
iterations). Each warrior may only activate their special ability once.
- Stone Warrior - The stone warrior generates an earthquake which creates an effective defence against its enemies. The warrior’s defence strength becomes set to the maximum of its current defense strength or 95% for 4 iterations. After which the warrior’s defence strength is set to the value it held before the ability was activated (subject to the rules of 3.7); any increase in defense strength gained for this stone warrior due to warrior alliances (Section 3.6 paragraph 2) during the time in which the special ability was activated are lost/overwritten after the 4 iterations. Unfortunately, due to the energy needed to create an earthquake, the warrior’s health decreases by 3% (note that this is not 3% of their warrior’s current health but it is literally the value 3%). Your program should immediately print “Special ability performed by stone warrior!”.
- Flame Warrior - This type of warrior generates a fire shield which results in a defence strength of 100% for 2 iterations, after which the warrior’s defence strength returns to the maximum of either its defence strength at the time of the ability activation or the value 70%; any increase in defense strength gained for this flame warrior due to warrior alliances (Section 3.6 paragraph 2) during the time in which the special ability was activated are lost/overwritten after the 2 iterations. Note that this value can be less than either of these in the situation where the warrior’s age necessitates a bound on the defence strength (Section 3.7). Your program should immediately print “Special ability performed by flame warrior!”.
- Water Warrior - The water warrior creates a watervapour shower which refresh the warrior and results in an increase in health of 20%(note that this is not 20% of their warrior’s current health but it is literally the value 20%) for the water warrior. Your program should immediately print “Special ability performed by water warrior!”.
- Air Warrior - This type of warrior manipulates the air into whirlwinds which attribute to an increase in offense strength of 30% (note that this is not 30% of their warrior’s current offense strength but it is literally the value 30%) for 3 iterations. After 3 iterations the offense strength is reduced by this 30%. Your program should immediately print “Special ability performed by air warrior!”.
Note that the bound on defence strength determined by the warrior’s age is not
taken into account for the iterations in which the stone/flame warrior’s
special ability is active (i.e. a warrior over 15 will be allowed to have a
defence strength of 75%/100% due to the nature of the special ability; it
therefore overrides the rules in Section 3.7). When determining what value the
warrior’s defence strength should return to after the stone/flame warrior’s
special ability period has completed, the defence strength bound determined by
age should be taken into consideration again.
Healer Pieces
- Restorer - When a warrior has a restorer piece in their neighbourhood, the warrior’s health increases by a value b where the benefit b is a value uniquely defined for each restorer piece in the program setup files.
- Peacemaker - When a peacemaker piece is in the neighbourhood of warrior, the other warriors in its neighbourhood do not attack the piece, the warrior therefore does not take any damage.
Potions
When a warrior has one or multiple potion objects in its neighbourhood, the
warrior drinks all available potions and is affected according to the rules in
Section 2.3.1. Potions do not disappear from the grid once used. A few
specific situation outcomes should be noted:
- If multiple potions of the same type are present in a warrior’s neighbourhood, the net effect is the same as one potion.
- If both a trance causing mixture and a trance healing mixture are present in a warrior’s neighbourhood then the warrior is not affected by the trance causing mixture.
- It is possible for a warrior to be affected by both the trance causing and invisibility mixture at one time.
- If a warrior is affected by the invisibility potion and encounters another invisibility potion; the second potion overrides the first and the invisibility lasts according to the second potion specification with a restarted iteration counter.
- If multiple invisibility potions are present in the warrior’s neighbourhood, the potion with the longest lasting strength is followed.
Water
Only a single water piece may be present in a cell on the grid and the pieces
act according to the following rules:
- If a cell contains a water piece and has 0 or 1 water objects in its neighbourhood, then the water object is removed from the grid (as if the water was absorbed into the ground).
- If a cell contains a water piece and has 2 or 3 water objects in its neighbourhood, then the water object remains on the grid.
- If a cell contains a water piece and has 4 or more water objects in its neighbourhood, then the water object is removed from the grid (as if the water flowed into the other water cells).
- If a cell does not contain a water object but has 3 water objects in its neighbourhood then a water object becomes present on the grid at this cell (as if the water flowed from the surrounding water).
During an iteration, if a warrior has one or more water objects in its
neighbourhood then the warrior takes a refreshing drink and their health is
increased by 3%. Each iteration where a warrior has no water objects in its
neighbourhood, the warrior’s health decreases by 0.5%.
Water warriors gain power from the water around them; for each water object in
the water warrior’s neighbourhood, its offense power is boosted by 1% (note
that this is a permanent change).
Magic Crystal
When the magic crystal has exactly 1 of each type of warrior in its
neighbourhood, configured in the formation one warrior per corner of the
neighbourhood, then the crystal is activated and removes all warriors from the
game except for those 4 that activated the magic crystal. The crystal itself
is then removed from the grid and no warrior battles occur for that iteration.
Your program should immediately print “The Magic Crystal has been activated!
Four warriors remain…”.
Exceptionally Important Info
- A helpful hint is that you should update each cell within the grid with respect to itself, taking into consideration information from its neighbourhood but never altering the neighbourhood cells around it. In other words, each cell is updated from the perspective of that cell where neighbouring cells affect it but it does not affect neighbouring cells.
- Since, within a single iteration, some operations alter the warrior’s attributes but other operations rely on these attribute values, the order in which these operations occur within the iteration result in different attribute value outcomes at the end of the iteration. It is therefore very important that you follow the operation order list below as this order will impact the statistics output printed at the end of your program execution. Please note that water and warrior movement updates come into effect at the beginning of each new grid configuration.
* If the magic crystal is activated, warriors should be removed from the grid as specified in Section 3.13.
* Warrior offense/health adjusted according to non-warrior pieces(water/restorer) in its neighbourhood and possible health decrease if no water is present in its neighbourhood.
* Warrior special abilities.
* Warrior’s defence adjusted according to warriors of the same type present on the same cell on the grid.
* Potions.
* Peacemaker check.
* Warrior battles (Rules in point 3 below).
* Increment age and update warrior attributes accordingly
* Weapon pick up.
* Check if a warrior has won. - It is therefore very important that, at the beginning of an iteration, you store the beginning values for an offense strength and defence strength; these stored values are then the ones used for comparison during battle. This prevents the issue of different outcomes since the updates made during battle do not affect the comparisons for the next warrior in the battle. It is vitally important that you get this right, if the test cases are working it is a good indication that you have grasped the concept.
- It is highly advised that you do the following to aid in a neat and effective project implementation.
* Look at the provided skeleton code structure and understand why each element has been put in place.
* Take some time to plan your coding strategy before jumping in and writing a bunch of code that could end up looking a bit like spaghetti.
* Use modular programming techniques to simplify your code, ideally to the extent that your method names `talk’ you through the algorithm without even reading the comments yet. Modular programming will also help to identify and fix bugs in your code since functionally different segments of code will be held in different methods.
Requirements
Your program should take in two command line arguments, the first argument
naming the path to the game setup file and the second a 0 or 1 value where 0
indicates no use of the game visualisation and a 1 indicates the use of the
game visualisation. When game visualisation is not used, your program should
output warrior statistics in accord with Section 4.1; when the game
visualisation is used then your program should output statistics in accord
with Section 4.1 as well as output visualisation as described in Section 4.2.
If you do not use the exact format described in the following sections, your
output will not be marked.
Warrior Statistics: command-line output
The starting grid’s stats and thereafter the stats for each iteration of the
game should be printed, your program should output command-line statistics for
each warrior still present on the grid. If the number of iterations to run is
zero then you should immediately print the statistics of the starting board.
The output order should list the information for each warrior starting with
the top left corner of the grid and ending with the bottom right corner of the
grid. The grid should be traversed similarly to the pattern of ordering shown
in Figure 4 (i.e. row for row (downwards direction), traversing the row cells
left to right). If multiple warriors are present at one cell on the grid, the
printing order should be in ascending order of the warrior object’s IDs.
Figure 4: Example grid traversal order
Each warrior’s statistics should be output on a new line and each value should
be separated by a space and then a comma character. The values are id, age,
health, offense power, defence strength, number of weapons in their inventory,
the type of warrior they are (“Stone”, “Flame”, “Water” or “Air”), the row
index and the column index of their position on the grid. See Table 1 for an
example of this format.
Warrior Statistics with Game Visualisation: command-line output
Visualisation output should be printed to the command line in the format
described below, once before any iterations (detailing the starting state
stats) and then once after every iteration of the game execution; each visual
grid should be matched with its statistics printed directly afterwards. Please
see the sample output files provided on sunLearn for examples of the output
format. If the number of game iterations is zero then you should print the
visual representation of the starting grid, the warrior statistics and
terminate. You have two options of output format, please specify in a
ReadMe.txt file included in your submission whether you used the plain
visualisation or the colourful visualisation output method since different
scripts will be used depending on your choice. Please note that the marks will
be exactly the same whether you choose the plain or the colourful output
versions, it is purely a choice of your own preference and since there could
be problems with plugin downloads etc in the case of the colourful version the
plain version is absolutely sufficient.
Plain Visualisation Format
After each iteration in the game execution, your program should print the
updated grid in the format of example output Figure 5. Each piece type has a
different character representation as defined in the list below; the displayed
item for each cell should be separated by a space character and a new line
must be printed after the final row (although not shown in the Figure 5
screenshot).
- A water warrior is represented by a `W’ character.
- A stone warrior is represented by a `S’ character.
- A flame warrior is represented by a `F’ character.
- An air warrior is represented by a `A’ character
- An empty cell is represented by a `.’ character.
- A potion piece is represented by a ‘p’ character.
- A healer piece is represented by a ‘h’ character.
- A magic crystal piece is represented by a ‘c’ character.
- A weapon piece is represented by a ‘x’ character.
- A water piece is represented by a ‘w’ character.
Since different pieces may overlap and occupy the same cell at the same time
the order of visualisation priority is as follows where those pieces higher in
the list should be prioritised in the display over those lower in the list. - If multiple warriors are present on a cell at one time, an integer number representing the number of warriors on the cell should be used instead of a warrior character.
- Warrior
- Magic crystal.
- Water
- Weapon
- Healer
- Potion
- Empty Cell
If an iteration occurs where only 1 warrior is present on the grid, your
program must print the grid as described above and follow it with the string
“A warrior has been proven victor!”. The game playout should be terminated at
this point and nothing else printed.
If an iteration occurs where 0 warriors are present on the grid, your program
must print the grid as described above and follow it with the string “No
warriors are left!”. The game playout should be terminated at this point and
nothing else printed.
Colourful Visualisation Format
The colourful visualisation allows certain piece types to be colour coded. The
format follows the rules in Section 4.2.1 but uses ANSI Escape Codes to
produce colour-coded command-line output. These ANSI escape codes can be used
in linux terminal and IntelliJ IDE without any extra plugin downloads/setting
changes but eclipse necessitates a plugin download before the colours will
display in the eclipse console; instructions for this are listed below.
Eclipse ANSI Escape Code plugin instructions:
- Click on the Help tab of eclipse
- Click on `Eclipse MarketPlace…’
- Type in “ANSI Escape in Console” into the search bar.
- Click install to the plugin named “ANSI Escape in Console” (see Figure 6)
- Accept the terms of the license agreement.
- Restart Eclipse
- Your eclipse should now have the required functionality. Please note that your may prefer the way the colours display in eclipse’s dark theme but it is up to your own preferences what you prefer. You can change the theme by going to eclipse’s Window tab, Preferences, General, Appearance and then select the dark theme (a restart may be required).
It is of the utmost importance that you use the colour codes defined in
ConsoleColours.java (on the SunLearn 144 home page under Project 2020). You
should add this colour library to your project and use printing statements in
the format of Figure 8 instead of those ordinarily formatted as Figure 7.