联系方式

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

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

日期:2024-03-19 09:31

Assignment 1.1 - Pocket Monsters

Key Information

Your Task

This is an individual open-book home assignment. It involves interacting with a game that is broken

up into a set of programming questions. We provide a small set of tests to allow you to check the

correctness of your solutions. However, these tests are not exhaustive, and passing the tests does not

guarantee full marks. You should perform your own testing to ensure your solution is coded

correctly.

The code scaffold can be found here.

DO NO FORK THE REPOSITORY. Please use the 'Use Template' button instead. Anyone that FORKS could be in

breach of Academic Integrity and liable for penalties that apply.

Mark Value

The assignment is worth 100 marks. 50 marks are for the code. 50 marks are for an individual

written test of your knowledge of the theory, to be conducted during Week 6

Due Date

The code part of the assignment is due on Thursday Week 5 (28 March 2024 11.55 PM Melbourne

time for Clayton students, 11.55PM MA time for Malaysian students)

For Malaysian Students - Since we can't extend the deadline for Malaysian students, any

submission made in the last 3 hours of the deadline will be marked as late on Ed, but will not be

considered late. Please ignore the message.

Submission

The final submission of the assignment is to be done through Ed. See this post for details on how to

submit.

Assessment Criteria

Please check the rubric for the assessment criteria

Late Penalty

10% deduction per calendar day or part thereof for up to one week

Submissions more than 7 calendar days after the due date will receive a mark of zero (0) and no

assessment feedback will be provided.

Generative AI tools cannot be used in this assessment task: In this assessment, you must not use generative

artificial intelligence (AI) to generate any materials or content in relation to the assessment task.

Welcome to A1.1 - Pokemon!

Welcome to the wonderful world of Pokemon. Pokemon Battles is a game played between teams of

opposing pokemon in an attempt to see who is the very best, like no one ever was! Pokemon have

stats like attack and defense, can evolve into other monsters, and level up.

In this assignment you'll be working on many of the features of the Pokemon Battles game, which

should also test you on your ability to apply the concepts covered in the first 4 weeks of

Fundamentals of Algorithms.

But, this is too easy! To make sure you are demonstrating all of the topics covered in this unit, the

following restrictions are in place.

Any use of python inbuilt lists, dictionaries, sets, etc. Is banned. Use of such structures nulls

both the test case and approach marks for the affected task. You can however use fixed

size tuples. (Please also read the FAQ announcement in the Forum.)

Accessing the internals of the data_structures classes outside of the definition of the class is

strictly prohibited (You can't access .array of CircularQueue for example, only interact with

its methods)

Not only does your code need to be functional, it needs to be the most efficient choice that is

best suited for the problem. In general, if there is a choice that is efficient and requires less

code, not choosing this will lose you marks (So don't use an array when a queue would also

work).

With all that in mind, make sure to read the next slide for a bunch of small tid-bits and we hope you

enjoy this assignment!

Important Information, Tips and Tricks

Important Information, Tips and Tricks

Before you get working on the application, please read these tips & tricks to ensure you don't get lost,

or lose any silly marks!

Common Mistakes / Advice

Except for task 1, Every method you implement requires complexity analysis in the

docstring. This should include both best and worst case analysis!

Be sure to state your variables

You can include a catch all at the top of your class definition to avoid writing constant time for a

bunch of methods. "Unless stated otherwise, all methods in this classes are O(1) best/worst

case."

You are marked on correctness in Ed. It doesn't matter if your code passes locally, it needs to

pass in Ed. Contact a TA if you are having trouble achieving parity.

Be careful of the specific Python version used, and don't import any other third party modules.

Separate your code into small methods of at most 20 lines, and try to abstract logic if you

find lots of duplicated work.

Running Tests

To run tests, call python3 run_tests.py . Note that you can restrict which tests are run using a

second argument. For example, running python3 run_tests.py 1 will only run tests from the

tests/test_task1 file. Note: this will bypass the need to manually enter the task number via the

prompt.

Basic Introduction to Pokemon Battles

Basic Premise

Pokemon

The titular Pokemon are the backbone of the Pokemon Battles. There are different types of pokemon

each with their own names and stats, and one type of pokemon can evolve into another type of

pokemon when they level up.

Pokemon have the following information:

Health

Level

Defence

Type

Battle Power (attack points)

Name

Evolution Line

Experience

Speed

These stats will be covered over the future tasks but here is a short overview of each of them:

1. Health - This is the stat that lets you know how many health points a Pokemon has before it faints.

Once the Pokemon gets attacked, it loses some health and once the health drops to 0, the Pokemon

faints

2. Level - This stat refers to the level that the Pokemon is on. Once a Pokemon battles another and

makes it faint, the level of the Pokemon goes up by 1, boosting most of its other stats.

3. Defence - This stat refers to the resistance that is offered by the Pokemon when it gets attacked.

You will learn more about the use of this stat when we discuss battling.

4. Type - A Pokemon's type affects the amount of damage it can do to another Pokemon. You will

learn more about this in Task 1.

5. Battle Power - This stat refers to the amount of base damage a Pokemon does to another during

the course of a battle.

6. Name - This refers to the name of the Pokemon

7. Evolution Line - This is a list of the Evolution names for this line of Pokemon. The length of this list

can vary as many Pokemon don't evolve, evolve once or even twice in some cases!

8. Experience - This stat refers to the experience that a Pokemon has. A pokemon gains experience

from battling another pokemon.

9. Speed - This stat refers to the speed of the Pokemon. Speed determines how fast the Pokemon is

and the faster Pokemon attacks first.

What is PokemonBase?

Because there are over 70 Pokemon to define, and we don't want to write out all the classes

individually. In particular, because almost all of the logic for all Pokemon are the same, all we have to

do is define this shared logic in PokemonBase . Then Pokemon.py creates different classes, which all

inherit from PokemonBase , and implements all of the abstract class methods at the bottom of

pokemon_base.py .

For example, you can do the following without touching the assignment and it works just fine:

from pokemon import Charmander, Gastly

charmander = Charmander()

gastly = Gastly()

print(charmander.get_name()) # Charmander

print(charmander.get_poketype()) # PokeType.FIRE

print(gastly.get_evolution()) # ['Gastly', 'Haunter', 'Gengar']

Teams

Pokemon are combined to form teams, which are used in battle. There are multiple options for

teams, such as the team mode, and selection mode, but these will be covered in more detail in task 3.

Battling

Battling is done between two teams in a turn-based manner, where every "turn" includes an action

from both teams. In a battle, each team selects one Pokemon to be currently out on the field, while

the rest of each team waits to help out.

Battle anatomy

In a battle, turns continue to occur until one or both teams have no more pokemon left (in the team

and on the field). If a pokemon on the field is killed (HP <= 0), then a new pokemon from the team is

sent out at the end of the turn.

Turn anatomy

In a Battle turn, each team selects an action, either ATTACK , SPECIAL or SWAP . If SWAP is chosen, the

currently out-on-the-field pokemon is returned to the team, and a new pokemon from the team is

selected (possibly the same pokemon). If SPECIAL is chosen, the pokemon is returned to the team,

the method .special() is called on the team object, and a pokemon is retrieved from the team

(possibly the same pokemon). If ATTACK is chosen, then the currently out-on-the-field pokemon

attacks the currently out-on-the-field pokemon for the other team.

Two things to note:

1. SWAP / SPECIAL actions are always completed before ATTACK actions

2. If both teams ATTACK , then some special logic occurs:

The pokemon with the higher speed stat attacks first. If the slower pokemon is still alive after this (HP

> 0), then it can attack in retaliation. If the speed stat of both pokemon is equal, then both pokemon

attack simultaneously, ignoring whether the attack they are receiving would kill them.

The process of pokemon attacking pokemon is defined as follows:

Step 1: Compute the damage

This is done by comparing pokemon1's attack (call it attack ) and pokemon2's defense (call it

defense ).

If defense < attack / 2 : damage = attack - defense

Otherwise, If defence < attack : damage = ceil(attack * 5/8 - defense / 4)

Otherwise, damage = ceil(attack / 4)

Step 2: Apply multipliers

When two Pokemon attack, the element of each Pokemon is considered. For example, Squirtle is a

Water Elemental Pokemon, where as Charmander is a Fire Elemental Pokemon. Since Water has an

effectiveness coefficient of 2 against Fire, this is used to multiply by the calculated damage:

effective_damage = damage * 2

Then, you apply the trainer's Pokedex completion multiplier, which can be obtained as a ratio

between the attacking trainer's Pokedex completion vs the defending trainer's Pokedex completion.

This is discussed in detail (and will make more sense once you read) Task 3 and the Battle Logic slide

effective_damage = effective_damage *

(attacking_pokedex_completion/defending_pokedex_completion)

Step 3: Get the ceiling of the effective_damage

Since at this point the damage may have a decimal component, round this number up.

Step 4: Deduct HP from pokemon2 equal to the effective_damage.

Note: During defense pokemon2 might reduce the effective_damage by half.

Leveling up

If at the end of a turn, one Pokemon is alive and the other is not, then the alive Pokemon levels up.

This may change the Pokemon's stats, and if they have an evolution, will force the Pokemon to

evolve.

When leveling up the difference between a Pokemon's max hp and current hp must be maintained.

Evolution

Some Pokemon types can evolve into other Pokemon types. The PokemonBase method

get_evolution will tell you whether this Pokemon type can evolve. If the pokemon cannot evolve,

the returned list only contains the Pokemon itself. Otherwise, the returned value is a list of its

evolution names. For example Charmander.get_evolution() == ['Charmeleon', 'Charizard'] .

However, for a Pokemon (object) to evolve in battle, the following must be true:

The Pokemon type must be able to evolve ( get_evolution is returns just the current

Pokemon's name instead. i.e. - it doesn't have an evolution)

The Pokemon must be a different level from the one it originally started as

To evolve a Pokemon, the evolve method is called. The evolve method modifies the current object,

changing its stats and upgrading the Pokemon to its new evolution.

Battle Tower

The Battle Tower is a battle feature where one team faces a gauntlet of other teams in succession, and

is covered in more detail in Task 4.

[TASK] Element Effectiveness + Pokemon Base

We are going to set up the Element effectiveness in this task. All your work will be in the

pokemon_base.py file.

For starters, you have been given a file called type_effectiveness.csv which contains a table

defining the type effectiveness for each type against each other.

Your job in this task is to:

populate the EFFECT_TABLE in the TypeEffectiveness class. Some of the code has already

been done for you so you need to complete the rest.

complete the method get_effectiveness which returns a float based on the attacking and

defending types supplied as arguments to the method.

Make sure to set up the table correctly. One example is that get_effectiveness(PokeType.WATER,

PokeType.GRASS) should return 0.5

Additionally, have a look at the PokemonBase class. Most of these methods have already been done

for you, however, you will need to implement the following:

_evolve : This method will evolve the Pokemon. You don't need to check if the pokemon needs

to evolve as this is done in the level_up method. However, what you need to do is to:

change the name of the pokemon to the next in the evolution line

set the battle power, health, speed and defence to 1.5 times what it currently is set to

attack : This method will return the attack points when this Pokemon is battling. This method

should return the product of the Pokemon's current attack damage and the type effectiveness

of the Pokemon vs the type of the defending Pokemon

Think carefully about the data structure that you are going to use in this task!

[TASK] Poke Team

A reminder that use of inbuilt lists, dictionaries, sets are banned, and using less suited data structures will

result in loss of marks.

For methods that differ in complexity based on the team mode selected, please include separate complexity

analysis for all 3 team modes (For example, O(1) best/worst for FRONT, O(1) best/worst for BACK,

O(n^5log(n!)) for OPTIMISE)

Now that we have Pokemon and can create them and view stats, it's time to group them into a team,

in preparation for our battles!

You will be working on the file poke_team.py

Teams are a bit complicated, and have a few different creation options, so we'll go through all the

details here.

What is a Team?

A team is an ordered collection of Pokemon, with an upper limit on the total number of monsters

contained (this is currently set at 6, but you should design your code so that this limit is easily

adjustable)

Team should have the following instance variable, although you can have more:

self.team to store the team that the trainer has

Teams have the following methods:

__init__ , to initialise the team. This SHOULD NOT take any additional arguments. However, if

you are adding some arguments, you should provide default values for them so they don't fail

the tests.

choose_manually , to let the user choose upto 6 Pokemon. Please note that the user should

have an option to choose less than 6 Pokemon if they choose to do so

choose_randomly , to generate a team randomly chosen Pokemon. This should be equal to the

TEAM_LIMT (normally 6).

regenerate_team(battle_mode, criterion=None) , to heal all of the pokemon to their original

HP while preserving their level and evolution. This should also assemble the team according to

the battle mode (discussed later)

assemble_team , to place your pokemon in the appropriate ADT when a battle mode is selected

(you will need to leave this empty right now but you will fill this in later in the next task)

special , which takes different effects based on the type of battle, which will be covered in the

next task

__getitem__ , to retrieve a Pokemon at a specific index of the team

len(team) , should return the current length of the team

str(team) , should print out the current members of the team with each member printed in a

new line

In a battle, Pokemon will be retrieved from the team and used in battle. If a Pokemon is swapped out,

then it is added back into the team.

What is a Trainer?

A trainer is the holder of a Pokemon team. The trainer has a name, a team and a Pokedex. A Pokedex

registers if a trainer has seen a particular pokemon, wether it be in their own team or during battle.

The class Trainer should have the following methods:

__init__ , which should take the name as an argument and set the Trainer's name, initialise a

new PokeTeam and also a Pokedex.

pick_team , which should pick a team based on the mode that is supplied to the method as an

argument. Pick team can only have the values 'Random' or 'Manual'. You should return an error

if one of these options is not chosen

get_team , which should return the current PokeTeam

register_pokemon , which should register a pokemon (by its PokeType ) as seen on the trainer's

Pokedex

get_pokedex_completion , which should return a rounded float ratio of the number of different

TYPES of pokemon seen vs the total number of TYPES of pokemon available rounded to 2

decimal points. For this point, two FIRE type pokemon count as the exact same

str(trainer) , should return a string of the following format: Trainer <trainer_name>

Pokedex Completion: <completion>%

You need to convert your pokedex completion to a percentage here by multiplying it by 100

Battle Logic

Commencing The Battle

After being positioned, the teams battle. Battling involves attacking and defending, after which HP is

lost according to the attack stat and the damage after being attacked stat. Remember to use the

Pokedex multiplier here!

The battle begins with the first Pokemon of each team (positioned in the right order) getting into

battle. The battle between two units (say P1 and P2) proceeds as follows:

If the speed of unit P1 is greater than that of P2, P1 attacks and P2 defends.

If the speed of unit P2 is greater than that of P1, P2 attacks and P1 defends.

If the speeds of P1 and P2 are identical, then both attack and defend simultaneously, regardless

of whether one, or both, would faint in combat. Alternately after this initial attack, if the

defending Pokemon has not fainted (that is, it still has HP > 0), then they will retort with their

own attack to the first Pokemon. Once this has happened, there can only be three scenarios:

One of the two Pokemon faints. In this case, the other Pokemon gains 1 level. The other

Pokemon then goes back to the team.

Both Pokemon faint. In this case, we just leave their carcasses on the battlefield and move on.

Both Pokemon are still alive after they have attacked each other. In this case, they both lose 1

HP. If they are still alive after losing this 1 HP, they are sent back to their teams. If a Pokemon

faints here due to losing this 1 HP and the other Pokemon is alive, such a Pokemon still gains 1

level.

Battle Multipliers

As you may remember, in Pokemon Base, we used a multiplier based on the type of Pokemon that is

attacking and the type of Pokemon that is defending.

While battling, we are going to introduce another multiplier, which grows stronger with trainer

experience.

When you are attacking another pokemon, multiply the attack damage with the ratio between the

pokedex completion of the attacker vs the pokedex completion of the defender.

For example, if Pokemon p1 that belongs to the trainer t1 is attacking Pokemon p2 that belongs to

the trainer t2 then:

attack_damage = ceil(p1.attack() * (t1.get_pokedex_completion()/t2.get_pokedex_completion())

This attack damage can then be used in the defend method of the defending pokemon

Ending the Battle

The game ends when at least one of the teams is empty (i.e., it has no usable Pokemon).

[TASK] Battle!

A reminder that use of inbuilt lists, dictionaries, sets are banned, and using less suited data structures will

result in loss of marks.

Finally, we make it to the Battles :)

Battle Modes

Before we commence the battle class, we need to understand how battle modes work. There are

overall 3 battle modes available:

Set Mode

In a Set mode, we will follow a 'King of the Hill' style of combat. In this mode, a particular Pokemon

from one trainer's team keeps fighting until its fainted (health <= 0). The pokemon gains experience

and levels up the same if it is able to faint the pokemon from the other team, but it keeps fighting

until it is exhausted. Here is a representation of how this may occur:

Note: The initial composition of the team should be in reverse order. That is, the first Pokemon to battle

should be the last Pokemon that was selected.

You have been given certain Abstract Data Types (ADTs) in the data_structures folder, one of which

can be used for this task. Think about what you need to accomplish and then pick a suitable ADT.

Rotating Mode

We will now focus on the rotating mode for battle. In this mode, a Pokemon fights a round, and then

is sent to the back of the team, making the next pokemon in the party fight the next round. The battle

ends when at least one of the teams is empty. You should again choose one of the ADTs provided to

you to make this mode work the way it is intended.

Here is a pictorial representation of how this may look:

Optimised Mode

Now, things get a little interesting in the optimised mode! In this mode, the user gets to choose an

attribute to order their team. They can choose between Level, HP, Attack, Defence and Speed. This

order will be maintained throughout the battle, even when the stats change after each round. The

battle mode for this mode is 2. And, once again, you need to choose from the given ADTs and once

you have chosen a suitable ADT, you need to

You need to add a new method assign_team method to assign the order of the team based on the

chosen attribute.

Improvement to the PokeTeam

First and foremost, you will need to complete the assemble_team method in the PokeTeam class.

Now that you have chosen your prefered ADTs, you can finish off the functionality of this method.

You will need to replace the self.team attribute of the PokeTeam with your ADT of choice.

Next, complete the special method in the PokeTeam. Here are the details:

If special is called on a PokeTeam, the following should occur based on the battle mode:

SET MODE: If special is called during battle, this should reverse the first half of the team

ROTATE MODE: If special is called during battle, this should reverse the bottom half of the team

OPTIMISE MODE: it toggles the sorting order (from ascending to descending and vice-versa)

Implement the Battle class

Most of the battle logic has already been discussed in the Battle Logic slide so here are the basics of

the Battle class:

In battle.py , we have the Battle class, with which you'll need to implement the following

methods:

__init__ , which initialises the battling trainers, the battle mode, and the criterion; if

applicable.

_create_teams , which turns the PokeTeams from the two trainers into appropriate data

structures based on the mode supplied to the battle as an initial argument.

commence_battle , which calls the appropriate battle method from the 3 based on the battle

mode set in the initialiser. This method returns the winning trainer or None; in the case when

its a draw

[TASK] Battle Tower

A reminder that use of inbuilt lists, dictionaries, sets are banned, and using less suited data structures will

result in loss of marks.

The final task! In the monster battles game, what's better than a battle between two Trainers? Why

multiple of course!

In the battle tower, the player (with a team of Pokemon), faces a gauntlet of teams of Pokemon to

battle.

Each team (both the player's team and the enemy teams) have some amount of lives. The enemy

teams take it in turns to battle the player's team, and the result is either a win/loss or draw. The losing

team loses a life, and in the result of a draw both teams lose a life.

The order in which enemy teams face up against the player team is determined in the following

manner:

Some initial ordering for the enemy teams is decided.

After all enemy teams have fought the player team, then of the remaining enemy teams, those

with at least 1 life will fight the player again, following the same initial ordering as before.

Before every battle, regenerate_team is called on both teams to heal the entire team and

revive fainted monsters.

So for example, suppose we have 3 enemy trainers, A B and C, each with 2, 1 and 3 lives.

Then in the order of play, assuming that the player wins every battle:

1. We face trainer A, B and then C

2. We face trainer A, then C

3. We face trainer C

The battle tower ends when there are no enemy trainer lives left, or no lives left for the player team,

or both.

Your task is to implement the following functionality in tower.py :

BattleTower Class

__init__ method: Initialises the class.

set_my_trainer : Sets the player team for the battle tower, and generates between MIN_LIVES

and MAX_LIVES lives

generate_enemy_trainers : Randomly generates n enemy teams (n is passed as a parameter).

All teams must use selection_mode RANDOM and all battle are fought with battle mode

ROTATE. Generate each team a number of lives between MIN_LIVES and MAX_LIVES , after each

team is generated but before the next team is generated.

battles_remaining : Returns True if there are more battles to be had, False if either the player

or all enemy teams have ran out of lives.

next_battle : Simulates one battle in the tower, between the player team and the next enemy

team. Returns 5 values: The battle result, the player team, the enemy team, the player lives

remaining after the battle, and the enemy lives remaining after the battle.

enemies_defeated , you should keep a counter of the number of enemy lives taken by the

player, which this method should return

Code Rubric

1 Automatic Zoom

Code Submission

Submit your entire code assignment in the submission box below

Please follow the instructions here:

https://edstem.org/au/courses/14293/discussion/1768539

Changelog

Changes implemented with the date of implementation

01/03/2024

[pokemon.py] get_all_pokemon_types - renamed obj to cls, to make it clear that we are

returning Pokemon classes , not Pokemon objects .

[pokemon.py] Bulbasaur init / Electabuzz init - Fixed minor issues with these two

initialisers ( Bulbasaur and Electabuzz ).

[pokemon_base.py] Removed BattleMode - this class should only be defined in

battle_mode.py .

04/03/2024

Updated documentation for Evolution here.

08/03/2024

[Forum thread] - Updated attack multiplies in turn anomy (Step 2) under Basic

introduction in the assignment spec.

Released the test cases - see Announcement for more information

Updated Important Information on how to run the test cases.

11/03/2024

Task 2 - Task Description - Updated to the following:

Teams have the following methods:

__init__ , to initialise the team. This SHOULD NOT take any additional arguments.

However, if you are adding some arguments, you should provide default values for them so they don't fai[tests/test_task2.py] - Changed to PokeTeam.TEAM_LIMIT, rather than

poketeam.team_limit. Also, reset the TEAM_LIMIT to 6, otherwise, other test cases will fail

. The spec has been reflected in select_randomly() to suggest it should be equal to

TEAM_LIMIT rather than hardcoding it to 6.

[tests/test_task3.py - Test 3.1 | Test 3.2] - The two test cases for Task 3, had the wrong

result. Sorry!

[tower.py] next_battle - Updated Type Hinting to include 5 parameters instead of 4.

14/03/2024

[Forum thread] - Updated specification of Set Mode to indicate the first Pokemon to

battle.

[Forum thread] - Updated Test 3.1 to set the seed to ensure the team order is always the

same.

15/03/2024

Added note to Step 4 of turn anatomy and modified register_pokemon to include

PokeType .

[Forum thread] - Updated generate_enemy_trainers in the Battle Tower to include the

required parameter ( num_teams ).

16/03/2024

[Forum thread] - Updated spec to explain add assign_team for the optimised mode.

[Forum thread] - Minor changes to the wording of Battle logic and the attack method to

make it clearer.


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

python代写
微信客服:codinghelp