首页 > > 详细

CSSE7030讲解 、辅导 Python程序设计

Into The Breach (ish)
Assignment 2
Semester 1, 2024
CSSE7030
Due date: 24 May 2024, 16:00 GMT+10
1 Introduction
In this assignment, you will implement a (heavily) simpliffed version of the video game ”Into The
Breach”. In this game players defend a set of civilian buildings from giant monsters. In order to
achieve this goal, the player commands a set of equally giant mechanical heroes called ”Mechs”.
There are a variety of enemy and mech types, which each behave slightly differently. Gameplay is
described in section 3 of this document.
Unlike assignment 1, in this assignment you will be using object-oriented programming and following
the Apply Model-View-Controller design pattern shown in lectures. In addition to creating code for
modelling the game, you will be implementing a graphical user interface (GUI). An example of a
ffnal completed game is shown in Figure 1.
2 Getting Started
Download a2.zip from Blackboard — this archive contains the necessary ffles to start this assignment.
Once extracted, the a2.zip archive will provide the following ffles:
a2.py This is the only ffle you will submit and is where you write your code. Do not make changes
to any other ffles.
a2 support.py Do not modify or submit this ffle, it contains pre-deffned classes, functions, and constants
to assist you in some parts of your assignment. In addition to these, you are encouraged
to create your own constants and helper functions in a2.py where possible.
levels/ This folder contains a small collection of ffles used to initialize games of Into The Breach. In
addition to these, you are encouraged to create your own ffles to help test your implementation
where possible.
3 Gameplay
This section describes an overview of gameplay for Assignment 2. Where interactions are not explicitly
mentioned in this section, please see Section 4.
3.1 Deffnitions
Gameplay takes place on a rectangular grid of tiles called a board, on which different types of entities
can stand. There are three types of tile: Ground tiles, mountain tiles, and building tiles. Building
1Figure 1: Example screenshot from a completed implementation. Note that your display may look
slightly different depending on your operating system.
tiles each possess a given amount of health, which is the amount of damage they can suffer before
they are destroyed. A building is destroyed if its health drops to 0. A tile may be blocking, in which
case entities cannot stand on it. Tiles that are not blocking may have a maximum of one entity
standing on them at any given time. Ground tiles are never blocking, mountain tiles are always
blocking, and building tiles are blocking if and only if they are not destroyed.
Entities may either be Mechs, which are controlled by the player, or Enemies, which attack the
player’s mechs and buildings. There are two types of mech; the Tank Mech and the Heal Mech. There
are also two types of enemy; the Scorpion and the Fireffy. Each entity possesses 4 characteristics:
1. position: the coordinate of the tile within the board on which the entity is currently standing.
2. health: the remaining amount of damage the entity can suffer before it is destroyed. An entity
is destroyed the moment its health drops to 0, at which point it is immediately removed from
the game.
3. speed: the number of tiles the entity can move during its movement phase (see below for
details). Entities can only move horizontally and vertically; that is, moving one tile diagonally
is considered two individual movements.
4. strength: how much damage the entity deals to buildings and other entities (i.e. the amount
by which it reduces the health of attacked buildings or entities).
The game is turn based, with each turn consisting of a player movement phase, an attack phase, and
an enemy movement phase. During the player movement phase, the player has the option to move
each of the mechs under their control to a new tile on the grid. During the attacking phase, each
mech and enemy perform an attack: an action that can damage mechs, enemies, or even buildings.
Each enemy, mech, and building can only receive a certain amount of damage. If a mech or enemy
is destroyed before they attack during a given attack phase, they do not attack during that attack
phase. During the enemy movement phase, each enemy chooses a tile as their objective, and then
moves to a new tile on the grid such that they are closer to their objective. The order in which
2mechs and enemies move and attack is determined by a ffxed priority that will be displayed to the
user at all times.
A valid path within the board is a sequence of movements into vertically or horizontally adjacent
non-blocking tiles which do not contain an entity. The length of a valid path is the number of
movements made within it. Note that each entity can only move through valid paths of length less
than or equal to their maximum path length (speed).
A game of Into The Breach is over when either:
1. The player wins because at the end of an attack phase, all enemies are destroyed, at least one
mech is not destroyed, and at least one building on the board is not destroyed.
2. The player loses because at the end of an attack phase, all buildings on the board are destroyed,
or all mechs are destroyed.
3.2 Game phases
The game begins with a board of tiles, with entities occupying non-blocking tiles (at least one mech
and at least one enemy). The exact set of tiles and entities is given by the level ffle used to initialise
the game. Next to the board of tiles, a list is presented. Each element of the list displays an entity,
alongside its position, current health, and current strength. The list is ordered by entity priority,
with the highest priority entity appearing at the top (see Figure 1 for an example).
The following four phases repeat until the end of the game:
1. Player movement phase: This is the main phase of the game where all user interaction occurs.
The user may click on any tile on the board. The action taken after a tile is clicked is summarized
in Table 1. See Figure 2 for an example of the movement system. During the player
movement phase, the user may also click one of the three buttons:
ˆ If the user clicks the Save button, they should be prompted to enter a name for their save
ffle via a ffledialog. Upon entering a name and clicking to save the ffle, a new level ffle
should be created based on the current game state. If a mech has been moved before the
save button is clicked, the user is warned instead via an error message box.
ˆ If the user clicks the Load button they should be prompted to select a saved ffle with a
ffledialog. When they select a ffle gameplay should restart as if the selected level ffle was
the ffle used to initialise the game.
ˆ If the user clicks the Undo button, the most recent move made by the user during the
current player movement phase is reverted
ˆ If the user clicks the End Turn button, the current player movement phase is ended, and
the program moves onto the attack phase.
2. Attack phase: During the attack phase each entity, in descending order of priority, makes an
attack. An attack affects a certain set of tiles depending on the entity making it. See Table 2
for the tiles affected by each entity. If a building tile is affected by an attack, then that building
loses health equal to the strength of the attacking entity. If an entity is on a tile affected by
an attack, then that entity is affected in a manner depending on what entity is performing the
attack. See Table 2 for the effects of attacks for each entity. If an entity is destroyed during
the attack phase by an entity with higher priority, it does not attack and is removed from
the game. After each entity has performed an attack, the program immediately moves to the
enemy movement phase.
3. Enemy movement phase: During the enemy movement phase, all enemies are assigned an
objective. An objective is the position of a tile on the board and is assigned based on the type
of entity as described in Table 3. Each enemy, in descending priority order, then moves to the
3tile that minimizes the length of the shortest path from itself to it’s objective. Note that the
enemy can only move to tiles reachable via valid paths of length no greater than it’s speed. If
there exists no valid path from an enemy to its objective, the enemy does not change position.
After every enemy has moved, the display is updated and the program moves to termination
checking.
4. Termination checking: If all enemies are destroyed, at least one mech is not destroyed, and at
least one building on the board is not destroyed, the user has won and a victory message is
displayed via an info messagebox. If all buildings on the board are destroyed or all mechs are
destroyed, the user has lost and a defeat message is displayed via an info messagebox. Both
victory and defeat messageboxes ask the user if they wish to play again. If the user does want
to play again, then the game is reinitialised using the level ffle and gameplay starts again from
the beginning. If the user does not want to play again the program closes the game window
and exits gracefully. If no messageboxes were displayed then the program immediately returns
to the player movement phase.
Clicked Tile Action to take
Tile containing a mech that
has not moved during the
current movement phase
Tiles which the mech can move to are highlighted in green. Valid tiles
are those to which a valid path can be formed from the mech’s position
with length less than or equal to the mech’s speed.
Tile highlighted by clicking
a tile containing a mech
that has not moved during
the current movement phase
The relevant mech is moved to that tile.
Tile containing an enemy, or
Tile containing a mech that
has moved during the current
player movement phase
Tiles which will be attacked by that entity during the following attack
phase are highlighted in red.
Any other tile. Nothing.
Table 1: Effect of clicking tiles during player movment phase. Every time the user clicks a tile, all
previous highlighting is removed.
4Figure 2: Movement of a mech during the player movement phase. The user clicks on the Heal
Mech, and then clicks on one of the highlighted squares. Clicking the heal mech again highlights the
squares it will attack.
5Entity Tiles Affected Attack Effect
Tank Mech The two sets of five tiles extending
in a horizontal line from the
tank mech: beginning from the
tile directly left of the tank mech
and extending left, and beginning
from the tile directly right of the
tank mech and extending right respectively.
Receive
damage equal to strength of tank mech.
Heal Mech The four tiles directly adjacent to
heal mech (not including diagonals)
If
target is a mech, recover health equal to strength
of heal mech. Do nothing otherwise.
Scorpion The four sets of two tiles extending
in horizontal and vertical
lines from the scorpion: beginning
from the tile directly left
of the scorpion and extending left,
beginning from the tile directly
right of the scorpion and extending
right, beginning from the tile
directly above of the scorpion and
extending upward, and beginning
from the tile directly below scorpion
and extending downwards
respectively.
Receive damage equal to strength of scorpion.
Firefly The two sets of five tiles extending
in a vertical line from the firefly:
beginning from the tile directly
above of the firefly and extending
upwards, and beginning
from the tile directly below the
firefly and extending downwards
respectively.
Receive damage equal to strength of firefly.
Table 2: Entity attack behavior
Enemy Assigned Objective
Scorpion Position of tile containing mech with the greatest health. If two
mechs are tied for greatest health, choose position of tile containing
the mech with the highest priority.
Firefly Position of building tile with the least health amongst the buildings
that are not destroyed. If two buildings are tied for the least health,
choose the position of the building tile in the bottommost row.
If there is still a tie for lowest health, choose the position of the
building tile in the rightmost column.
Table 3: Enemy objectives
64 Implementation
NOTE: You are not permitted to add any additional import statements to a2.py. Doing
so will result in a deduction of up to 100% of your mark. You must not modify or remove the
import statements already provided to you in a2.py. Removing or modifying these existing import
statements may result in your code not functioning, and may result in a deduction of up to 100%
of your mark.
Required Classes and Methods
You will be following the Apple Model-View-Controller design pattern when implementing this assignment,
and are required to implement a number of classes in order to do so.
The class diagram in Figure 3 provides an overview of all of the classes you must implement in
your assignment, and the basic relationships between them. The details of these classes and their
methods are described in depth in Sections 4.1, 4.2 and 4.3. Within Figure 3:
ˆ Orange classes are those provided to you in the support file, or imported from TkInter.
ˆ Green classes are abstract classes. However, you are not required to enforce the abstract nature
of the green classes in their implementation. The purpose of this distinction is to indicate to
you that you should only ever instantiate the blue and orange classes in your program (though
you should instantiate the green classes to test them before beginning work on their subclasses).
ˆ Blue classes are concrete classes.
ˆ Solid arrows indicate inheritance (i.e. the “is-a” relationship).
ˆ Dotted arrows indicate composition (i.e. the “has-a” relationship). An arrow marked with 1-1
denotes that each instance of the class at the base of the arrow contains exactly one instance
of the class at the head of the arrow. An arrow marked with 1-N denotes that each instance of
the class at the base of the arrow may contain many instances of the class at the head of the
arrow.
Figure 3: Basic class relationship diagram for the classes in assignment 2.
The rest of this section describes the required implementation in detail. You should complete the
model section before attempting the view and controller sections, ensuring that everything you
implement is tested thoroughly, operating correctly, and passes all relevant Gradescope tests. You
will not be able to earn marks for the controller section until you have passed all Gradescope tests
for the model section.
NOTE: It is possible to recieve a passing grade on this assessment by completing section 4.1, providing
all hidden tests are passed, and no marks are lost on style (See section 5.2 for more detail on
style requirements)
74.1 Model
The following are the classes and methods you are required to implement as part of the model.
You should develop the classes in the order in which they are described in this section and test
each one (including on Gradescope) before moving on to the next class. Functionality marks are
awarded for each class (and each method) that work correctly. You will likely do very poorly if you
submit an attempt at every class, where no classes work according to the description. Some classes
require significantly more time to implement than others. The marks allocated to each class are not
necessarily an indication of their difficulty or the time required to complete them. You are allowed
(and encouraged) to write additional helper methods for any class to help break up long methods,
but these helper methods MUST be private (i.e. they must be named with a leading underscore).
4.1.1 Tile()
Tile is an abstract class from which all instantiated types of tile inherit. Provides default tile behavior,
which can be inherited or overridden by specific types of tiles. Abstract tiles are represented
by the character T. The init method does not take any arguments beyond self.
Tile should implement the following methods:
ˆ repr (self) -> str
Returns a machine readable string that could be used to construct an identical instance of the
tile.
ˆ str (self) -> str
Returns the character representing the type of the tile.
ˆ get tile name(self) -> str
Returns the name of the type of the tile (i.e. the name of the most specific class to which the
tile belongs).
ˆ is blocking(self) -> bool
Returns True only when the tile is blocking. By default tiles are not blocking
Examples:
>>> tile = Tile()
>>> tile
Tile()
>>> str(tile)
'T'
>>> tile.get_tile_name()
'Tile'
>>> tile.is_blocking()
False
4.1.2 Ground(Tile)
Ground inherits from Tile. Ground tiles represent simple, walkable ground with no special properties.
Ground tiles are never blocking and are represented by a space character (’ ’).
Examples:
8>>> ground = Ground()
>>> ground
Ground()
>>> str(ground)
' '
>>> ground.get_tile_name()
'Ground'
>>> ground.is_blocking()
False
4.1.3 Mountain(Tile)
Mountain inherits from Tile. Mountain tiles represent unpassable terrain. Mountain tiles are always
blocking and are represented by the character M.
Examples:
>>> mountain = Mountain()
>>> mountain
Mountain()
>>> str(mountain)
'M'
>>> mountain.get_tile_name()
'Mountain'
>>> mountain.is_blocking()
True
4.1.4 Building(Tile)
Building inherits from Tile. Building tiles represent one or more buildings that the player must
protect from enemies. Building tiles have an integer health value and can be destroyed. A building
tile is destroyed when its health drops to zero. The health value of a building can never increase
above 9. Building tiles are blocking only when they are not destroyed. Building tiles are represented
by their current health value, as a string.
In addition to the Tile methods that must be supported, Building should additonally implement
the following methods:
ˆ init (self, initial health: int) -> None
instantiates a building with the specified health. A precondition to this function is that the
specified health will be between 0 and 9 (inclusive).
ˆ is destroyed(self) -> bool
Returns True only when the building is destroyed.
ˆ damage(self, damage: int) -> None
Reduces the health of the building by the amount specified. Note that damage is not constrained
to be positive. The health of the building should be capped to be between 0 and 9 (inclusive).
This function should do nothing if the building is destroyed.
Examples:
9>>> building = Building(5)
>>> building
Building(5)
>>> str(building)
'5'
>>> building.is_destroyed()
False
>>> building.is_blocking()
True
>>> building.damage(-10)
>>> str(building)
'9'
>>> building.damage(15)
>>> str(building)
'0'
>>> building.is_destroyed()
True
>>> building.is_blocking()
False
>>> building.damage(-1)
>>> str(building)
'0'
4.1.5 Board()
Board represents a structured set of tiles. A board organizes tiles in a rectangular grid, where each
tile has an associated (row, column) position. (0,0) represents the top-left corner, (1,0) represents
the position directly below the top-left corner, and (0, 1) represents the position directly right of the
top left corner. The methods that must be implemented in Board are:
ˆ init (self, board: list[list[str]]) -> None
Sets up a new Board instance from the information in the board argument. Each list in board
represents a row of the board. The first list represents the top-most row of the board, and the
last list represents the bottom-most row of the board. The first character of each inner list
represents the left-most tile on that row, and the last character of each inner list represents the
right-most tile on that row. Each character should be mapped to the tile that the character
represents.
A precondition to this function is that each list (each row) within the given board will have
the same length. Another precondition to this function is that the given array will contain at
least one row. The final precondition to this function is that each character provided will be
the string representation of one of the tile subclasses described in previous sections.
ˆ repr (self) -> str
Returns a machine readable string that could be used to construct an identical instance of the
board.
ˆ str (self) -> str
Returns a string representation of the board. This is the string formed by concatenating the
characters representing each tile of a row in the order they appear (left to right), and then
concatenating each row in order (from top to bottom), separating each row with a new line
character.
10ˆ get dimensions(self) -> tuple[int, int]
Returns the (#rows, #columns) dimensions of the board.
ˆ get tile(self, position: tuple[int, int]) -> Tile
Returns the Tile instance located at the given position. A precondition to this function is that
the provided position will not be out of bounds, that is,
(0,0) <= position < self.get dimensions()
ˆ get buildings(self) -> dict[tuple[int, int], Building]
Returns a dictionary mapping the positions of buildings to the building instances at those
positions. This dictionary should only contain positions at which there is a building tile.
Examples:
>>> tiles = [[" ","4"],["6","M"]]
>>> board = Board(tiles)
>>> board
Board([[' ', '4'], ['6', 'M']])
>>> str(board)
' 4\n6M'
>>> board.get_dimensions()
(2, 2)
>>> board.get_tile((0,1))
Building(4)
>>> board.get_buildings()
{(0, 1): Building(4), (1, 0): Building(6)}
4.1.6 Entity()
Entity is an abstract class from which all instantiated types of entity inherit. This class provides
default entity behavior, which can be inherited or overridden by specific types of entities. All entities
exist at a given (row, column) position, and possess integer health, speed, and strength values. Note:
it is not the role of an entity to determine if the position it occupies exists or is valid. Like buildings,
entities can be destroyed. An entity is destroyed when its health drops to zero. Entities can be
friendly (that is, under player control), or not. Abstract entities are represented by the character E.
Entity should implement the following methods:
ˆ init (
self,
position: tuple[int, int],
initial health: int,
speed: int,
strength: int
) -> None:
Instantiates a new entity with the specified position, health, speed, and strength.
ˆ repr (self) -> str
Returns a machine readable string that could be used to construct an identical instance of the
entity.
ˆ str (self) -> str
11Returns the string representation of the entity. The string representation of an entity is a
comma separated list containing (in order): the character representing the type of the entity;
the row currently occupied by the entity; the column currently occupied by the entity; the
current health of the entity; the entity’s speed; and the entity’s strength.
ˆ get symbol(self) -> str
Returns the character that represents the entity type.
ˆ get name(self) -> str
Returns the name of the type of the entity (the name of the most specific class to which this
entity belongs).
ˆ get position(self) -> tuple[int, int]
Returns the (row, column) position currently occupied by the entity.
ˆ set position(self, position: tuple[int, int]) -> None
Moves the entity to the specified position.
ˆ get health(self) -> int
Returns the current health of the entity
ˆ get speed(self) -> int
Returns the speed of the entity
ˆ get strength(self) -> int
Returns the strength of the entity
ˆ damage(self, damage: int) -> None
Reduces the health of the entity by the amount specified. Note that the amount of damage
suffered is not constrained to be positive. The health of the entity should be capped to be
non-negative. The health of the entity should not be capped to any maximum value. This
function should do nothing if the entity is destroyed.
ˆ is alive(self) -> bool
Returns True if and only if the entity is not destroyed.
ˆ is friendly(self) -> bool
Returns True if and only if the entity is friendly. By default, entities are not friendly
ˆ get targets(self) -> list[tuple[int, int]]
Returns the positions that would be attacked by the entity during a combat phase. By default,
entities target vertically and horizontally adjacent tiles. When overriding get targets in
subclasses, see Table 2. Note: The order of elements in this list does not matter.
ˆ attack(self, entity: "Entity") -> None
12Applies this entity’s effect to the given entity. By default, entities deal damage equal to the
strength of the entity. When overridding the attack method in subclasses, refer to Table 2.
Note: as the attack method is defined as part of the definition of the Entity class, the typehint
for entity will need to be wrapped in double quotes or else python will throw a syntax error.
The type of entity is still Entity.
Examples:
>>> e1 = Entity((0,0),1,1,1)
>>> e1
Entity((0, 0), 1, 1, 1)
>>> str(e1)
'E,0,0,1,1,1'
>>> e1.get_symbol()
'E'
>>> e1.get_name()
'Entity'
>>> e1.is_friendly()
False
>>> e1.get_health()
1
>>> e1.get_speed()
1
>>> e1.get_strength()
1
>>> e1.get_position()
(0, 0)
>>> e1.set_position((24,4))
>>> e1.get_position()
(24, 4)
>>> e1.get_targets()
[(24, 5), (24, 3), (25, 4), (23, 4)]
>>> e1.get_health()
1
>>> e1.damage(2)
>>> e1.get_health()
0
>>> e1.is_alive()
False
>>> e1.damage(-4)
>>> e1.get_health()
0
>>> e2 = Entity((1,0),2,1,1)
>>> e2.get_health()
2
>>> e1.attack(e2)
>>> e2.get_health()
1
4.1.7 Mech(Entity)
Mech is an abstract class that inherits from Entity from which all instantiated types of mech inherit.
This class provides default mech behavior, which can be inherited or overridden by specific types of
13mechs. All mechs can be active (that is, able to be moved by user input), or not. Mechs are always
active upon instantiation. Additionally, all mechs also keep track of their previous position, that is,
the position they were at before the most recent call to set position. Mechs of any type are always
friendly. Abstract mechs are represented by the character M.
In addition to the Entity methods that must be supported, Mech should additionally implement the
following methods:
ˆ get old position(self) -> tuple[int,int]
Returns the previous position of the mech. If set position has never been called on the mech,
then the previous position will be current position.
ˆ enable(self) -> None
Sets the mech to be active.
ˆ disable(self) -> None
Sets the mech to not be active.
ˆ is active(self) -> bool
Returns true if and only if the mech is active.
Examples:
>>> mech = Mech((0,0),1,1,1)
>>> mech.get_symbol()
'M'
>>> mech.get_name()
'Mech'
>>> mech.is_friendly()
True
>>> mech.is_active()
True
>>> mech.get_old_position()
(0, 0)
>>> mech.set_position((1,1))
>>> mech.get_old_position()
(0, 0)
>>> mech.set_position((0,2))
>>> mech.get_old_position()
(1, 1)
>>> mech.disable()
>>> mech.is_active()
False
>>> mech.enable()
>>> mech.is_active()
True
4.1.8 TankMech(Mech)
TankMech inherits from Mech. TankMech represents a type of mech that attacks at a long range
horizontally. Tank mechs are represented by the character T.
Examples:
14>>> tank = TankMech((0,0),1,1,1)
>>> tank.get_symbol()
'T'
>>> tank.get_name()
'TankMech'
>>> tank.get_targets()
[(0, 1), (0, -1), (0, 2), (0, -2), (0, 3), (0, -3), (0, 4), (0, -4), (0, 5), (0, -5)]
4.1.9 HealMech(Mech)
HealMech inherits from Mech. HealMech represents a type of mech that does not deal damage, but
instead supports friendly units and buildings by healing (that is, increasing health); that is, HealMech
objects ‘damage‘ friendly units and buildings by a negative amount. In order to achieve this, the
get strength method of the HealMech should return a value equal to the negative of the heal mech’s
strength. A heal mech does nothing when attacking an entity that is not friendly. Heal mechs are
represented by the character H.
Examples:
>>> heal = HealMech((0,0),1,1,2)
>>> heal.get_symbol()
'H'
>>> heal.get_name()
'HealMech'
>>> heal.get_strength()
-2
>>> friendly = TankMech((1,1),1,1,1)
>>> not_friendly = Entity((1,1),1,1,1)
>>> friendly.get_health()
1
>>> heal.attack(friendly)
>>> friendly.get_health()
3
>>> not_friendly.get_health()
1
>>> heal.attack(not_friendly)
>>> not_friendly.get_health()
1
4.1.10 Enemy(Entity)
Enemy is an abstract class that inherits from Entity from which all instantiated types of enemy
inherit. This class provides default enemy behavior, which can be inherited or overridden by specific
types of enemies. All enemies have an objective, which is a position that the entity wants to move
towards. The objective of all enemies upon instantiation is the enemy’s current position. Enemies
of any type are never friendly. Abstract enemies are represented by the character N.
In addition to the Entity methods that must be supported, Enemy should additionally implement
the following methods:
ˆ get objective(self) -> tuple[int, int]
Returns the current objective of the enemy.
15ˆ update objective(self, entities: list[Entity], buildings: dict[tuple[int, int],
Building]) -> None
Updates the objective of the enemy based on a list of entities and dictionary of buildings,
according to Table 3. The default behavior (that is, the behavior in the abstract Enemy class)
is to set the objective of the enemy to the current position of the enemy. If no valid objective
exists, then the enemy’s objective should not change.
A precondition to this function is that the given list of entities is sorted in descending priority
order, with the first entity in the list being the highest priority.
Examples:
>>> enemy = Enemy((0,0),1,1,1)
>>> enemy.get_symbol()
'N'
>>> enemy.get_name()
'Enemy'
>>> enemy.get_objective()
(0, 0)
>>> enemy.set_position((3,3))
>>> entities = [TankMech((0,1),1,1,1), HealMech((0,2),2,1,1)]
>>> buildings = {(1,0): Building(1), (1,1): Building(2)}
>>> enemy.update_objective(entities, buildings)
>>> enemy.get_objective()
(3, 3)
4.1.11 Scorpion(Enemy)
Scorpion inherits from Enemy. Scorpion represents a type of enemy that attacks at a moderate
range in all directions, and targets mechs with the highest health. Scorpions are represented by the
character S.
Examples:
>>> scorpion = Scorpion((0,0),1,1,1)
>>> scorpion.get_symbol()
'S'
>>> scorpion.get_name()
'Scorpion'
>>> scorpion.get_targets()
[(0, 1), (0, -1), (1, 0), (-1, 0), (0, 2), (0, -2), (2, 0), (-2, 0)]
>>> entities = [TankMech((0,1),1,1,1), HealMech((0,2),2,1,1)]
>>> buildings = {(1,0): Building(1), (1,1): Building(2)}
>>> scorpion.update_objective(entities, buildings)
>>> scorpion.get_objective()
(0, 2)
4.1.12 Firefly(Enemy)
Firefly inherits from Entity. Firefly represents a type of enemy that attacks at a long range
vertically, and targets buildings with the lowest health. Fireflies are represented by the character F.
Examples:
>>> firefly = Firefly((0,0),1,1,1)
>>> firefly.get_symbol()
16'F'
>>> firefly.get_name()
'Firefly'
>>> firefly.get_targets()
[(1, 0), (-1, 0), (2, 0), (-2, 0), (3, 0), (-3, 0), (4, 0), (-4, 0), (5, 0), (-5, 0)]
>>> entities = [TankMech((0,1),1,1,1), HealMech((0,2),2,1,1)]
>>> buildings = {(1,0): Building(1), (1,1): Building(2)}
>>> firefly.u
联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!