import kotlin.random.Random
open class Pokemon(val name: String, val type: String, val attacks: Array<String>) {
var healthPoints = 100
// Method Overloading - multiple methods with the same name but different parameters
fun attack(pokemon: Pokemon) {
val attackIndex = Random.nextInt(attacks.size)
attack(pokemon, attackIndex)
}
fun attack(pokemon: Pokemon, attackIndex: Int) {
val attack = attacks[attackIndex]
val damage = (0..50).random()
pokemon.healthPoints -= damage
println("$name used $attack and dealt $damage damage to ${pokemon.name}")
}
open fun isAlive(): Boolean {
return healthPoints > 0
}
}
class Pikachu(name: String, type: String, attacks: Array<String>) : Pokemon(name, type, attacks) {
override fun isAlive(): Boolean {
return healthPoints > 20 // Pikachu is stronger than other Pokemon
}
}
class Game {
val types = arrayOf("Fire", "Water", "Grass", "Electric")
val attacks = arrayOf("Tackle", "Thunder Shock", "Water Gun", "Vine Whip", "Ember", "Bubble")
fun generatePokemon(): Pokemon {
val name = "Pokemon${(1..100).random()}"
val type = types.random()
val pokemonAttacks = arrayOf(attacks.random(), attacks.random())
return when (type) {
"Electric" -> Pikachu(name, type, pokemonAttacks)
else -> Pokemon(name, type, pokemonAttacks)
}
}
fun play() {
for (i in 1..10) {
val pokemon1 = generatePokemon()
val pokemon2 = generatePokemon()
println("${pokemon1.name} (${pokemon1.type}) vs ${pokemon2.name} (${pokemon2.type})")
while (pokemon1.isAlive() && pokemon2.isAlive()) {
pokemon1.attack(pokemon2)
if (pokemon2.isAlive()) {
pokemon2.attack(pokemon1)
}
}
if (pokemon1.isAlive()) {
println("${pokemon1.name} wins!")
} else {
println("${pokemon2.name} wins!")
}
println()
}
}
}
fun main() {
val game = Game()
game.play()
}