I have some code for a discord bot I am building that I want to make cleaner. Instead of writing a new if statement when a new enemy is made, I would like to check if a user input is already an enemy(class object) and then preform an action on that class object of the same name.
Below is the code for building an enemy.
class EnemyCreator:
type = 'enemy'
def __init__(self, name, enemy_type, health, ap):
self.name = name
self.enemy_type = enemy_type
self.health = health
self.ap = ap
info = (name ', ' str(health) ', ' str(ap))
npc_info.append(info)
And here is an example enemy:
skeleton = EnemyCreator('Randy Bones', 'skeleton', 100, 2)
I have an attack function:
def attack(enemy):
enemy.health = enemy.health - playerChar.ap
if enemy.health > 0:
playerChar.health = playerChar.health - enemy.ap
return ('You attacked ' enemy.name '. ' str(enemy.health) ' life remaining. \n'
enemy.name ' attacks back! You take ' str(enemy.ap) ' damage. You have ' str(playerChar.health)
' remaining!')
if enemy.health <= 0:
return enemy.name ' has been defeated!'
if playerChar.health <= 0:
return 'You died idiot.'
Then I have the input checked with this code:
async def on_message(message):
print(message.content)
if message.author != client.user:
if 'test' in message.content.lower():
print(npc_info)
if '!attack' in message.content.lower():
await message.channel.send(
attack(message.content[8::))
However, this causes an issue because the object passed into the attack(enemy)
function is a string, and I need it to be a class object. Any ideas on how to add this functionaliy?
CodePudding user response:
You should have a way of getting the existing enemies. I will propose something using an in-memory solution, but for a more robust/scalable solution, you should use a database (sqlite, Postgresql, Mysql), and for easy development, an ORM (SQLalchemy or Django).
An EnemyList would be:
class EnemyList:
def __init__(self):
self._enemies = []
def new_enemy(name, enemy_type, health, ap):
enemy = EnemyCreator(name, enemy_type, health, ap)
self.enemies.append(enemy)
return enemy
def find_enemy(name):
return next(filter(lambda enemy, enemy.name == name, self.enemies))
Then you would need to change your on_message
function to use it
async def on_message(message):
print(message.content)
if message.author != client.user:
if 'test' in message.content.lower():
print(npc_info)
if '!attack' in message.content.lower():
await message.channel.send(
attack(EnemyList.find_enemy(message.content[8::)))
This is the short answer, I won't add here other advice because they are not related to the question but you can also check:
- String Formating
- OO -> The attack function maybe should be a method of a playerChar object?
- The DB thing I already spoke of.
CodePudding user response:
I found a solution. I have made a list of all enemy's along side their name. Then I return the index of the corresponding value to the enemies name. Below is what I came up with.
Enemy creation:
boss = EnemyCreator('Charles Hammerdick', 'boss', 10000, 200)
npc_list.append(boss)
npc_list.append(boss.name)
attack function:
def attack(enemy):
for thing in npc_list:
if str(enemy) in str(thing):
enemy = (npc_list[npc_list.index(thing) - 1])
enemy.health = enemy.health - playerChar.ap
if enemy.health > 0:
playerChar.health = playerChar.health - enemy.ap
return ('You attacked ' enemy.name '. ' str(enemy.health) ' life remaining. \n'
enemy.name ' attacks back! You take ' str(enemy.ap) ' damage. You have ' str(playerChar.health)
' remaining!')
if enemy.health <= 0:
return enemy.name ' has been defeated!'
if playerChar.health <= 0:
return 'You died idiot.'