Sunteți pe pagina 1din 7

CmpE 260 Principles of Programming Languages

Smalltalk Project - Pokemon Game


Due Date: May 25, 2016 23:55 PM
I wanna be the very best, like no one ever was. Ash Ketchum

Introduction

In this project, you are going to implement a simple command-based Pokemon game. In order to
give a brief introduction, Pokemon is famous as a Japanese anime series which centered on creatures
called Pokemon and Pokemon trainers. Pokemon trainers try to catch Pokemons and train them
to battle each other and enter tournaments.
The anime series are parallel to the video games and there are lots of different version of Pokemon
video games. However, the differences between the versions of the games are mostly minor. In the
game, you play as a Pokemon trainer, try to catch Pokemons, train them and try to win the
tournament by battling other Pokemon trainers and earn badges.
For this project, you are going to implement a simple version of this game by coding with
Smalltalk, which is an object-oriented programming language. Although the original game consists
of various details and processes, the Smalltalk implementation will consist of a simple battle between
2 Pokemons. The aim of this project is learning the essence of objects and relations between different
objects depends on the messages sent.
You should use Pharo environment for implementing your Smalltalk project. Although there
are other Smalltalk environments available, using Pharo is a must for this project.

Classes

In Pokemon, there are several types of creatures such as grass, electric, ghost, water and so on.
Each of the types has different characteristics and attack types. For this reason, some types may
have advantage over the others. For instance, a water type Pokemon may have an advantage over a
fire type Pokemon.
Unit
PokemonMaster

Pokemon
ElectricType

FireType

RockType

GrassType

WaterType

AttackOnly YourOwnStrategy

Pikachu Voltorb Charmender Magmar Bulbasaur Oddish Geodude Onix Squirtle Krabby

Figure 1: Hierarchy of Pokemon Classes


For this project, you need to implement 5 different type of Pokemon classes, as shown by Figure
1. For each type, there are 2 different Pokemons. For example, Pikachu is a famous electric type
Pokemon, and Charmender is a nice example for fire type Pokemon.
Each type has different characteristics and features. On the other hand, 2 different Pokemons
belong to the same type may have different powers. For this project, each Pokemon will have 3

Table 1: Pokemons Features


Pokemon

HP

Attack

Defense

Pikachu

35

6-8

Voltorb

40

3-5

Charmender

39

5-8

Magmar

65

9-10

Bulbasaur

45

4-6

Oddish

45

5-6

Geodude

40

8-9

Onix

35

4-7

Krabby

30

10-11

Squirtle

44

4-7

different features, as shown by Table 1. One of them is HP (health points). If one of the Pokemons
HP reaches to 0 in a battle, it loses the game. The second feature is attack power. Each Pokemon
has different attack power and gives damage to its rival accordingly. This attack power may change
according to the type of its rival, which will be explained later. The last feature is defense, which
provides a mechanism for a Pokemon to decrease the received damage.
As seen, we have 5 different types and 2 Pokemon for each type. Table 1 presents you the features
of the Pokemons that you need to use in your Project. You may easily get that each Pokemons
attack is ranged. This means that the attack power changes randomly between the specified values.
More information will be given in the following sections.
On the other hand, there is a subclass of Unit class called PokemonMaster. Furthermore,
there should be 2 different subclasses of PokemonMaster. These subclasses consist of strategies.
This part is explained by Section 8 in detail.
For playing the game, you need to implement required classes for Pokemon types and Pokemons,
with the given features and 2 strategies mentioned by Figure 1.

Attack

The previous section shows that each Pokemon has a range of attack power. This means that,
when a Pokemon wants to attack, a random value between the provided range is selected as the
attack power.
As mentioned, type of the Pokemons have a direct influence on the battles. In your project, you
should use these features as exactly given below:
Electric type is weak against rock but powerful against water type.
Fire type is weak against water but powerful against grass type.
Grass type is weak against fire but powerful against water type.
Rock type is weak against water but powerful against electric type.
Water type is weak against electric & grass but powerful against rock & fire type.

This means that, the attack power depends on whom you are battling to. For example, if an
electric type battles against rock type, the attack power decreases but if it battles against water
type, its attack power increases.
If our Pokemon has a type disadvantage, the damage it gives to the enemy is this:
GivenDamage = (RandomAttackf orGivenRange 0.8) EnemyDef ense
If our Pokemon has a type advantage, the damage it gives to the enemy is this:
GivenDamage = (RandomAttackf orGivenRange 2) EnemyDef ense
The first think that you need to consider is taking a random number for attack power for a
Pokemon (with the provided ranges), than checking the types for both Pokemons and checking the
enemys defense point. These variables are the key points for calculating the damage given for an
attack.
There is a constraint on the given formulas. The minimum value of Given Damage is 1, which
means that if defense of enemy is higher than the measured attack, the given damage will be 1. For
example, suppose that (random attack value)*2 equals to 6 but the enemy has a defense value of 10.
This means that, given damage will be equal to 1, instead of no damage. The calculations should
be done with Integer values. If you come up with a float number, it should be rounded (6,4 = 6 but
6,6 = 7).
Another important point is, there is always 10% probability for a Pokemon to miss the attack.
This will be explained in the following sections.

Defense

Each Pokemon has a defense point in order to decrease the damage taken. These values are
provided by Table 1. However, it is possible to increase the defense points during the battle. The
following sections give detail about this.

Health Points (HP)

Health points (HP) are the indicator of the remaining conscious of the Pokemon. During battle,
attacks decrease the enemys HP and when one of the Pokemons HP decreases to 0, it loses the
game.

The Rules of the Game

Pokemon is a turn-based game. One of the players start the game (player1), and each player can
select only 1 action during its turn. There are 3 different actions that a player can take within the
turn:
Attack
Defense
Potion
When the game initializes, player1 start the game by taking the first action. The attack action
is simple as mentioned. When a player takes attack action, your code needs to calculate the given
damage and decrease that amount of damage from the other player (or Pokemon).However, for each
turn, there is a 10% probability that a Pokemon can miss the attack and the turn goes waste. You
should implement this feature and given probability applies for each of the turns for both players.
If the attack misses for a player, sorry that now it is the other players turn, you cannot try second
action in a single turn.
3

When defense action is taken, this means that the defense point of the player is increased by 1.
This may be a strategic action for some games in order to decrease the damage taken.
Potion is the last action. Each player has only 1 potion that can be used in any of the turns.
When a player uses potion, it fills its HP to the maximum provided to that Pokemon. For example,
if initial HP of a Pokemon is 50 and current HP is 2 after several turns, the potion usage makes the
HP increased to 50 again. It is important that each player can use potion only once during a battle.

GameController

Your project will have a central mechanism that controls the multitude of games between 2
Pokemon Masters. The details about Pokemon Masters will be given in the following section.
For constructing such mechanism, you need to implement a class named GameController.
This class will only have a have method which takes 2 different parameters for strategies and an
additional parameter which is explained below. Each of the first 2 parameters is the instance of
different strategies. When you execute this method, the implementation should run 200 different
games between strategies. For first 100 games, first Pokemon Master takes the first action and game
goes by and for the second 100 games, second Pokemon Master takes the first action and so on.
For each 100 games, each Pokemon battles with each Pokemon. Since there is 10 different Pokemon
selection for each master, there will be 10x10 games. Keep in mind that, Pikachu can battle against
Pikachu.
For instance, 1st game will be Pikachu vs. Pikachu, 2nd game will be Pikachu vs. Voltorb, 3rd
game will be Pikachu vs. Charmender, 11th game will be Voltorb vs. Pikachu and so on. Your
code should arrange matches for all possible combination for different strategies. As mentioned, for
the first 100 games, first strategist will take the first action and for the second 100 games, second
strategist will take the first action. In total, GameController will run 200 games consists of all
possible combinations, 2 times.
The name of the method should be: player1: strategist1 player2: strategist2 isSpecialAction: [true or false]
As mentioned, the first 2 paremeters are instances of strategies. The 3rd parameter is just a
boolean value, either true or false. For this project, you need to implement a special action in
addition to attack, defense, and potion. This special action will apply for all Pokemons, you do
not need to implement different special actions for each different Pokemons. Watch out that these
special actions should make sense. For example killing punch as a special action which gives
200000 damages instantly does not make sense. Again lets go back to the 3rd parameter. If you
give true for the 3rd parameter, this means that special action is allowed for 200 games. If 3rd
parameter is given as false, this means that controller does not let special action usage.
Here you can find the typical standard for starting the bunch of games sequentially. Watch out
that the method name and controller class name should be exactly like this.
How to start a game
|ash brock |
ash := AttackOnly new.
brock := YourStrategy new.
GameController player1: ash player2: brock isSpecialAction: true.
When you execute such a code block given above (AttackOnly etc. will be explained in the
following section), the controller automatically executes 200 games in total. At the end of 200
games, you should print out a statement like strategist1: 120, strategist2: 80 which indicates how
many games is dominated by which Pokemon Master.
The main point of GameController is managing the game and constructing the loops. The more
detail about how game proceeds will be given in the following section after introducing the strategies.

Strategies

As shown by Figure 1, you should implement a class called PokemonMaster which is a subclass
of Unit. Besides, there should be 2 different subclasses of PokemonMaster which defines 2 different
strategies for playing the game.
First of all, everyone should implement a subclass called AttackOnly. An instance of this class
takes attack action whatever the current state of the game is.
The second subclass of PokemonMaster will be your own strategy. The name of this subclass
should be Master[studentID] without any brackets. For this class, you need to come up with
different strategies for different possible states.
The previous section gives a simple example code block in order to run 200 games. Within that
method, at each turn (for a particular game), the GameController will inform the player about the
current state of the game.
The current state of the game includes these parameters and values:
enemy HP left
enemy type (e.g. fire)
enemy current defense value
enemy potion left
last action taken by the enemy
Actually, the controller stores these values for each player. However, for instance, when it is
player1s turn, it gives the current state of the player2 and when it is player2s turn, it gives the
current state of the player1. Thus, controller should track each players situation. At the first turn,
there will be no last action taken by the enemy so you can leave it blank only for the first turn.
Now lets take a look from the Pokemon Masters side. At each turn, it receives some values from
the controller and it should decide which action needs to be taken. In order to implement this, you
should create a method for Pokemon Master called getAction: currentState. As shown above,
current state will consist of 5 different values. In order GameController to store recent state at each
turn, you need to implement get methods for the variables mentioned. Also, define set methods
for GameController to decrease the HP of the Pokemon who receives damage or increase defense
who takes defense action.
After receiving the current state of the game (how is the enemys condition right now), this
method should return an action: attack, defense, or potion. In order to do that, at each turn,
GameController must send getAction message to the corresponding Pokemon Master and learn
which action is taken by that master. The return value of getAction can be a simple string (attack,
defense, potion).
If this method returns attack string, GameController should measure the given damage (you
have the formula) and set new HP to the Pokemon who just received a damage. The only thing that
strategist needs to do is deciding on the action, the rest is the responsibility of the GameController.
If getAction method returns defense, it should set the defense value of that Pokemon. If getAction
method returns potion, GameController should check whether it has a potion remaining. If does,
it sets the new HP (max HP) of that Pokemon. If does not, GameController selectes the action as
attack automatically and calculate the given damage. However, before leaving the check of potion
to the GameController, the corresponding strategy can check whether there is any potion left for it.
On the other hand, there should be another method for Pokemon Master called setPokemon:
aPokemon. This assigns a Pokemon at the beginning of each battle to the a Master after creating
an instance of that Pokemon. For instance, the GameController should behave something like this
at the first battle:

How to game proceeds


|ash brock |
pokemonFirst := Pikachu new.
pokemonSecond := Pikachu new.
attackStrategyInstance setPokemon: pokemonFirst.
yourStrategyInstance setPokemon: pokemonSecond.
action1 := attackStrategyInstance getAction: currentState. ....
Of course there should be some loops etc., the code only explains the functionality.
There are two conditions for finalizing a single battle. First of them is when HP of one of the
Pokemons will reach to 0. When HP of a Pokemon reaches to 0, GameController finalizes this battle
and starts a new one with another combination.
Also, each game consists of 40 steps. If none of the Pokemons HP reaches to 0 after 40 turns
(in total, not 40 turns for each), the battle ends, and the one with the higher HP wins that battle.
Shortly, the battle ends either when HP of one of the Pokemons reaches to 0 or after 40 turns
passed.
You do not print out the winner of a single battle. You just need to print the number of winning
of each strategist at the end of 200 battles.

Standards

Although the whole document gives you the exact formats of some classes and methods, this
section summarizes them all. Beside of these, you can implement other methods or required stuffs
in any method you want.
You must use Pharo as Smalltalk environment for implementing your project.
All the classes shown by Figure 1 should be exactly named like that (FireType, PokemonMaster, AttackOnly etc.)
If required, define constructors as abstract and leave the responsibility to the subclass.
The name of the class for the controller must be GameController.
The method name for GameController must be player1: player2: isSpecialAction:
You should calculate the given damage for an enemy at GameController. The potion check,
setting new variables after each action should be executed by GameController The classes
should only inform GameController about which action is taken according to the implemented
strategy considering the recent state of the game.
You must have 2 different strategies as subclasses of PokemonMaster. The first of them must
be AttackOnly which takes attack action whatevet the current state is. The other strategy
is your own strategy and the name of that class should be Master[studentID] without any
brackets.
There should be 2 methods for Pokemon Masters. First of them should be getAction: and
second of them should be setPokemon: .
You need to implement get-set methods for only required variables.
GameController must run 200 games for each execution. Each game ends after either one of
the Pokemons HP reaches to 0 or 40 turns. After 200 games end, the program should print
out (to the Transcript) which strategy wins how many games.

10

Submission Process

Your classes should be included in a new package. The name of your package should be
[StudentID] without the brackets. So that, when you export your package consists of your
codes, the exported file will be StudentID.st
It is obligatory to write comments for each of the class and instance methods.
You should group the methods under appropriate protocols.
Submit a zipped file on Moodle until the given deadline. The files that must be included in
the zipped file are:
StudentID.st
StudentID.txt which should include a couple of lines or paragraphs that explain how
to start the game. Then, this txt file should include a simple code block that shows how
to initialize the instances of the strategies and start the game.
The name of the zipped file should be [StudentID].zip without the brackets.
There will be no late submission. Be aware that, you need to submit all of the projects in
order to pass the course.
There will be demo sessions and you need to demo your applications. The period of demo
sessions will be announced. Each demo for a person will consist of 5 minutes.

S-ar putea să vă placă și