1

I'm currently making a game for CompSci class, and I want to shorten our random monster fights. Is there a way to make it so when I call a def I can change the name depending on a random variable? This is the snippet I'm talking about

Loop = True
        MonsterType = random.randint(1,20)
        Monster*()
        battle()

I have

def Monster1
def Monster2
def Monster3
.
.
.
def Monster20

I want the * in the first snippet to be the variable MonsterType, is there a way to have it do that? I.e. When it runs, if MonsterType = 15, then it'll be Monster13() that's called.

  • 2
    I didn't quiet understand . Are you talking about inheritance? – rafaelc May 14 '15 at 16:52
  • 1
    Can you post your actual code and explain your problem a bit clearer? – SuperBiasedMan May 14 '15 at 16:53
  • I clarified a little. Basically the * will be a number determined by MonsterType. Just wondering if there was a way to make the number set the MonsterType, rather than a bunch of if and elif statements for each monster. –  May 14 '15 at 16:53
  • 2
    Create a base monster type then a bunch of monsters that inherit from it. Then make a array holding all your monsters. Then access a monster in the array with the random int you are generating. – marsh May 14 '15 at 16:54
  • I will note that what you generally want is *not* this, but a method that can produce a monster for you on demand. – Makoto May 14 '15 at 16:56

3 Answers3

2

Yes there is a way, Create a dictionary and map each function to an integer:

import random

def monster1():
    print "Hello monster1"

def monster2():
    print "Hello monster2"

def monster3():
    print "Hello monster3"

def monster4():
    print "Hello monster4"

d = {1:monster1, 2:monster2, 3:monster3, 4:monster4}

#When you need to call:
monsterType = random.randint(1, 4)
d[monsterType]()
ZdaR
  • 22,343
  • 7
  • 66
  • 87
  • 1
    I wouldn't even suggest `eval()` to someone who's unfamiliar with why it's a bad idea to begin with. it will only be dangerous. Perhaps say **Never use `eval()`** if anything :) – Torxed May 14 '15 at 16:57
1

After reading what you're trying to accomplish, I believe that using OOP is going to be better for your situation:

# A class for a bunch of monsters
class Mob(object):
    def __init__(self, num_monsters):
        self._num_monsters = num_monsters
        self._monsters = []
        for i in range(self._num_monsters):
            # randomly create a type of monster based on the number of monsters
            self._monsters.append(Monster(random.randint(0, self._num_monsters)))

# Each monster has a type that is attacks with
class Monster(object):
    def __init__(self, monster_type):
        self._type = monster_type

    def attack(self):
        print(self._type)

test = Mob(20)
James Mertz
  • 8,459
  • 11
  • 60
  • 87
1

sounds like you you use a bit of OOP. I would recommend:

class Monster(object):
  def __init__(self, name):
    self.name = name
  def do_work(self):
    print self.name

then create a manager that can generate n number of monster objects, and provide a static method that can manage what object to call:

class MonsterManager(object):
  monsters = []
  def call_monster(self, index):
    monsters[i].do_work()

with this, you can have a better useage, like so:

manager = MonsterManager();
manager.monsters.append(Monster('Monster1')
manager.monsters.append(Monster('Monster2')
# etc
# then call a single monster
manager.call_monster(i)
Nathan Tregillus
  • 6,006
  • 3
  • 52
  • 91