It's a Pokemon battle! Your task is to calculate the damage that a particular move would do using the following formula (not the actual one from the game):

Where:

* attack = your attack power
* defense = the opponent's defense
* effectiveness = the effectiveness of the attack based on the matchup (see explanation below)

Effectiveness:

Attacks can be super effective, neutral, or not very effective depending on the matchup. For example, water would be super effective against fire, but not very effective against grass.

* Super effective: 2x damage
* Neutral: 1x damage
* Not very effective: 0.5x damage

To prevent this kata from being tedious, you'll only be dealing with four types: `fire`, `water`, `grass`, and `electric`.  Here is the effectiveness of each matchup:

* `fire > grass`
* `fire < water`
* `fire = electric`

* `water < grass`
* `water < electric`

* `grass = electric`

For this kata, any type against itself is not very effective. Also, assume that the relationships between different types are symmetric (if `A` is super effective against `B`, then `B` is not very effective against `A`).

The function you must implement takes in:
1. your type
2. the opponent's type
3. your attack power
4. the opponent's defense

Source: codewars | Difficulty: EASY
Tags: String algorithms

Data structures

Game theory

Ad-hoc

Starter code: def calculate_damage(your_type, opponent_type, attack, defense):
	

Solutions:
import math
effectiveness = {'electric': {'electric': 0.5, 'fire': 1, 'grass': 1, 'water': 2}, 'fire': {'electric': 1, 'fire': 0.5, 'grass': 2, 'water': 0.5}, 'grass': {'electric': 1, 'fire': 0.5, 'grass': 0.5, 'water': 2}, 'water': {'electric': 0.5, 'fire': 2, 'grass': 0.5, 'water': 0.5}}

def calculate_damage(your_type, opponent_type, attack, defense):
	return math.ceil(50 * (attack / defense) * effectiveness[your_type][opponent_type])


from math import ceil
D = {'fire': 'grass', 'water': 'fire', 'grass': 'water', 'electric': 'water'}

def calculate_damage(a, b, n, m):
	return ceil(50 * (n / m) * (2 if D[a] == b else 0.5 if D[b] == a or a == b else 1))


def calculate_damage(your_type, opponent_type, attack, defense):
	damage = 50 * (attack / defense)
	if your_type == opponent_type:
		return int(damage * 0.5)
	pairs = (('water', 'fire'), ('fire', 'grass'), ('grass', 'water'), ('electric', 'water'))
	e = 1
	for p in pairs:
		if your_type in p and opponent_type in p:
			if p.index(your_type) == 0:
				e = 2
			else:
				e = 0.5
	return int(damage * e)


from math import ceil
EFF = {('fire', 'grass'): 2, ('fire', 'water'): 0.5, ('grass', 'water'): 2, ('electric', 'water'): 2}

def calculate_damage(you, opp, attack, defense):
	k = (you, opp) if you < opp else (opp, you)
	eff = 0.5 if you == opp else EFF.get(k, 1) if k[0] == you else 1 / EFF.get(k, 1)
	return ceil(50 * eff * attack / defense)


def calculate_damage(your_type, opponent_type, attack, defense):
	types = {'fire': 0, 'water': 1, 'grass': 2, 'electric': 3}
	effectiveness = [[0.5, 0.5, 2.0, 1.0], [2.0, 0.5, 0.5, 0.5], [0.5, 2.0, 0.5, 1.0], [1.0, 2.0, 1.0, 0.5]]
	return 50 * (attack / defense) * effectiveness[types[your_type]][types[opponent_type]]


def calculate_damage(your_type, opponent_type, attack, defense):
	effectivnes_matrix = [[0.5, 0.5, 2, 1], [2, 0.5, 0.5, 0.5], [0.5, 2, 0.5, 1], [1, 2, 1, 0.5]]
	types = ['fire', 'water', 'grass', 'electric']
	effectivness = effectivnes_matrix[types.index(your_type)][types.index(opponent_type)]
	return 50 * (attack / defense) * effectivness


col = {'fire': 0, 'water': 1, 'grass': 2, 'electric': 3}
effects = [[0.5, 0.5, 2, 1], [2, 0.5, 0.5, 0.5], [0.5, 2, 0.5, 1], [1, 2, 1, 0.5]]

def eff(t1, t2):
	(x, y) = (col[t1], col[t2])
	return effects[x][y]

def calculate_damage(your_type, opponent_type, attack, defense):
	return 50 * (attack / defense) * eff(your_type, opponent_type)


import math

def calculate_damage(your_type, opponent_type, attack, defense):
	powerMap = {('fire', 'grass'): 2, ('water', 'fire'): 2, ('fire', 'electric'): 1, ('grass', 'water'): 2, ('electric', 'water'): 2, ('grass', 'electric'): 1}
	print((your_type, opponent_type, attack, defense))
	effectiveness = 0
	if your_type == opponent_type or ((opponent_type, your_type) in powerMap and powerMap[opponent_type, your_type] == 2):
		effectiveness = 0.5
	elif (your_type, opponent_type) in powerMap:
		effectiveness = powerMap[your_type, opponent_type]
	elif (opponent_type, your_type) in powerMap and powerMap[opponent_type, your_type] == 1:
		effectiveness = 1
	return math.ceil(attack / defense * 50 * effectiveness)