联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> Python编程Python编程

日期:2018-06-15 09:27

CSC148 Summer 2018: Assignment 1

Due: Sunday, June 17th @ 11PM

Overview

In this assignment, you'll be implementing a Battle Game. This game consists of two types of

characters which can perform various attacks against each other. In this assignment, you'll be

implementing various classes and designing their functionality (in order to fit the

requirements of the client code), getting practice with inheritance and composition, as well as

implementing a type of queue.

This assignment contains lots of small parts for you to implement, and may require some

planning. It's recommended that you organize your code on paper first (write out what classes

you'll need, what attributes they should have, what methods, their relationship to other

classes) before you start coding in order to save yourself from re-writing and re-organizing

your code.

This document is fairly verbose, as we've decided to explain parts of the client code and classes

provided in some detail. Most of this documentation is also present in the starter code, of

which a description is provided below. Please take your time to read through it!

You will still have to read the client code to understand the names of methods that we expect.

At the end of this document, the grading scheme for this assignment has also been provided to

you. There should be no surprises when the assignments are graded, as you should be able to

estimate 60% of your final grade prior to submitting.

Plagiarism

As with all exercises and assignments: there is no tolerance for plagiarism. We do have tools to

detect plagiarism, and it does so extremely well. This assignment is also being used for the first

time, so searching online for a solution won't be too helpful. Remember: If you can search for a

solution online, so can we.

Absolutely do not post any of your assignment code or show it to anyone aside from the

CSC148 course staff! If someone plagiarises your work, you're both at risk.

A typical penalty for a first offence is a zero on the assignment. The case will also be entered

into the UofT academic offence database. (If you get caught a second time ever as an

undergrad, the penalties are much, much more severe.)

Our tips to avoiding plagiarism:

● Remember that figuring out what code needs to be written is the most important part of

the assignment. Typing out code based on steps that someone else gave you is

considered cheating, as you are submitting someone else's ideas as your own.

● Don't search the web for solutions. We've already done that and will be comparing what

we found with what you submit. It doesn't help to change variable names and move

functions around. Our software will still find you.

● Don't ask your friend for their solution, even if you just want it to "see how to solve it".

Don't show your friends your solution either.

● Don't get solutions, or partial solutions, from a tutor. They frequently provide the same

code or ideas to more than one person. We know because we frequently catch people

who do it.

● Only ask for detailed help on your code from official CSC148 course staff, including the

Help Centre.

● If you can't figure out how to write a function, it's often because you haven't fully

understood an underlying concept. Review the materials on that topic, experiment in

the Python shell, and ask us for help!

● Remember that it is better to submit an assignment with a few missing functions than

to cheat!

Please also see the Collaboration Policy on the Assignment page.

Your Task

For this assignment, you will need the pygame library.

If you don't have it: You can download this through Pycharm (similar to how we installed

python-ta), or by opening terminal/cmd.exe (depending on what system you're using) and

running the command:

py -m pip install pygame

Download a1.zip and extract the files in it. This contains all of the starter code and files used by

the starter code:

● a1_game.py: The file with client code for you to read and understand. Fill in the

dictionaries at the top of the file, putting in the class names as needed.

○ The perform_attack() function gets called whenever an action is to be made. It

tries to decide on a move to make by using the next player's playstyle and

selecting an attack. It then tries to make the next player in the battle_queue

perform that action, removing the player from the queue if it can. This is called

whenever a key is pressed if the next player in the battle_queue is using the

Manual playstyle, or every few seconds if the next player in the battle_queue is

using a non-Manual playstyle.

○ The set_up_game() function is called before a game is created. It sets up the

parameters of which characters to use, what names to give them, which

playstyle to use, and which player acts first.

○ The update_ui() function is called repeatedly (every 100 milliseconds) and

updates the ui by giving the next sprites to draw and updating the Health Points

(HP) and Skill Points (SP) displays. Most of the getters you'll need to write are

called here.

● a1_ui.py: When you want to run the game, run a1_ui.py! You do not need to read or

understand any of the code in this file (although you can if you want). a1_ui.py is the

file that actually runs your code and draws it in pygame, making calls to the functions

and looking at the variables defined in a1_game.py. We've moved it to another file so

that you can focus on the client code as opposed to the details of pygame.

● a1_rogue_unittest.py: The file that contains basic test cases for the rogue character

you'll be implementing. Passing these tests ensures that our test scripts can run on

your code, and will determine a portion of your mark (see Grading Scheme).

● a1_mage_unittest.py: The file that contains basic test cases for the mage character

you'll be implementing. Passing these tests ensures that our test scripts can run on

your code, and will determine a portion of your mark (see Grading Scheme).

● a1_battle_queue.py: The file containing your BattleQueue class. The method headers

and descriptions have been provided for you already, but not the implementation.

○ Fill in the docstrings, type annotations, implementation, and make sure to test

this on your own. No test cases have been provided for the battle queue!

● a1_playstyle.py: The file containing various Playstyle classes. The Manual playstyle

class has been provided for you, but you are tasked with implementing the Random

playstyle, which will pick one of the available skills at random.

● sprites (folder): This folder contains the sprites used by a1_ui.py. The sprites all have

the name format: [character]_[type]_#.png where [character] is rogue or mage, [type]

is idle, attack, or special, and # is a number from 0 - 9. Your get_next_sprite() method

for the classes you implement should return a name in that format. For example:

○ rogue_idle_0.png

○ mage_attack_2.png

○ mage_special_9.png

● a1_pyta.txt: The python_ta file to use for this assignment.

Description of Classes

Below is a description of the classes you'll encounter in this assignment. Note that you may

want to implement additional classes beyond those that are mentioned below, and that it's

highly recommended for you to do so.

Characters

In this assignment, there are 2 characters that are available: Rogue and Mage. These are the

characters that can be chosen to fight. All characters start with 100 Health Points ("HP"), 100

Skill Points ("SP"), and their respective defense stats (unique to each character). They also

have a name that they start with, a playstyle, an "animation state", certain skills that they can

use, and an enemy that they target. The BattleQueue that's being used is also passed into them

as an attribute for convenience.

There are 2 types of skills which the Manual Playstyle has key mappings for:

● "A": Attacks; these are the basic attacks performed by a character. Details are in the

character descriptions.

○ They are called using the attack() method.

● "S": Special attacks; these are special skills performed by a character. Details are in the

character descriptions. These skills can have additional effects beyond simply causing

damage to their enemy.

○ They are called using the special_attack() method.

When a character is hit by a skill, their HP is reduced by (Damage - Defense) amount. The

character performing a skill loses a certain number of SP based on the skill used.

The "animation state" keeps track of which sprite needs to be drawn next, and is based on the

action taken by the character. If the character isn't doing anything, or if an animation has just

ended, it should provide the sprites for its idle animation (e.g. [character]_idle_0, then

[character]_idle_1, and so on).

When a character attacks, the next sprite to be drawn should be the corresponding attack

frame (e.g., [character]_attack_0, then [character]_attack_1, and so on until

[character]_attack_9, after which it goes to [character]_idle_0) -- once that ends, it

should return to the idle animation.

The same goes for its special attack (e.g., [character]_special_0, then

[character]_special_1, and so on until [character]_special_9, after which it goes to

[character]_idle_0).

In this assignment, we won't be forcing you to use any specific implementation for this. The

only thing you need to do is make sure the get_next_sprite() method returns the next sprite

to be drawn (this should always return [character]_idle_0 first for a character that has yet to

perform any action, but if we call an action before our first call to get_next_sprite() such as

attacking, we should return the corresponding 0th frame, e.g. [character]_attack_0).

For more information about sprites/get_next_sprite():

Go to the end of the document "Appendix A: Sprites"

See the set_up_game() function in a1_game.py to see how a character is initialized. In addition

to its initialization, characters must have an .enemy attribute which will be set prior to any

attacks being called. This is also done in the set_up_game() function.

Rogue

A rogue is a character with 10 defense. Their skills are as follows:

● "A" (Attacks): Deals 15 damage and adds the Rogue to the end of the BattleQueue. Takes

3 SP.

● "S" (Special Attacks): Deals 20 damage and adds the Rogue to the BattleQueue twice, so

it can attack twice in succession. Takes 10 SP.

Mage

A mage is a character with 8 defense. Their skills are as follows:

● "A" (Attacks): Deals 20 damage and adds the Mage to the end of the BattleQueue. Takes

5 SP.

● "S" (Special Attacks): Deals 40 damage and adds its enemy to the BattleQueue once

before adding the Mage itself into the BattleQueue (i.e. the enemy gets to attack an

additional time before the Mage is able to attack again). Takes 30 SP.

Other Notes

While only existent in the docstring examples for BattleQueue and in the unittests, your

Characters should have a __repr__ which takes the following form:

Name (Character): HP/SP

For example, for a Rogue named Sophia with 13 HP and 37 SP, the repr should return

Sophia (Rogue): 13/37

Playstyle

The Playstyle classes represent ways for us to choose attacks. There are 2 attributes for a

Playstyle: one representing whether it's a Manual mode or not, and another representing the

battle queue that the Playstyle is used in. When it's called to perform an action, it'll try to

decide an action for the first person in that BattleQueue. The Manual Playstyle has been

provided for you. It simply takes the key that is pressed and returns that key if it's a proper

attack ("A" or "S").

You are tasked with implementing the Random Playstyle, which returns a key for a move that

can be used by the player (e.g. if the character has enough SP for only a normal attack, it should

return 'A'. If they have enough SP for either a normal or a special attack, it should return either

'A' or 'S') at random.

Docstring examples are not required for Playstyles.

BattleQueue

A BattleQueue is a queue that lets our game know in what order various characters are going to

attack. The method headers and descriptions have all been provided for you, but the

implementation will depend on you.

In addition to the regular queue methods (add(), remove(), and is_empty()), three additional

methods are required:

● peek() should return (but not remove) the next person in the BattleQueue who can use

a skill (similar to how remove() and is_empty() ignores characters who can't use

skills).

○ You may assume that we will call is_over() before calling peek(), and that we

won't call peek() on an empty BattleQueue.

● is_over() should check whether the game being carried out in the BattleQueue is over

or not. The game is considered over if any of these conditions are true:

○ Both players have no skills that they can use (because they have too little/no SP)

○ One player has 0 HP

○ The BattleQueue is empty (which should only happen if no players have any

skills that they can use).

● get_winner()should return the winner of the game, if there is one. If not, or if the

game is not over yet, it should return None. The winner of the game is considered to be

the one who has more than 0 HP when the game is over if the other player has 0 HP. In

all other cases (e.g. the game not being over or both players being unable to use any

skills), the winner is None.

○ The winner returned should refer to the object, not their name.

Additionally, remove() and is_empty() should ignore any characters that have no skills at

their disposal. I.e.:

● remove() should return the next character in the BattleQueue who can use a skill.

○ When testing, we will not try to remove from a BattleQueue that is empty (i.e. if

is_empty() returns True, we won't try to remove from the BattleQueue).

● is_empty() should return True if there are no characters in the BattleQueue who can

use skills.

You may add additional methods to your BattleQueue if you would like, but they won't be

tested. The documentation will, however, still be graded.

Submission

Exercises are to be submitted through MarkUs in the a1 folder. You only need to submit

a1_game.py, a1_battle_queue.py, a1_playstyle.py and any files you've written/imported into

a1_game.py. You do not need to submit any of the icons provided, a1_ui.py, or the unittests

provided.

To log in to MarkUs, use your UTORid as the log-in name. The password is your teaching labs

password. If you have not set this up or have forgotten your password, go to the Teaching Lab's

Account Management Page and (re)set your password.

Lateness Penalty

If you are unable to complete course work due to an emergency (e.g. illness, injury, or other

serious situations), please e-mail Sophia as soon as possible.

You have 6 grace tokens shared across both assignments, with each of them being worth 2

hours each. Submitting an assignment late will reduce the total number of grace tokens (i.e. 1

minutes late will remove 1 token, 2 hours and 1 minute late will remove 2 tokens in total, etc.).

You can distribute these across your assignments however you like. Work submitted beyond

the extensions provided by grace tokens (i.e. you ran out) will not be graded unless you have

special circumstances.

Grading Scheme

Below is the grading scheme for this assignment. As this is provided, there shouldn't be many

surprises when you receive your mark, as you should be able to estimate at least 60% of your

grade following the below rubric.

20% Code Style

● 10% PythonTA: For every PythonTA violation, you'll lose a portion of this grade. Make

sure all of the files you submit are PythonTA compliant.

○ This excludes a1_game.py -- that file is not to have PythonTA run on it.

● 10% Documentation: Documentation includes: type annotations, docstrings (the

existence of them, and the quality of them), and docstring examples for all code that

you write. Docstring examples are not needed for a1_playstyle.py, and only the type

annotations and docstring examples in a1_battle_queue.py will be marked (as we have

done the majority of the documentation for you in that file).

80% Code Correctness

Code correctness is based entirely on passing test scripts.

● 40% for the Provided Unittests: You lose a portion of your mark for each test case you

fail (proportional to how many test cases are in the file).

○ 20% for a1_rogue_unittest.py

○ 20% for a1_mage_unittest.py

Passing the provided unittests does not guarantee that your code is flawless. The tests

only provide a basic check for functionality, and ensures that our hidden tests are able

to run.

○ These tests also do not include detailed tests for the BattleQueue -- there are

part of our hidden tests. You are to test your BattleQueue on your own.

● 40% for Hidden Tests: The hidden tests will test for correctness of your code in various

scenarios. If you do not pass the provided unittests, you will likely also not pass most of

the hidden tests.

○ Examples of what the hidden tests may check for include (but are not limited

to):

■ Edge cases.

■ Various combinations of (valid) method calls.

■ Various ways of 'finishing' a battle.

■ Whether you're using inheritance or not.

■ Whether you're using inheritance correctly.

■ Functionality of your BattleQueue class.

● Especially testing your BattleQueue to make sure it ignores

characters without enough SP to act.

● We may forcibly add/remove from a BattleQueue to put things

into a certain order.

○ We will not test on any invalid input. For example:

■ We will not try to remove from or peek at a BattleQueue if it's empty

(unless it's empty when it shouldn't be).

■ We will not try to make perform certain attacks if they're not valid, but

we will want check if it's valid or not.

■ We will not pass in anything unexpected: if a method is supposed to take

in an int, then we'll pass in an int.

■ We will not have a player's enemy in a different BattleQueue than what

the player has. (i.e. assume that a player and their enemy are both in the

same BattleQueue.)

■ We will not call is_empty() if is_over() is True because a character has 0

HP.

● We will, however, call is_empty() on cases where both players

don't have enough SP to act.

○ One thing that we may do (and which is done in the unittests provided) is ignore

the BattleQueue all together and just use skills.

■ We will not test the state of the BattleQueue if we do this though, since it

doesn't make sense; this is just to check other methods (such as

get_next_sprite(), is_valid_actions(), etc.)

○ We will also not test your the correctness of your Playstyle class. This is just for

you to be able to use your class, and to become familiar with how the Playstyle

functions should work, as they'll be important for A2.

■ With that said, your code should still be documented properly, as we will

check that. Docstring examples, however, are not required for Playstyle

classes.

○ If you have any questions about what might be tested, ask Sophia (Piazza is

particularly good for these types of questions). A list of clarifications and

assumptions you can make will be maintained.

Appendix A: Sprites

For context: Sprites are images. In a game sense, they're images that float above others (like

ghosts or sprites, hence the term, sprites). In the context of our: our characters use sprites

which float above the background of the game. So each character has "sprites" and each

"sprite" is a frame for an animation.

If you're not familiar with animation frames: imagine you have a bunch of images. You flip

through each of them, and when played sequentially, they make an animation. If you go

through the images in the sprites folder, you'll be able to run through the sprites and see that,

when played sequentially, an animation is formed.

● As an example of what get_next_sprite() should return: Let's say you have a new

Mage.

● The first time you call get_next_sprite() it should return mage_idle_0

● The second time you call get_next_sprite() it should return mage_idle_1

● Continue in this way for each call, up until you return mage_idle_9

● The next call to get_next_sprite() should start back at mage_idle_0

● Suppose your mage calls attack(). Then the next call to get_next_sprite() should be

mage_attack_0

● The call after will return mage_attack_1

● And so on until mage_attack_9 (unless another call to attack() or special_attack()

happens, in which case you go to their animation at frame 0)

● Then the next call will return mage_idle_0

● The call after returns mage_idle_1

● And suppose we call special_attack(). Then the next call to get_next_sprite()

should return mage_special_0

● And so on until mage_special_9

Here's a visual guide for reference (the dotted arrows are jus omitting frames 2 ~ 8 for space).


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp