Assignment 2: Cosmic Warrior ��
Cosmic Warrior ��
Assignment Information
Welcome to assignment 2! Please read this slide, as well as all other slides in this lesson carefully.
Due date 11:59:00 PM Sunday 7 November 2021 (Sydney local time)
This assessment is CONFIDENTIAL. © University of Sydney.
This assignment is worth 20% of your �nal assessment.
A message to all students about posting on Ed
This is an assignment, and sta� are not permitted to give guidance on your code or how to solve the
speci�c problem. That is the purpose of the assessment that you are required to perform to achieve
the grade.
You may ask clari�cation questions about the assignment description. This is often necessary to
implement functionality that is otherwise ambiguous.
The assignment description is not intended to be complete and you can con�rm your assumptions
in a form of a question. In asking the question you should be quoting the description you are asking
about.
If you have a question to ask on Ed please search before asking. However, remember that you should
not be posting any assignment code publicly, as this would constitute academic dishonesty. Also, do
not wait too long before starting. This assignment needs time and sustained e�ort.
Restrictions
You may only import the following two modules. No other modules are permitted.
math
random
All built-in functions and types (those available without imports) may be used within reason.
Marking breakdown
Automatic test cases
You will submit your program using Ed’s submission system. Your program will be evaluated with
automatic test cases. Please ensure that you carefully follow the assignment speci�cation. Your
program must match the exact output in the examples and the test cases on Ed. You may submit as
many times as you like but only the latest submission will be used for your �nal mark.
You can add additional methods if desired, but you cannot change any existing method prototypes or
add additional �les.
In order to discourage hard coding, existing test cases may be adjusted, and new test cases may be
added after the due date.
Performance marking
Your bot ( Player class) will be tested against various scenarios and its �nal scores will be compared
against de�ned cuto�s, with increasing amounts of credit available for higher scores.
A leaderboard is available for you to gauge your bot’s performance against your classmates’.
It may be tempting to create something that performs very well on the leaderboard, but very badly in
performance marking. This is known as over�tting. Keep in mind that the game states used to generate your
�nal performance score are di�erent to the leaderboard states. It’s important not to optimise your strategy
against the leaderboard only.
Code style and structure
Your overall style will be evaluated, involving both code comments and variable naming and
consistency. It is acknowledged that some comments have been provided with the sca�old, however
you should provide comments in regards to lines of code you have written.
Your program variable names must be descriptive and follow snake_case. It is advisable that you
adhere to PEP8.
Avoid Magic Numbers. In the case of game constants, you should make use of values provided in
config.py .
Late Submissions
There are three separate submissions for this assignment. Refer to the course outline for late
penalties.
Late penalty will apply to late submissions to Ed (game code, style & structure) – 9% total
Late penalty will apply to late submissions to Ed (bot, style & structure) – 6% total
Late penalty will apply to late submissions to Canvas (report) – 5% total
Late penalties are applied separately to each submission.
Acknowledgements
Photo by Adrien Olichon on Unsplash
Icons made by Freepik from www.�aticon.com
‘Space Chronicles’: Why Exploring Space Still Matters
Game Overview
Asteroids have us in our sight. The dinosaurs didn’t have a space program, so they’re
not here to talk about this problem. We are, and we have the power to do something
about it. I don’t want to be the embarrassment of the galaxy, to have had the power to
de�ect an asteroid, and then not, and end up going extinct. We’d be the laughing stock
of the aliens of the cosmos if that were the case…. Astrophysicist Neil deGrasse Tyson
To raise awareness of the risk of asteroids to humanity, your mission is to create the Cosmic Warrior
game in order to demonstrate the e�ectiveness of spaceships in their use of advanced technologies
to defend against incoming asteroids.
Introduction
The game features your spaceship, as well as numerous asteroids that �oat around within the game
map. You can score by shooting asteroids with your ship’s cannons and the objective is to score as
high as possible before running out of fuel.
The map is unbounded, that is, objects that travel o� the screen edge immediately reappear on the
opposite side. This is known as wraparound.
Asteroids
Asteroids comes in two sizes, small and large. Smaller asteroids are worth more points as they
are harder to shoot (see table below).
Asteroids pose a major risk to your spaceship upon contact. You will lose points if your ship
crashes into an asteroid.
There will always be a constant number of asteroids in the map.
When an asteroid is destroyed, a new asteroid appears in the map.
Spaceship
Your spaceship can be manoeuvred through the use of its thrusters:
main thruster (accelerate / brake)
boosters (left turn / right turn)
The spaceship consumes one unit of fuel each frame, regardless of whether thrusters are used.
Bullets
Bullets destroy asteroids upon contact.
They travel much faster than your spaceship but have a limited range.
Each bullet costs two units of fuel. Use them wisely!
Game Constants
The following values are �xed and do not change.
All of these constants are provided in config.py .
Game Variables
The following values can change from game to game and are provided through a game state �le.
You can download sample game state �les as part of the sca�old from the “Where to start?” slide.
The game consists of various classes, three of which you will need to implement:
Engine: the main game engine, representing the game world & controls SpaceObjects
SpaceObject: game objects, namely spaceships, asteroids and bullets
Player: plays the game by controlling the spaceship
To help with your development e�orts, we provide a GUI class which can be used to visualise the
game. To use this class, you will need to install the pygame module. Here are the installation
instructions.
Engine class
Engine is located in �le game_engine.py
def __init__(self, game_state_filename, player_class,
gui_class)
Initialises the game engine with the following parameters:
game_state_�lename (path to the game state �le)
player_class & gui_class: the Player and GUI classes
Within the constructor, you should call the import_state() method (see below) and instantiate the
Player and GUI classes.
def import_state(self, game_state_filename)
Opens & imports data from game_state_filename . You will need to raise exceptions with speci�ed
messages if there are errors with the �le, namely:
If the �le is not found: FileNotFoundError(“Error: unable to open
If the �le is incomplete: ValueError(“Error: game state incomplete”)
If a line does not consist of a key and value pair: ValueError(“Error: expecting a key and
value in line
If a line contains an unexpected key: ValueError(“Error: unexpected key:
If a value contains an invalid data type: ValueError(“Error: invalid data type in line
def export_state(self, game_state_filename)
Opens game_state_filename and writes the game state data to it.
def run_game(self)
Starts running the game by launching a loop called game loop. Each iteration of this loop generates a
new frame, with three main actions required for each frame:
1. Receive player input
This is done by calling Player.action() with the current game state
Refer to the Player section for the player’s input
2. Process game logic
1. Manoeuvre the spaceship as per the Player’s input
Turning has priority over forward thruster
You do not need to consider circular motion
2. Update positions of asteroids by calling SpaceObject.move_forward() for each
asteroid
3. Update positions of bullets:
launch a new bullet if instructed by Player
New bullets are given a unique ID in increasing order, starting from 0
If fuel is less than the Minimum fuel to shoot bullet constant, do not
launch the bullet
print Cannot shoot due to low fuel
remove expired bullets (those that have travelled more than the “Bullet range”
constant)
update positions of bullets by calling SpaceObject.move_forward() for each bullet
4. Detect collisions
If a bullet collides with an asteroid, delete both objects and update score
print: Score:
If the spaceship collides with an asteroid, delete the asteroid and update score
print: Score:
In either case, replenish asteroids using the �rst available asteroid from Upcoming
asteroids
print: Added asteroid
If asteroids cannot be replenished, print Error: no more asteroids
available and end the game.
5. Deduct fuel for spaceship and bullets (if launched)
Print out the following warning message when fuel remaining drops to or below
75%, 50% and 25%:
3. Draw the game state on screen using the GUI class.
Refer to the GUI section.
Your game loop should continue to run until either:
the spaceship runs out of fuel
no more asteroids are available
SpaceObject class
SpaceObject is located in �le space_object.py
def __init__(self, x, y, width, height, angle, obj_type, id)
Initialises the SpaceObject with the following parameters:
x & y coordinates (�oat)
Map width & height (int)
angle of object (int)
type of object (string). Possible types are spaceship , bullet , asteroid_small ,
asteroid_large
ID (int)
def turn_left(self) and def turn_right(self)
Rotates the spaceship counterclockwise or clockwise according to the “Spaceship rotational speed”
constant, without changing position.
Asteroids or bullets do not rotate.
def move_forward(self)
Moves the object forward according to its speed constant while maintaining its direction (angle).
The trigonometric functions sine and cosine are extremely useful in this regard.
def get_xy(self)
Returns a 2-tuple containing the XY coordinate of the object.
def collide_with(self, other)
Return True if the object collides (overlaps) with other or False otherwise.
def __repr__(self)
Returns the object’s state as a string in the following format:
For example: asteroid_small 861.5,362.7,184,1
Player class
Player is located in �le player.py
As the player, you are the Cosmic Warrior and will take up the role of commander of your spaceship.
With the game objective in mind, you should come up with a game bot strategy which maximises
scores within the game’s constraints.
def __init__(self)
Initialises the Player class. You can either leave this empty or add your own logic. No speci�c
requirements here.
def action(self, spaceship, asteroid_ls, bullet_ls, fuel,
score)
Returns the next move of the spaceship as a list or 4-tuple, according to the table below.
The parameters are:
spaceship: spaceship object
asteroid_ls: list of visible asteroid objects (no upcoming asteroids)
bullet_ls: list of bullet objects
fuel: remaining fuel
score: current score
For example, to thrust forward without turning or �ring bullets, it would return (True, False,
False, False) .
N.B. If both counterclockwise and clockwise rotation are on, the spaceship does not turn.
You’re free to add any additional methods if required to implement your strategy. You may also do
your own research and implement arti�cial intelligence (AI) techniques not covered in this course, but
make sure all the code you write is your own.
GUI class
GUI is located in �le gui.py
The GUI class contains the game visualiser and is provided for your convenience. To use this class,
you will need to install the pygame module. Here are the installation instructions.
You should use the latest version of pygame (2.0.0 or later). We cannot guarantee compatibility with
older versions.
The pygame GUI cannot be ran on Ed. It must be ran on your computer.
def __init__(self, width, height)
Launches the visualiser using the given width and height. You should call the constructor once within
Engine.__init__()
def update_frame(self, spaceship, asteroid_ls, bullet_ls,
score, fuel)
Displays a new frame using the following arguments:
spaceship (SpaceObject)
asteroid_ls (list of SpaceObject)
bullet_ls (list of SpaceObject)
score (int)
fuel (int)
You should call this method immediately after processing each frame.
This function incurs a default delay of 0.03 seconds (yielding ~33fps) – you can adjust the
frame_delay constant in config.py if required.
def finish(self, score)
Displays the �nal score and closes the visualiser. You should call this method when the game
�nishes.
launch_game.py
This �le is the entry point to your game and is written for you. Its purpose is to import the
appropriate modules required for the game engine, and to start the game.
You should launch your game by running python3 launch_game.py
You may modify the game state �le path in line 5 if desired.
from game_engine import Engine
from gui import GUI
from player import Player
game = Engine(‘examples/game_state_good.txt’, Player, GUI)
game.run_game()
Report
As part of your submission you are required to write a report. The report is worth 5 marks and is
broken down into three sections:
Talk about your development process – 500 words (answer 3 questions)
1. How did you test and debug your game engine?
2. How did you handle wraparound for movements and collisions?
3. How did you test your �le parser ( import_state method)?
4. What problems could occur with �oating point calculations in this game, and how did you
deal with them?
5. What’s the most complex part of your code, and how would you make it more modular?
Indicate the �le name and line numbers.
6. Suppose your bot ( Player class) is for sale, which testing methodologies will you use and
why?
Talk about extending your game – 250 words (answer 1 question)
1. How would you add a second spaceship (multiplayer mode)? Describe all the steps
necessary to transform your program.
2. Suppose some asteroids carry natural fuel reserves. How would you capture the asteroid
and implement refuel capability?
3. Suppose asteroids may collide and break up into smaller asteroids. How would you
implement such behaviour?
4. Suppose your spaceship has an laser. The laser �res in a straight line, at light speed, and
destroys everything in its path. How would you change your collision detection method to
acommodate that?
Talk about your bot’s strategy – 500 words (answer all questions)
1. Provide a brief overview of your �nal strategy
2. How does your program use the available data to make decisions?
3. How would you adapt your strategy if you knew about the upcoming asteroids?
Additional information
The report must be submitted as a single PDF �le to Canvas
The report must be typed with a legible font and font size
You must clearly specify the questions numbers you have chosen to answer
answer 7 questions in total: 3 from section one, 1 from section two, 3 from section three
You may include pictures / diagrams where appropriate
Succinct, in-depth discussion is preferred over verbose answers, “quality over quantity”
All external sources must be referenced. See https://libguides.library.usyd.edu.au/citation
Table of contents and references are not part of the word count
Physics Refresher
This assignment requires the knowledge of basic physics and mathematics concepts (at high school
level). This page outlines the concepts that you need to know.
Game map coordinates
The game uses the Cartesian coordinate system where the coordinates correspond to the
distance of the point from the origin (top left corner).
(x, y)
width x-axis
y-axis
height
Euclidean distance
It is very easy to calculate euclidean distance (the distance between two points) – all you have to do is
to apply the pythagorean theorem.
width x-axis
y-axis
height
Angle representation
Angles in this game are expressed in degrees, where corresponds to the east and increases in
counterclockwise orientation.
0∘
Finding vector components
When we move objects around, we need to convert the displacement vector (angle and magnitude)
into x- and y- components used by our coordinate system. This is easily done with a little help from
trigonometry.
Suppose the magnitude (distance travelled) is and angle (direction / heading) is , then:Δs θ
Horizontal component: Δx = Δs cos(θ)
Vertical component: Δy = Δs sin(θ)
x
y
total distance
travelled
direction
of travel
In Python, trig functions are available through the math module. Additionally, we will need to
convert degrees into radians. Give the following code snippet a try:
import math
angle = 0
dx = math.cos(math.radians(angle))
dy = math.sin(math.radians(angle))
print(dx, dy)
Collision detection
We need to detect when asteroids collide with our spaceship or bullets. Fortunately, all objects in this
game are represented as circles, making this process simple.
Two circles collide when the euclidean distance between their centres are less than or equal to the
sum of their radii: d ≤ r +1 r 2
Non-colliding Colliding
Examples
Example Tests
These examples are provided through example_tests.py with additional �les in the examples
folder. Feel free to run them to assist with your development e�orts.
example_spaceobject_1: initialising & printing Space Object
example_spaceobject_2: moving Space Object
example_spaceobject_3: collision detection
example_game_basic_1: stationary spaceship with 2 asteroids
example_game_basic_2: moving spaceship with 2 asteroids
example_game_basic_3: moving & shooting, with 2 asteroids
The following video was recorded with frame_delay = 0.25 (4 fps).
To run these tests:
python example_tests.py example_spaceobject_1 | diff – examples/example_spaceobject_1.out
python example_tests.py example_spaceobject_2 | diff – examples/example_spaceobject_2.out
python example_tests.py example_spaceobject_3 | diff – examples/example_spaceobject_3.out
python example_tests.py example_game_basic_1 | diff – examples/example_game_basic_1.out
python example_tests.py example_game_basic_2 | diff – examples/example_game_basic_2.out
python example_tests.py example_game_basic_3 | diff – examples/example_game_basic_3.out
Sample Game State Files
Two game state �les are provided in the examples folder:
game_state_good.txt: A valid game state �le.
game_state_bad.txt: An example of an invalid game state. Your Engine should raise a
ValueError with message Error: invalid data type in line 7
Player / Game Bot
An example of a (reasonably good) bot playing a game
An example of a worse bot playing the same game
Where to start?
First make sure you have completed the week 10 tutorial on Classes!
Then, after reading through the assignment description carefully, download the sca�old from the
workspace on the right.
It is recommend that you implement classes in the following order:
1. SpaceObject
2. Engine
3. Player
Start small, try and pass the easy test cases as shown in the Examples slide before attempting the rest
of the assignment.
Game Code Submission
Submit your game code here.
Only submit game_engine.py and space_object.py – do not submit any other �les.
Academic declaration
By submitting this assignment you declare the following:
I declare that I have read and understood the University of Sydney Academic Dishonesty and
Plagiarism in Coursework Policy, and except where speci�cally acknowledged, the work contained in
this assignment or project is my own work and has not been copied from other sources or been
previously submitted for award or assessment.
I understand that failure to comply with the Academic Dishonesty and Plagiarism in Coursework
Policy can lead to severe penalties as outlined under Chapter 8 of the University of Sydney By-Law
1999 (as amended). These penalties may be imposed in cases where any signi�cant portion of my
submitted work has been copied without proper acknowledgement from other sources, including
published works, the internet, existing programs, the work of other students, or work previously
submitted for other awards or assessments.
I realize that I may be asked to identify those portions of the work contributed by me and required to
demonstrate my knowledge of the relevant material by answering oral questions or by undertaking
supplementary work, either written or in the laboratory, in order to arrive at the �nal assessment
mark.
I acknowledge that the School of Computer Science, in assessing this assignment, may reproduce it
entirely, may provide a copy to another member of faculty, and or communicate a copy of this
assignment to a plagiarism checking service or in the house computer program, and that a copy of
the assignment may be maintained by the service or the School of Computer Science for the purpose
of future plagiarism checking.
Warning: Any attempts to deceive or disrupt the marking system will result in an immediate zero for
the entire assignment. Negative marks can be assigned if you do not properly follow the assignment
description, or your code is unnecessarily or deliberately obfuscated.
Bot Submission
Submit your bot here.
Only submit player.py – do not submit any other �les.
Your Leaderboard ID will be visible after submission and your score will be shown on the
leaderboard within the next 30 minutes.
Please note all test cases here will never ‘pass’. This is intentional so that performance stats can be
collected.
Academic declaration
By submitting this assignment you declare the following:
I declare that I have read and understood the University of Sydney Academic Dishonesty and
Plagiarism in Coursework Policy, and except where speci�cally acknowledged, the work contained in
this assignment or project is my own work and has not been copied from other sources or been
previously submitted for award or assessment.
I understand that failure to comply with the Academic Dishonesty and Plagiarism in Coursework
Policy can lead to severe penalties as outlined under Chapter 8 of the University of Sydney By-Law
1999 (as amended). These penalties may be imposed in cases where any signi�cant portion of my
submitted work has been copied without proper acknowledgement from other sources, including
published works, the internet, existing programs, the work of other students, or work previously
submitted for other awards or assessments.
I realize that I may be asked to identify those portions of the work contributed by me and required to
demonstrate my knowledge of the relevant material by answering oral questions or by undertaking
supplementary work, either written or in the laboratory, in order to arrive at the �nal assessment
mark.
I acknowledge that the School of Computer Science, in assessing this assignment, may reproduce it
entirely, may provide a copy to another member of faculty, and or communicate a copy of this
assignment to a plagiarism checking service or in the house computer program, and that a copy of
the assignment may be maintained by the service or the School of Computer Science for the purpose
of future plagiarism checking.
Warning: Any attempts to deceive or disrupt the marking system will result in an immediate zero for
the entire assignment. Negative marks can be assigned if you do not properly follow the assignment
description, or your code is unnecessarily or deliberately obfuscated.
Report Submission
Submit on Canvas: https://canvas.sydney.edu.au/courses/35309/assignments/332325
Submission Checklist
a)
True
False
b)
True
False
c)
True
False
d)
True
False
Have you submitted game code ( game_engine.py , space_object.py ) to Ed?
Have you submitted your bot ( player.py ) to Ed?
Have you submitted the report ( report.pdf ) to Canvas?
Do you know your ID on the Leaderboard?
Leaderboard
Cosmic Warrior Leaderboard
Rank Identifier Timestamp
Basic
A
Basic
B
Complex
A
Complex
B
Complex
C
Getting Marks for Code Style