Pokémon zijn fictieve wezens die gevangen en getraind worden door mensen — in deze context Pokémon Trainers genaamd — om ze dan voor de sport tegen elkaar te laten vechten. Tijdens zo een gevecht kan een Pokémon die aanvalt een slag (技 waza) uitdelen aan zijn tegenstander om daarmee diens hoeveelheid HP (health points) tot nul te proberen herleiden, waarop de Pokémon bezwijkt (ひんし hinshi).
Het type (タイプ taipu) van een Pokémon is een belangrijke eigenschap die aangeeft wat zijn sterke en zwakke punten zijn. Het is een bepalende factor voor de effectiviteit van de slagen die hij aan tegenstanders kan uitdelen, als een soort uitbreiding op de onderlinge verhoudingen tussen de symbolen gebruikt bij het spelletje blad-steen-schaar. Het schoolvoorbeeld van deze onderlinge verhoudingen zijn deze tussen Grass, Fire en Water types: Grass is zwak tegen Fire, Fire is zwak tegen Water, Water is zwak tegen Grass, maar elk zijn ze vrij goed bestand tegen de andere types. Sommige Pokémon zijn ook volledig immuun tegen bepaalde soorten aanvallen, zoals bijvoorbeeld het Ghost type dat immuun is tegen slagen van de types Normal en Fighting. Deze zwakheden, weerstanden en immuniteiten kunnen ook gecombineerd worden als een Pokémon meerdere types heeft.
Momenteel bestaan er 802 verschillende soorten Pokémon en zijn er 18 verschillende Pokémontypes. Onderstaande tabel geeft een samenvatting van hun onderlinge verhoudingen:
Bij een gevecht tussen twee Pokémon wordt diegene die een slag uitbrengt de aanvaller genoemd, en diegene die de slag incasseert de verdediger. Een slag heeft altijd een bepaald type en kan ofwel supereffectief zijn, gewoon, niet zeer effectief, of helemaal geen effect hebben op de verdediger. Deze vertalen respectievelijk naar een beschadigingsfactor van $$2\times$$, $$1\times$$, $$0.5\times$$ en $$0\times$$. Als een Pokémon meerdere types heeft, dan wordt de effectiviteit van een slag tegen die Pokémon bepaald als het product van de beschadigingsfactoren voor de individuele types.
We gebruiken tekstbestanden waarin de onderlinge verhoudingen van verschillende Pokémontypes vastgelegd worden. Elke regel van het bestand bevat drie informatievelden die telkens van elkaar gescheiden worden door een tab: i) een type aanval, ii) een type verdediger en iii) de beschadigingsfactor (een floating point getal) van een slag die het type aanval uitdeelt aan het type verdediger. Enkel slagen die afwijken van de gewone effectiviteit (beschadigingsfactor $$1\times$$) worden in het bestand opgenomen.
grass steel 0.5
steel rock 2.0
grass grass 0.5
dragon steel 0.5
fighting psychic 0.5
electric grass 0.5
ice ice 0.5
dark fighting 0.5
Gevraagd wordt om op basis van de informatie uit zo een tekstbestand, de effectiviteit te bepalen van een slag die wordt uitgedeeld aan een Pokémon die meerdere types kan hebben. Hiervoor ga je als volgt te werk:
Schrijf een functie beschadigingsfactor waaraan de locatie (str) moet doorgegeven worden van een tekstbestand waarin de onderlinge verhoudingen van verschillende Pokémontypes vastgelegd worden. De functie moet een dictionary (dict) teruggeven waarvan de sleutels gevormd worden door alle types aanvallen (str) die in het gegeven bestand voorkomen. Elk type aanval moet afgebeeld worden op een afzonderlijke dictionary (dict), die alle types verdedigers (str) uit het gegeven bestand afbeeldt op de beschadigingsfactor (float) van een slag die dat type aanval uitdeelt aan dat type verdediger.
Schrijf een functie effectiviteit waarmee de effectiviteit kan bepaald worden van een slag die wordt uitgedeeld aan een Pokémon. Aan deze functie moeten drie argumenten doorgegeven worden: i) het type van de slag (str), ii) de types van de verdediger (str; de verschillende types van de Pokémon worden telkens van elkaar gescheiden door één enkele spatie) en iii) de locatie (str) van een tekstbestand waarin de onderlinge verhoudingen van verschillende Pokémontypes vastgelegd worden. De functie moet de effectiviteit (float) van de slag teruggeven. Hierbij moet rekening gehouden worden met het feit dat als een Pokémon meerdere types heeft, de effectiviteit van een slag tegen die Pokémon bepaald wordt als het product van de beschadigingsfactoren voor de individuele types, en het feit dat slagen tussen individuele types met beschadigingsfactor $$1\times$$ niet expliciet in het gegeven bestand vervat zitten.
In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand verhoudingen.txt1 zich in de huidige directory bevindt.
>>> beschadigingsfactor('verhoudingen.txt2') {'fairy': {'poison': 0.5, 'steel': 0.5, 'fire': 0.5, 'dark': 2.0, 'fighting': 2.0, 'dragon': 2.0}, 'fighting': {'fairy': 0.5, 'ghost': 0.0, 'steel': 2.0, 'flying': 0.5, 'ice': 2.0, 'poison': 0.5, 'bug': 0.5, 'normal': 2.0, 'dark': 2.0, 'psychic': 0.5, 'rock': 2.0}, 'steel': {'steel': 0.5, 'ice': 2.0, 'fairy': 2.0, 'electric': 0.5, 'water': 0.5, 'fire': 0.5, 'rock': 2.0}, 'ice': {'ground': 2.0, 'steel': 0.5, 'grass': 2.0, 'ice': 0.5, 'flying': 2.0, 'water': 0.5, 'dragon': 2.0, 'fire': 0.5}, 'water': {'ground': 2.0, 'fire': 2.0, 'grass': 0.5, 'water': 0.5, 'dragon': 0.5, 'rock': 2.0}, 'dark': {'ghost': 2.0, 'fighting': 0.5, 'dark': 0.5, 'psychic': 2.0, 'fairy': 0.5}, 'flying': {'steel': 0.5, 'bug': 2.0, 'fighting': 2.0, 'electric': 0.5, 'grass': 2.0, 'rock': 0.5}, 'grass': {'ground': 2.0, 'poison': 0.5, 'steel': 0.5, 'grass': 0.5, 'bug': 0.5, 'flying': 0.5, 'water': 2.0, 'fire': 0.5, 'dragon': 0.5, 'rock': 2.0}, 'rock': {'ground': 0.5, 'flying': 2.0, 'steel': 0.5, 'ice': 2.0, 'bug': 2.0, 'fighting': 0.5, 'fire': 2.0}, 'ground': {'poison': 2.0, 'steel': 2.0, 'fire': 2.0, 'bug': 0.5, 'flying': 0.0, 'electric': 2.0, 'grass': 0.5, 'rock': 2.0}, 'ghost': {'dark': 0.5, 'ghost': 2.0, 'psychic': 2.0, 'normal': 0.0}, 'poison': {'ground': 0.5, 'ghost': 0.5, 'steel': 0.0, 'poison': 0.5, 'fairy': 2.0, 'grass': 2.0, 'rock': 0.5}, 'fire': {'fire': 0.5, 'dragon': 0.5, 'ice': 2.0, 'steel': 2.0, 'bug': 2.0, 'water': 0.5, 'grass': 2.0, 'rock': 0.5}, 'normal': {'ghost': 0.0, 'steel': 0.5, 'rock': 0.5}, 'bug': {'ghost': 0.5, 'poison': 0.5, 'steel': 0.5, 'grass': 2.0, 'fairy': 0.5, 'flying': 0.5, 'fighting': 0.5, 'fire': 0.5, 'dark': 2.0, 'psychic': 2.0}, 'electric': {'ground': 0.0, 'grass': 0.5, 'electric': 0.5, 'flying': 2.0, 'water': 2.0, 'dragon': 0.5}, 'dragon': {'steel': 0.5, 'dragon': 2.0, 'fairy': 0.0}, 'psychic': {'fighting': 2.0, 'dark': 0.0, 'poison': 2.0, 'steel': 0.5, 'psychic': 0.5}} >>> effectiviteit('fire', 'grass', 'verhoudingen.txt3') 2.0 >>> effectiviteit('fighting', 'ice rock', 'verhoudingen.txt4') 4.0 >>> effectiviteit('psychic', 'poison dark', 'verhoudingen.txt5') 0.0 >>> effectiviteit('water', 'normal', 'verhoudingen.txt6') 1.0 >>> effectiviteit('fire', 'rock', 'verhoudingen.txt7') 0.5
Dankzij het wereldwijde succes van het spelletje Pokémon Go8, spande Pokémon in 2016 de kroon als meest gebruikte zoekterm in Google9.