1 Pokemon: Lets Go, Prolog!
Pokemon World needs your help to set things to rights. You will design an interface for Pokemon Trainers, so that they can create different Pokemon teams and simulate battles against other Trainers.
Pokemon is identical in the singular and plural. (Motivation)
2 Knowledge Base
In your knowledge base (pokemon data.pl), you have a list of predicates, pokemon stats, pokemon evolution, pokemon types, type chart attack and pokemon trainer. They are defned as follows:
pokemon stats(Pokemon, Types, HealthPoint, Attack, Defense). pokemon evolution(Pokemon, EvolvedPokemon, MinRequiredLevel). pokemon types(PokemonTypes). type chart attack(AttackingType, TypeMultipliers). pokemon trainer(PokemonTrainer, PokemonTeam, PokemonLevels).
- pokemon stats defines a Pokemon, and for each Pokemon, its types, base health points, attack and defense values are listed. Health points, attack and defense values are Pokemons base statistics or in other words, when the Pokemon is at level 0. pokemon stats(bulbasaur, [grass, poison], 45, 49, 49).
- pokemon evolution defines the evolution process for Pokemon that can evolve.
pokemon evolution(bulbasaur, ivysaur, 16).
- pokemon types defines all Pokemon types. This is just a single fact to show the order of types to be used in type chart attack.
pokemon types([normal, fire, water, electric, grass, ice, fighting, poison, ground, flying, psychic, bug, rock, ghost, dragon, dark, steel, fairy]).
- type chart attack defines a type, and for each type, attack multipliers against all types are listed. The ordering of the multiplier lists are the same with pokemon types.
type chart attack(grass, [1.0, 0.5, 2.0, 1.0, 0.5, 1.0, 1.0, 0.5, 2.0, 0.5, 1.0,
0.5, 2.0, 1.0, 0.5, 1.0, 0.5, 1.0]).
- pokemon trainer defines a Pokemon trainer, and for each Pokemon trainer, his/her Pokemon team and their levels are listed. pokemon trainer(ash, [pikachu, bulbasaur, charmeleon, squirtle], [45, 15, 28, 42]).
3 Game Mechanics
In this section we will explain important mechanics that you should consider while coding writing required predicates. It will also help you to understand the concept better. Do not make any assumptions or add new concepts that are not present here.
3.1 Leveling Up
Each Pokemon can be at any level. Level of a Pokemon has an effect on its statistics and evolution process. With every level a Pokemon gains 2 health points, 1 attack point and 1 defense point. For example; base values of health point, attack and defense for Balbasaur are 45, 49, 49 respectively. If we have a level 30 Bulbasaur then its values of health point, attack and defense will be 45+302 = 105, 49 + 30 1 = 79 and 49 + 30 1 = 79 respectively.
3.2 Evolution
When a Pokemon reaches its minimum required level for evolution it can evolve. However, it is not a compulsory action. So there can be Pokemon of any kind at any level (level 10 Charizard or level 50 Charmander are both possible situations). But, Pokemon trainers always make their Pokemon evolve before tournaments if possible (see pokemon tournament predicate).
3.3 Pokemon Types and Type Multipliers
All Pokemon creatures are assigned certain types. Each type has several strengths and weaknesses in both attack and defense. In battle, you should use Pokemon that have a type advantage over your opponent; doing so will cause much more damage than normal. Each Pokemon are assigned to at least one and at most two types.
A single-type advantage (for instance a Water-type Pokemon against a Ground-type Pokemon) will net you double normal damage. The advantages also stack up, so a double-type advantage (for instance a Water-type Pokemon against a Ground/Rock-type Pokemon) will net you quadruple damage. Conversely, a single- and double-type disadvantage will afflict half and a quarter normal damage respectively.
For more information and visual version of the type chart: Pokemon Types. (We are not using attack types in this project, so dont confuse yourself with attack types or STAB from the link.)
4 Gotta Catch Em All
In this section, we will explain the predicates that you need to write for this project. In the example queries, three dots () at the end of an output means that the output still continues and the displayed output is only the first part of the result.
4.1 find pokemon evolution(+PokemonLevel, +Pokemon, -EvolvedPokemon)
This predicate is to find the evolved version of Pokemon given its level. If there is no evolution, then EvolvedPokemon = Pokemon. Pokemon can evolve more than one time if it has enough levels.
Examples:
?- find pokemon evolution(40, charmeleon, EvolvedPokemon). EvolvedPokemon = charizard.
?- find pokemon evolution(50, charmander, EvolvedPokemon).
EvolvedPokemon = charizard.
Note: charmander lvl16 charmeleon lvl36 charizard.
?- find pokemon evolution(10, charizard, EvolvedPokemon). EvolvedPokemon = charizard.
?- find pokemon evolution(20, charmander, EvolvedPokemon). EvolvedPokemon = charmeleon.
4.2 pokemon level stats(+PokemonLevel, ?Pokemon, -PokemonHp, -PokemonAttack, -PokemonDefense)
This predicate evaluates the statistics of a Pokemon for the given level. With every level a Pokemon gains 2 health points, 1 attack point and 1 defense point. You can get the base statistics from pokemon stats.
Examples:
?- pokemon level stats(30, squirtle, PokemonHp, PokemonAttack, PokemonDefense).
PokemonHp = 104, PokemonAttack = 78,
PokemonDefense = 95.
?- pokemon level stats(10, blastoise, PokemonHp, PokemonAttack, PokemonDefense).
PokemonHp = 99, PokemonAttack = 113,
PokemonDefense = 130.
?- pokemon level stats(30, Pokemon, PokemonHp, PokemonAttack, PokemonDefense).
Pokemon = bulbasaur,
PokemonHp = 105,
PokemonAttack = PokemonDefense, PokemonDefense = 79;
Pokemon = ivysaur,
PokemonHp = 120,
PokemonAttack = 92,
PokemonDefense = 93; Pokemon = venusaur,
PokemonHp = 140,
PokemonAttack = 130,
PokemonDefense = 153;
Pokemon = charmander,
PokemonHp = 99,
PokemonAttack = 82, PokemonDefense = 73;
4.3 single type multiplier(?AttackerType, +DefenderType, ?Multiplier)
This predicate will be used to find single-type advantage/disadvantage multiplier. It can also be used to find types that achieves a given multiplier.
Examples:
?- single type multiplier(fire, grass, Multiplier).
Multiplier = 2.0;
?- single type multiplier(AttackerType, poison, 2.0).
AttackerType = ground;
AttackerType = psychic;
?- single type multiplier(AttackerType, ghost, Multiplier).
AttackerType = normal,
Multiplier = 0.0;
AttackerType = fire,
Multiplier = 1.0;
AttackerType = water,
Multiplier = 1.0;
AttackerType = electric, Multiplier = 1.0;
4.4 type multiplier(?AttackerType, +DefenderTypeList, ?Multiplier)
This predicate will be used to find double-type advantage/disadvantage multiplier. It can also be used to find types that achieves a given multiplier. DefenderTypeList can only have one item or two items.
Examples:
?- type multiplier(ice, [grass, ground], Multiplier).
Multiplier = 4.0;
?- type multiplier(AttackerType, [grass, ground], 4.0). AttackerType = ice;
4.5 pokemon type multiplier(?AttackerPokemon, ?DefenderPokemon, ?Multiplier)
This predicate will be used to find type multiplier between two Pokemon. It can also be used to find different attacker/defender Pokemon that achieves a given multiplier. If an attacker Pokemon has two types, then the Pokemon uses the type that gives the higher multiplier against the defender Pokemon.
Examples:
?- pokemon type multiplier(bulbasaur, geodude, Multiplier).
Multiplier = 4.0;
Note: bulbasaur (grass, poison), geodude (rock, ground); grass vs (rock, ground) Multiplier = 4.0, poison vs (rock, ground) Multiplier = 0.25 ; 4.0 > 0.25 4.0
?- pokemon type multiplier(AttackerPokemon, charizard, 4.0).
AttackerPokemon = geodude;
AttackerPokemon = graveler; AttackerPokemon = golem; AttackerPokemon = onix;
?- pokemon type multiplier(machop, DefenderPokemon, 0.25).
DefenderPokemon = butterfree;
DefenderPokemon = zubat;
DefenderPokemon = golbat;
?- pokemon type multiplier(psyduck, DefenderPokemon, Multiplier).
DefenderPokemon = bulbasaur,
Multiplier = 0.5;
DefenderPokemon = ivysaur,
Multiplier = 0.5;
DefenderPokemon = venusaur,
Multiplier = 0.5;
DefenderPokemon = charmander, Multiplier = 2.0;
4.6 pokemon attack(+AttackerPokemon, +AttackerPokemonLevel, +DefenderPokemon, +DefenderPokemonLevel, -Damage)
This predicate finds the damage dealt from the attack of the AttackerPokemon to the DefenderPokemon.
Damage = (0.5 AttackerPokemonLevel (AttackerPokemonAttack / DefenderPokemonDefense) TypeMultiplier) + 1 Examples:
?- pokemon attack(pikachu, 15, ekans, 12, Damage). Damage = 10.375.
?- pokemon attack(psyduck, 35, pikachu, 28, Damage). Damage = 23.38970588235294.
?- pokemon attack(golduck, 35, pikachu, 28, Damage). Damage = 31.1102941176470.
4.7 pokemon fight(+Pokemon1, +Pokemon1Level, +Pokemon2, +Pokemon2Level, -Pokemon1Hp, -Pokemon2Hp, -Rounds)
This predicate simulates a fight between two Pokemon then finds health points of each Pokemon at the end of the fight and the number of rounds. Each Pokemon attacks at the same time and each attack sequence count as one round. After each attack, health points of each Pokemon reduced by the amount of calculated damage points. When a Pokemons health points reach or drop below zero (HP <= 0), the fight ends.
Examples:
?- pokemon fight(pikachu, 15, ekans, 12, Pokemon1Hp, Pokemon2Hp, Rounds).
Pokemon1Hp = 11.872727272727257,
Pokemon2Hp = -3.25,
Rounds = 6.
?- pokemon fight(psyduck, 35, pikachu, 28, Pokemon1Hp, Pokemon2Hp, Rounds).
Pokemon1Hp = 4.0,
Pokemon2Hp = -2.558823529411761, Rounds = 4.
?- pokemon fight(golduck, 35, pikachu, 28, Pokemon1Hp, Pokemon2Hp, Rounds).
Pokemon1Hp = 85.3008849557522, Pokemon2Hp = -2.330882352941181, Rounds = 3.
?- pokemon fight(pikachu, 18, pikachu, 18, Pokemon1Hp, Pokemon2Hp, Rounds). Pokemon1Hp = Pokemon2Hp, Pokemon2Hp = -2.301724137931041, Rounds = 11.
4.8 pokemon tournament(+PokemonTrainer1, +PokemonTrainer2, -WinnerTrainerList)
This predicate simulates a tournament between two Pokemon trainers then finds the winner Pokemon trainer of each fight. Pokemon trainers must have the same number of Pokemon. Pokemon fights in order. First Pokemon of the first Pokemon trainer fights with the first Pokemon of the second Pokemon trainer, second Pokemon of the first Pokemon trainer fights with the second Pokemon of the second Pokemon trainer. A fight ends when a Pokemons health points drop below zero. At the end of the fight, Pokemon with more health points win the fight, so does the Pokemon trainer that owns the winner Pokemon. In case of a tie, PokemonTrainer1 wins. Important Note: Pokemon trainers force their Pokemon to evolve (if possible) before tournament fights to gain maximum efficiency. So you should check evolution status of each Pokemon.
Examples:
?- pokemon tournament(ash, team rocket, WinnerTrainerList). WinnerTrainerList = [ash, team rocket, team rocket, ash].
?- pokemon tournament(ash, misty, WinnerTrainerList). WinnerTrainerList = [ash, ash, misty, ash].
?- pokemon tournament(ash, brock, WinnerTrainerList). WinnerTrainerList = [brock, brock, brock, ash].
?- pokemon tournament(misty, brock, WinnerTrainerList). WinnerTrainerList = [brock, brock, misty, misty].
?- pokemon tournament(misty, team rocket, WinnerTrainerList). WinnerTrainerList = [team rocket, team rocket, misty, misty].
?- pokemon tournament(brock, team rocket, WinnerTrainerList).
WinnerTrainerList = [brock, brock, team rocket, team rocket].
?- pokemon tournament(ash, ash clone, WinnerTrainerList).
WinnerTrainerList = [ash, ash, ash, ash].
Note: ash clone is the clone of Ash (obviously). He has the exact same Pokemon team with Ash. Thus the fights are always end in a draw and we declare Ash, PokemonTrainer1, as the winner.
4.9 best pokemon(+EnemyPokemon, +LevelCap, -RemainingHP, -BestPokemon)
This predicate finds the best Pokemon against the given EnemyPokemon where the both Pokemons levels are LevelCap. Do not evolve Pokemon. We define the best Pokemon as the Pokemon with the most remaining health points after the fight.
Examples:
?- best pokemon(charizard, 42, RemainingHP, BestPokemon). RemainingHP = 144.17441860465118, BestPokemon = golem.
?- best pokemon(charmander, 4, RemainingHP, BestPokemon). RemainingHP = 123.99999999999997, BestPokemon = lapras.
?- best pokemon(charmander, 42, RemainingHP, BestPokemon). RemainingHP = 179.63934426229508, BestPokemon = lapras.
?- best pokemon(charmander, 88, RemainingHP, BestPokemon). RemainingHP = 237.7309644670051, BestPokemon = gyarados.
4.10 best pokemon team(+OpponentTrainer, -PokemonTeam)
This predicate finds the best Pokemon Team against the given OpponentTrainer where the levels of each Pokemon of our best Pokemon Team are the same with the corresponding Opponents Pokemon levels (e.g. Level of the first Pokemon of the best Pokemon Team is same with the level of the first Pokemon of the Opponent Trainer). Both Pokemon should be evolved according to their level before fighting like in the tournament. We define the best Pokemon as the Pokemon with the most remaining health points after the fight.
Examples:
?- best pokemon team(team rocket, PokemonTeam)
PokemonTeam = [wigglytuff, golem, zapdos, golem].
?- best pokemon team(ash, PokemonTeam)
PokemonTeam = [golem, mewtwo, gyarados, exeggutor].
?- best pokemon team(misty, PokemonTeam)
PokemonTeam = [lapras, lapras, exeggutor, exeggutor].
?- best pokemon team(brock, PokemonTeam)
PokemonTeam = [lapras, exeggutor, golem, mewtwo].
4.11 pokemon types(+TypeList, +InitialPokemonList, -PokemonList)
This predicate will be used to find every Pokemon from InitialPokemonList that are at least one of the types from TypeList.
Examples:
?- pokemon types([grass, flying, ground], [bulbasaur, charmander, charizard, gyarados, pikachu], PokemonList).
PokemonList = [bulbasaur, charizard, gyarados].
?- pokemon types([grass, poison], [bulbasaur, charmander, charizard, gastly, pikachu], PokemonList).
PokemonList = [bulbasaur, gastly].
4.12 generate pokemon team(+LikedTypes, +DislikedTypes, +Criterion, +Count, -PokemonTeam)
This predicate generates a Pokemon team based on liked and disliked types and some criteria. This team can only have Pokemon from LikedTypes and cant have Pokemon from DislikedTypes. The predicate sorts Pokemon according to one of the three criterion in descending order: health points (h), attack (a), defense (d). Then selects Count number of Pokemon that have highest values in the selected criterion. If two or more Pokemon has the same value, the order is not important between these Pokemon.
Examples:
?- generate pokemon team([dragon, fire, ghost, ice], [flying, ground, rock], a, 4, PokemonTeam).
PokemonTeam = [[cloyster, 50, 95, 180], [magmar, 65, 95, 57], [lapras, 130, 85, 80], [dragonair, 61, 84, 65]].
?- generate pokemon team([fire, water, electric], [psychic, dragon], h, 4, PokemonTeam). PokemonTeam = [[lapras, 130, 85, 80], [gyarados, 95, 155, 109], [zapdos, 90, 90, 85], [moltres, 90, 100, 90]].
?- generate pokemon team([fire, water, electric], [psychic, dragon], a, 4, PokemonTeam). PokemonTeam = [[gyarados, 95, 155, 109], [charizard, 78, 104, 78], [blastoise, 79, 103, 120], [moltres, 90, 100, 90]].
?- generate pokemon team([fire, water, electric], [psychic, dragon], d, 4, PokemonTeam).
PokemonTeam = [[cloyster, 50, 95, 180], [blastoise, 79, 103, 120], [gyarados, 95, 155, 109], [shellder, 30, 65, 100]].
5 Efficiency
Your code should run under thirty seconds for all the test cases collectively.
6 Documentation
You will be graded for the readability of your code, so dont skip steps or make your code complex, write as clear as possible. You will also be graded for the documentation of your code, so explain what each predicate is for in comments in your code. No extra documentation.
7 Submission
You are going to submit just one file named pokemon.pl to Moodle. First four lines of your pokemon.pl file must have exactly the lines below, since it will be used for compiling and testing your code automatically:
% name surname
% student id
% compiling: yes
% complete: yes
The third line denotes whether your code compiles correctly, and the fourth line denotes whether you completed all of the project, which must be no (without quotes) if youre doing a partial submission. This whole part must be lowercase and include only English alphabet.
Also you must include pokemon data.pl in your code. Do not copy paste the contents of pokemon data.pl into your code file pokemon.pl.
8 Tips for the Project
- Try to formalize the problem, then try to convert the logic formulate to Prolog.
- You can use findall/3, bagof/3 or setof/3. Be careful when using bagof/3 and setof/3, and remember to set which free variables to ignore.
- Pay attention to the prefixes of the arguments in predicates which determines if the argument is a free variable or not (+, -, ?).
- You can use extra predicates for listing all the Pokemon or removing lists etc., but the ones given above are compulsory.
- Try to build complex predicates over the simpler ones, the project is designed to encourage that. If a predicate becomes too complex, either divide it into some predicates, or take another approach. Use debugging (through trace/1 and spy/1), approach your program systematically.
Reviews
There are no reviews yet.