# 代写DPST1091 23T2

- 首页 >> Algorithm 算法

DPST1091 23T2
Assignment 1 - CS Defence
Tower Defence is a specific genre of games that boomed in the late 2000s. Many innovative games were created under this genre that pushed new and exciting ideas!

The core mechanics of these types of games are actually very simple! Waves of enemies continuously spawn (often forever!) and the player has the task of placing towers that will automatically fight these enemies. Both the player and enemies increase in strength over time and the defences need to be upgraded and improved to avoid enemies reaching a particular destination that could end the game!

CS Defence is heavily inspired by this genre, and specifically, one of the more famous games under its belt - Bloons Tower Defense. In this game, as well as CS Defence, enemies spawn from some start position and try to move to some end position via a path on the map. The player's goal is to place down towers that attack these enemies as they move. As towers destroy enemies, the player earns money that they can use to either upgrade or place down new towers.

Overview
Assignment Structure
This assignment will test your ability to create, use and manipulate 2D arrays and structs to solve problems. To do this, the map used in the game has been implemented as a 2D array of tiles. These tiles are each represented by a struct tile, which is outlined below:

struct tile

Purpose:
To store information about the tiles of the map.
Contains:
enum land land_type
The type of land this tile has.
All land types are found in the enum land definition.
enum entity entity
The type of entity that exists on top of the land for this tile.
All entity types are found in the enum entity definition.
int n_enemies
Represents the number of enemies at this tile in the map.
The provided enums are quite extensive. Definitions of each are provided below:

enum land

Purpose:
Represent the type of land.
Possible values:
GRASS
Represents a piece of grass. It is notable that towers can be placed on this land.
WATER
Represents a block of water. It is notable that towers cannot be placed on this land, with an exception mentioned in later stages.
PATH_START
Represents the start of the path on the map. It is notable that this is where enemies will spawn.
PATH_END
Represents the end of the path on the map. It is notable that enemies move to this location, and when reached, the player loses lives.
PATH_UP, PATH_RIGHT, PATH_DOWN, PATH_LEFT
Represents the “flow” of a path on this piece of land. Each of these types indicates the direction that the path is heading.
TELEPORTER
Represents a teleporter on the path that links to another teleporter. Similar use case as the path tiles mentioned, but allows for more complex path flow.
enum entity

Purpose:
Represent the kind of entity.
Possible values:
EMPTY
Represents no entity. Some tiles will only have land and no entity, this allows us to represent that.
ENEMY
Represents single or multiple enemies. Used when enemies are spawned and will move along the path.
BASIC_TOWER, POWER_TOWER, FORTIFIED_TOWER
Represents all the different types of towers that exist. Each tower has different abilities, specified in Stage 3.
Mental Model
A tile can always be thought of as a piece of land with an entity on top of it. Click through the different combination of land + entities below to build up this mental model of what a tile is!

In this assignment, you will have a 2D array of these tiles. This could represent a map like the one below:

example-map.png

You may notice that there is no starting tile in the example above. This is explained in Stage 2.1, but don't worry about it for now!
Implementation Model
Although the mental model mentioned above is a great way to understand how the map works in this assignment, it is also important to understand how it works in the code itself.

In this assignment, you will be need to manipulate a map provided which is defined as

struct tile map[MAP_ROWS][MAP_COLUMNS];,

where MAP_ROWS is 6 and MAP_COLUMNS is 12.

This means that we have a 2D array of struct tiles, which themselves have both entity + land enums associated with them.

Note that the indices indicate which struct in the array you are accessing, and the word after the . indicates which member of that struct that you are accessing.

For example in the map below, the land_type of the tile at row 3 and column 8 is PATH_DOWN and the type of entity that exists on top of the land for this tile is EMPTY. The number of enemies at this tile is 0:

map.jpg

How To Get Started
There are a few steps to getting started with CS Defence.

Create a new folder for your assignment work and move into it.

mkdir ass1
cd ass1

cp -n /web/dp1091/23T2/activities/cs_defence/cs_defence.c .
Run 1091 autotest cs_defence to make sure you have correctly downloaded the file.

1091 autotest cs_defence
When running the autotest on the starter code (with no modifications), it is expected to see failed tests.

Spend a few minutes playing with the reference solution -- get a feel for how the assignment works.

1091 cs_defence

You might also find it helpful to draw diagrams and write pseudocode between later stages, especially stage 3 and stage 4!
Start coding!
The provided starter code has done some setup for you. This is explained below.

Before the main function, the starter code has:

Imported the standard input/output library.
Defined some initial #define's and enums.
Defined the struct described above.
In the main function, the starter code:

Creates a 2D array of struct tiles called map.
Initialises this map with some default values.
Prompts you to write your own code!
To start with, feel free to write your code in the main function! You can also add in your own functions as you go - we would definitely recommend this :)
This assignment consists of four stages. Each stage builds on the work of the previous stage, and each stage has a higher complexity than its predecessor. You should complete the stages in order.

Stage 1 ●??
Stage 2 ●??
Stage 3 ●●?
Stage 4 ●●●
Stage 1
Stage 1.1 - Setup
To start off the assignment, you will need to initialise some basic information for the game. The starter code currently creates a 2D array of struct tiles and initialises them using the initialise_map() function that we’ve provided.

Your job is to take input from the user, asking them for their initial lives and money. An example of this is shown below:

dcc cs_defence.c -o cs_defence
./cs_defence
Starting Lives: 100
Starting Money(\$): 500
Once you have the above working, you will need to scan in the “starting” point on the map and the “ending” point on the map. We describe a point as 2 integers, indicating a row then column. The starting and ending points will indicate where enemies will spawn from, and where they need to get to respectively. Implementing this, your program should behave in the same manner as below:

dcc cs_defence.c -o cs_defence
./cs_defence
Starting Lives: 100
Starting Money(\$): 500
Start Point: 1 2
End Point: 4 10
In the example above, the start point is at row 1, column 2 and the ending point is at row 4, column 10.

These points can be visualised on the map like so:

1.1.1.jpg

You will need to modify the given 2D array, map, to account for these points.

Make sure to read through the overview of the given structs/enums to understand how they work before continuing.

Once you understand how each struct/enum works, it is important to know that the map variable in the code is a 2D array of struct tiles. Alternatively, it can also be thought of as a 2D array of land with optional entities on top of it, since this is what each tile represents.

Currently, all the land is simply grass. However, given the starting/ending point that was just scanned in, you should update the relevant tiles such that their land is now PATH_START and PATH_END respectively.

After this, you should print out the map using the provided print_map() function. When printing out the map, the start point will be printed as S and the ending point will be printed as E, assuming you’ve updated the land correctly!

Unsure how to call the print_map() function? Here is an example that you can copy to your main function.
print_map(map, 5, 10);
Notice how we only need to provide the map variable, no square brackets are required!
This will print your current map with 5 lives and \$10 in money. How could you modify this to use the lives/money that we scanned in?

Assumptions/Restrictions/Clarifications
Starting lives and money will always be given as numbers greater than 0.
Start/End points will always be valid indexes in the map array. They will never be out of bounds.
Start/End points will never be the same point.
Examples
You may like to autotest this section with the following command:
1091 autotest-stage 01_01 cs_defence
Remember to do your own testing!

Stage 1.2 - Initial Enemies
Tower defence games aren’t quite so fun when enemies don’t exist! For Stage 1.2, you will add some initial enemies to the starting point on the map. After printing out the map in the previous section, you should scan in how many enemies to put at the starting point:

Initial Enemies: [num]
To add enemies to the starting tile, you need to do two things:

Set the entity component at that tile to ENEMY.
Set the n_enemies component of that tile to the number scanned in.
In the case where num is 0 or negative, the starting tile should not change.

After scanning in the enemies, you will need to print out the map again. If done correctly, the map will now show a number above the 'S' on the starting tile!

Assumptions/Restrictions/Clarifications
You can assume that the initial enemies will never be greater than 999.
Examples
You may like to autotest this section with the following command:
1091 autotest-stage 01_02 cs_defence
Remember to do your own testing!

Stage 1.3 - Lake
A common way to increase the difficulty of Tower Defence games is to add environmental obstacles, rather than just bombarding the player with more enemies. For Stage 1.3, you will add the ability to create a lake on the map! Lakes restrict the types of towers that can be placed on them.

After printing out the map in the previous section, you should scan in information about this lake:

Enter Lake: [row] [column] [height] [width]
The row and column that are scanned in indicate where the lake starts. The height and width indicate how far the lake stretches out in both dimensions. The lake always stretches down and to the right with these dimensions.

For every tile that appears in the lake on the map, their land component should be set to WATER.

After filling in the lake, the map should be printed again.

As an example, assume we give the program the following input:

Enter Lake: 1 2 4 6
The map would then look like this (ignoring start/ending tiles and initial enemies):

1.3.1.png

If you haven't started thinking about using functions yet, now is a good time!
It is highly recommended that you write the code for Stage 1.3 in a separate function to get a feel for writing functions in this assignment.

Error Handling
If the row and column provided is outside the map, or the height or width would stretch the lake outside the map, the message below should be printed and no lake should be added.

"Error: Lake out of bounds, ignoring...".

Checking if a point is inside the map is going to be a very common operation that you do throughout this assignment. As a result, it is a good idea to prevent this repetition where possible... Through a function!
Here is a small function that you can modify and use in your assignment:

int valid_point(int row, int column) {
return row > 0 && column > 0;
}
How could you modify this function to return whether the combination of row and column is a valid point?

Assumptions/Restrictions/Clarifications
The given lake will never overlap with the start/end points.
The height and width entered will always be positive integers.
When handling the lake out-of-bounds error mentioned, the program should still continue normally. This error should only cause the lake to be ignored, and no water to be added to the map.
The map should still be printed even if the lake out-of-bounds error occurs.
Examples
You may like to autotest this section with the following command:
1091 autotest-stage 01_03 cs_defence
Remember to do your own testing!

Testing and Submission
Are you finished with this stage? If so, you should make sure to do the following:

Run 1091 style, and clean up any issues a human may have reading your code. Don't forget -- 10% of your mark in the assignment is based on style!
Autotest for this stage of the assignment by running the autotest-stage command as shown below.
Remember -- give early, and give often. Only your last submission counts, but why not be safe and submit right now?
1091 style cs_defence.c
1091 autotest-stage 01 cs_defence
give dp1091 ass1_cs_defence cs_defence.c

Assessment
Assignment Conditions
Joint work is not permitted on this assignment.

This is an individual assignment.

The work you submit must be entirely your own work. Submission of any work even partly written by any other person is not permitted.

Except, you may use small amounts (< 10 lines) of general purpose code (not specific to the assignment) obtained from a site such as Stack Overflow or other publically available resources. You should attribute clearly the source of this code in an accompanying comment.

Assignment submissions will be examined, both automatically and manually for work written by others.

Do not request help from anyone other than the teaching staff of DPST1091, e.g. in the course forum & help sessions.

Do not post your assignment code to the course forum - the teaching staff can view assignment code you have recently autotested or submitted with give.

Rationale: this assignment is designed to develop the individual skills needed to produce an entire working program. Using code written by or taken from other people will stop you learning these skills. Other CSE courses focus on the skill needed for work in a team.

The use of code-synthesis tools, such as GitHub Copilot, or any AI software such as ChatGPT, is not permitted on this assignment.

Rationale: this assignment is intended to develop your understanding of basic concepts. Using synthesis tools will stop you learning these fundamental concepts.

Sharing, publishing, distributing your assignment work is not permitted.

Do not provide or show your assignment work to any other person other than the teaching staff of DPST1091. For example, do not message your work to friends.

Do not publish your assignment code via the internet. For example, do not place your assignment in a public GitHub repository.

Rationale: by publishing or sharing your work you are facilitating other students using your work which is not permitted. If they submit your work, you may become involved in an academic integrity investigation.

Sharing, publishing, distributing your assignment work after the completion of DPST1091 is not permitted.

For example, do not place your assignment in a public GitHub repository after DPST1091 is over.

Rationale: DPST1091 sometimes reuses assignment themes using similar concepts and content. Students in future terms find your code and use it which is not permitted and you may become involved in an academic integrity investigation.

Violation of the above conditions may result in an academic integrity investigation with possible penalties, up to and including a mark of 0 in DPST1091 and exclusion from UNSW.

Relevant scholarship authorities will be informed if students holding scholarships are involved in an incident of plagiarism or other misconduct. If you knowingly provide or show your assignment work to another person for any reason, and work derived from it is submitted you may be penalised, even if the work was submitted without your knowledge or consent. This may apply even if your work is submitted by a third party unknown to you.

Note, you will not be penalised if your work is taken without your consent or knowledge.

0 for the assignmentKnowingly providing your work to anyone and it is subsequently submitted (by anyone).
0 for the assignmentSubmitting any other person's work. This includes joint work.
0 FL for DPST1091Paying another person to complete work. Submitting another person's work without their consent.
Submission of Work
You should submit intermediate versions of your assignment. Every time you autotest or submit, a copy will be saved as a backup. You can find those backups here, by logging in, and choosing the yellow button next to 'cs_defence.c'.

Every time you work on the assignment and make some progress you should copy your work to your CSE account and submit it using the give command below.

It is fine if intermediate versions do not compile or otherwise fail submission tests.

Only the final submitted version of your assignment will be marked.

You submit your work like this:

give dp1091 ass1_cs_defence cs_defence.c
Assessment Scheme