Question 2 : Virus Wars
A popular subgenre of strategy game is the so-called Virus
War format, where the player is shown a field of cells, each
with a virus count, and may attack other cells within a
certain range.
We are going to write some classes in Python to implement a
simple Virus Wars game.
2a) The position class (9 points)
Everything within this game is going to require a position, so
it makes sense to define it up front. Define a class Position, with
the following fields:
- x (float) -> an x coordinate, must be
initialized.
- y (float) -> a y coordinate, must be
initialized.
- dx(float) -> a destination x co-ordinate,
initialized to zero.
- dy(float) -> a destination y co-ordinate,
initialized to zero.
- speed (float) -> determines rate of movement, must be
initialized. The speed cannot be negative. Raise a ValueError if
the speed is provided as a negative number.
Define the following methods, in addition to init.
- moveTo - takes an x and a y co-ordinate, and sets them to the
values of dx and dy respectively.
- tick - simulates one "second" of simulation time. During a
tick, if dx and dy are different than x and y, move x and y towards
the values of dx and dy by the value of speed. If x or y are less
than speed distance away from dx or dy respectively, set the value
of x or y to dx or dy.
- distance - takes self and other, calculates the euclidan
distance between self and other using pythagorean theorem.
2b) The Cell class (23 points)
Our cells are going to need a class, which needs to inherit
Position.
A cell has a number of fields. Define an initialization method
which takes arguments in the order (X, Y, colour, attackRange) and
sets the following:
- colour (string) -> indicates which team controls the cell.
Valid values include things like "Red", "Blue". Must be
initialized.
- viruses (integer) -> indicates the number of viruses
contained within the cell, initializes to 0 for cells with colour
"None", and initializes to 5 for all other colours.
- defense (integer) -> the accumulated defense points of the
cell, initializes to 10.
- maxDefense (integer) -> the maximum defense value,
initializes to 10.
- attackRange (float) -> the cell can't attack outside this
range, must be initialized.
- mood (string) -> Indicates whether a cell has been upgraded,
and what that upgrade is. Valid values are "Happy", "Busy",
"Stoic", and "Angry". Initializes to "Happy"
- "Happy" cells have a speed of 0.1, "Angry" cells have a speed
of 0.2, "Stoic" cells have a speed of 0.05, and "Busy" cells have a
speed of 0. Speed should be initialized accordingly.
The cell class must have the following methods aside from
__init__:
- tick -> takes no arguments (besides self). Determines the
behavior of the cell population, according the the cell's mood.
Happy cells produce 3 additional viruses each time tick is called.
Busy cells produce 8 additional viruses. Stoic cells produce 6
additional viruses per tick, and Angry cells produce 6 additional
viruses per tick. The defense parameter also moves towards the
value of maxDefense by 1 every tick, unless it is equal to
maxDefense. Don't forget to call tick for the inherited class!
- changeMood -> takes the argument newMood. Creates a
ValueError exception if the new mood is not in the list of valid
moods above, excluding "Happy". It costs 20 population for a cell
to change mood. If there are insufficient viruses, create a custom
VirusesInsufficient exception. Otherwise, subtract 20 from the
virus population and change the mood to the specified value. If
that value is "Stoic", change maxDefense to 30. If that value is
"Angry" or "Busy", change maxDefense to 5. Remember to adjust the
cell's speed for the new mood.
- attack -> takes other of type Cell as an argument. If other
not within the attack range of self, create an OutOfRange
exception. Otherwise, the cell attacks with it's whole population,
this is the base attack value. The actual attack
value is the base attack value minus the other cell's defense
value. If the defense value is greater than the base attack value,
reduce the defense by the base attack value. Otherwise, the defense
value is reduced to zero. If the actual attack value is greater
than the other cell's population, the attack succeeds the cell's
colour is changed to the that of the attacking cell, the cell's
population becomes the difference between the actual attack value
and the defending population. If the attack is unsuccessful, the
defending population is reduced by the actual attack value. If the
defending population and the actual attack value are the same, the
cell colour returns to "None." In any event, the population of the
attacking cell is reduced to zero.
- __eq__ -> Two cells are the same if they are at the same
co-ordinate, have the same number of viruses, defense value and
mood.
2c) The VirusGame class (13 points)
Create a new class VirusGame which contains the following
fields:
- cells -> a list of Cell objects. The initialization function
must take a parameter n, and generate a number of cells with random
positions between (-10.0,-10.0) and (10.0,10.0). One of these cells
(it doesn't matter which), must be initialized as a "Red" cell, and
one other cell must be initialized as a "Blue" cell. All cells have
an attack range of 3.0
And the following methods:
- checkVictory -> If all the cells have the same colour,
return that colour as a string. Otherwise, return "None
yet..."
- action -> Takes two Position objects. The algorithm always
goes with the first cell it finds that is within a radius of 1 for
both positions. If there is a cell at the first position and the
second position, the cell at the first position attacks the cell at
the second position. If the second position is not within range of
any cell, the first cell is "commanded" to move to the second
position. If the second position is within range of the first cell,
change the mood of that cell to "Busy", and be sure to handle any
exceptions. If the first position is not within range of a cell,
the method does nothing, regardless of the state of the second
cell.
- tick -> the tick method will invoke the tick methods of all
cells.
Python 3, I need help for b and c as a is done already.
a is posted as background information.