Seite 1 von 1
Problem beim Aufruf von Methoden
Verfasst: Donnerstag 7. Februar 2013, 17:15
von kevind
Hallo Zusammen!
In meinem Textgame soll der spieler verschiedene attacken auswählen können, diese sind mit einer ID und Name in einer Klasse/Instanz des Spielers gespeichert. Es existieren gleichnamige Funktionen zu den attacken welche ich durch eingabe des Users ausführen möchte.
Klasse des Spielers:
Code: Alles auswählen
class character():
def __init__(self, name, npc):
#character properties
self.npc = npc
self.name = name
self.level = 1
#character status values
self.strengh = 10
self.vitality = 100
self.defense = 5
self.dextery = 15
self.combat_experience = 100
#abilitys
self.attacks = {1: "Kick", 2: "Punch"}
#base damage
self.base_damage = int(self.strengh + (self.dextery / 3) +
(self.combat_experience / 10))
attacken:
Code: Alles auswählen
class Skills():
def __init__(self, character_instance):
self.chara = character_instance
def Punch(self):
self.punch_dmg = int(self.chara.base_damage + 10)
return self.punch_dmg
def Kick(self):
self.kick_dmg = int(self.chara.base_damage + 5)
return self.kick_dmg
Abschnitt der Skill auswahl:
Code: Alles auswählen
def attack(player):
# argument "player" is the character instance
atk_input = None
if player.npc is True: # check if "player" is a npc
atk_input = random.randint(1, 2)
elif player.npc is False: # check if "player" is a player
print("-----------")
for attack_id, attack_name in player.attacks.items():
print(attack_id, attack_name)
atk_input = int(input(prompt))
attack = player.attacks[atk_input] # name of the attack
Die ausgabe sieht ca so aus:
Angenommen der Spieler gibt 1 ein (somit steht in der Variable attacke nun "Kick"), dann möchte ich dass die methode player.Kick aufgerufen wird.
Ich möchte es einfach variabel halten und ewige if, elif,elif,elif vermeiden.
Hab bereits mit eval() versucht das player.attack irgendwie umzuwandeln aber ohne Erfolg.
Wäre um anregungen und Tipps dankbar.
Gruss, Kev
Re: Problem beim Aufruf von Methoden
Verfasst: Donnerstag 7. Februar 2013, 20:52
von cmax
z.B. so:
Code: Alles auswählen
class character():
def __init__(self, name, npc):
...
self.attacks = {1: attack('kick',5), 2: attack('punch',5)}
...
def attacks(self,opponent,attackNr):
a = self.attacks[i]
print a.name
opponent.vitality -= int(self.chara.base_damage + a.damage)
class attack():
def __init__(self,name,damage):
self.name
self.damage
...
Re: Problem beim Aufruf von Methoden
Verfasst: Donnerstag 7. Februar 2013, 22:16
von cofi
Warum stecken deine Attacken denn in einer Klasse? Du hast keinen echten geteilten Zustand auf dem die Methoden operieren.
Loest man es auf einfache Funktionen auf, kann man direkt die Funktionen benutzen:
Code: Alles auswählen
class Character():
....
self.attacks = [('Kick', lambda: self.base_damage + 5),
('Punch', lambda: self.base_damage + 10)]
....
for i, attack in enumerate(self.attacks, 1):
name, _ = attack
print("%d: %s" % i, name)
choice = int(input(prompt))
name, dmg_function = self.attacks[choice - 1]
....
Anstelle der Lambda Funktionen kann man natuerlich auch benannte nehmen .. oder gebundene Methodenobjekte, falls tatsaechlich so eine Skill Klasse noetig werden sollte.
Daneben sei dir PEP 8 empfohlen.
Re: Problem beim Aufruf von Methoden
Verfasst: Freitag 8. Februar 2013, 09:19
von kevind
Erstmals vielen dank das hat mich wirklich weitergebracht !
cmax hat geschrieben:z.B. so:
Code: Alles auswählen
class character():
def __init__(self, name, npc):
...
self.attacks = {1: attack('kick',5), 2: attack('punch',5)}
...
def attacks(self,opponent,attackNr):
a = self.attacks[i]
print a.name
opponent.vitality -= int(self.chara.base_damage + a.damage)
class attack():
def __init__(self,name,damage):
self.name
self.damage
...
Sollte vermutlich so aussehen:
Code: Alles auswählen
def attacks(self,opponent,attackNr):
a = self.attacks[[b]attackNr[/b]]
und problematisch ist noch das die methode
attacks und das attribut
attacks den selben Namen haben.
Denn wenn ich folgendes versuche:
Code: Alles auswählen
dude = character("dude", False)
dude.attacks(enemy, 1)
sagt er das dict object nicht callable ist. Denke er greift hier direkt auf das Attribut zu und nicht auf die Methode.
Wenn ich irgendwo falsch liege bitte sagt es mir.
@cofi
Ich habe deswegen die Attacken in eine Klasse eingebaut weil ich noch die Idee hatte den Attacken eine art "cooldown" und andere attribute zu verpassen, welche sozusagen abhängig davon sind welcher Character welche attacke wie oft ausführt. Wenn Character X attacke Punch 100 mal ausführt dann wird diese bei Character Y immer ineffektiver. Daher wollte ich die Attacken pro Character instanzieren.
Andererseits wusste ich nicht was besser ist, kann vermutlich auch nicht so weit vorausdenken da meine Python skills noch nicht so ausgeprägt sind und wenig Erfahrung vorhanden ist
Den Style guide habe ich mir schon angeschaut und versuche ihn vermehrt zu verwenden.
Lambda kenne ich noch nicht, werde mir das aber auch noch ansehen.
Gruss, Kev
Re: Problem beim Aufruf von Methoden
Verfasst: Freitag 8. Februar 2013, 20:13
von cmax
kevind hat geschrieben:Sollte vermutlich so aussehen:
...
und problematisch ist noch das die methode attacks und das attribut attacks den selben Namen haben.
Du hast beide Fehler im Suchquellcode gefunden.
Nein, sorry. Hatte es nur schnell ohne Test runtergetippt mit Fokus auf die Objekte im dict.

Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 14:27
von kevind
Hallo nochmals,
so ich habe nun etwas herumgespielt und möchte euch mein Resultat zeigen, mit bitte um feedback.
Meine Anforderungen waren:
Irgendwo werden alle Skills definiert (Hier in Dictionarys)
Jeder Charakter erhält eine liste mit erlernten/verfügbaren skills (Hier die Liste "autos" (könnte dann auch in der Klasse des Charakters stehen))
Skills können einfach aufgelistet werden und per Nummern eingabe verwendet werden.
Skills haben attribute wie zb. "Cooldown" die einzigartig pro Skills und Charakter sind. (Sobald die skills instanziert sind kann damit "schön" gearbeitet werden)
Stellt euch einfach vor das es keine Autos sondern Skills sind
ps: Gibts es eine andere Möglichkeit als "x = []" um "x" zu initalisieren ?
Code: Alles auswählen
class car(object):
def __init__(self, name, ps, sitze):
self.name = name
self.ps = ps
self.sitze = sitze
def ausgabe(self):
print(self.name, self.ps)
dict_opel = {"name:": "Opel", "PS:": 300, "sitze:": 4}
dict_mazda = {"name:": "Familywagen:", "PS:": 100, "sitze:": 5}
dict_porsche = {"name:": "Sportwagen:", "PS:": 500, "sitze:": 2}
dict_audi = {"name:": "Audi A8", "PS:": 500, "sitze:": 4}
autos = [dict_opel, dict_mazda, dict_porsche, dict_audi]
x = []
print("Wähle ein Auto")
for index, obj in enumerate(autos):
print(index, autos[index]["name:"])
x.append(car(obj["name:"], obj["PS:"], obj["sitze:"]))
auto = int(input(">>"))
print("Du steigst in den {0} ein und fährst davon", x[auto].name)
print("--"*10)
for index, car in enumerate(x):
print(index, car.name)
Danke euch !
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 14:37
von cofi
Code: Alles auswählen
class Car():
def __init__(self, name, ps, size):
self.name = name
self.ps = ps
self.size = size
def __str__(self):
return '%s %s' % (self.name, self.ps)
cars = [Car(*attr) for attr in [('Opel', 300, 4),
...
]]
print('Wähle ein Auto:')
for i, car in enumerate(cars):
print(i, car.name)
...
Warum noch das Dictionary, wenn du schon eine Klasse dafuer hast? `cars` ist nun übrigens dein `x` (Was davor auch schon redundant zu `autos` war)
PEP 8 sei dir immernoch empfohlen, was hier ganz nuetzlich ist das passende Programm:
http://pypi.python.org/pypi/pep8/1.4.2
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 14:53
von kevind
Ja den Style guide habe ich im Hinterkopf, habe aber leider wenig Zeit und meistens is die Lust zu coden grösser als den Guide zu lesen ... ich werde es aber bald machen, versprochen
Danke für den Link!
Hier wird meine Anforderung
- Irgendwo werden alle Skills definiert (Hier in Dictionarys)
- Jeder Charakter erhält eine liste mit erlernten/verfügbaren skills (Hier die Liste "autos" (könnte dann auch in der Klasse des Charakters stehen))
Aber nicht gedeckt, denn alle skills stecken in ´cars´. Oder übersehe ich etwas ?
Das Dictionary stellt alle verfügbaren Skills dar, in der Liste ´autos´ werden alle Skills zum jeweiligen Charakter gespeichert. (sollte wohl besser als Attribut in die charakter Klasse).
und mit der Klasse erstelle ich aus den beiden Informationen dann die Instanzen der einzelnen Fähigkeiten. So hätte ich jetzt den Sinn und Zweck des ganzen beschrieben.
**na super jetzt vermische ich Autos und Skills... kein Wunder wenn ich keine Antworten mehr bekomm

Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 14:59
von cofi
kevind hat geschrieben:Aber nicht gedeckt, denn alle skills stecken in ´cars´. Oder übersehe ich etwas ?
Ja, das (zugegeben abgekuerzte) Listen-Literal in der LC, die cars erstellt.
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 15:44
von kevind
Ja ich sehe die Liste, einen punkt habe ich noch:
hier habe ich noch die zuordnung der Skills für jeden Charakter, diese fehlt bei dir oder ?
Code: Alles auswählen
...
autos_dude = [dict_opel, dict_mazda, dict_porsche, dict_audi]
autos_enemy = [dict_porsche, dict_audi]
...
Und deine ´cars´ zuweisung macht das selbe wie meine for schleife "for index, obj..." nur kompakter oder ?
(was ist mit LC gemeint?)
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 16:28
von EyDu
kevind hat geschrieben:hier habe ich noch die zuordnung der Skills für jeden Charakter, diese fehlt bei dir oder ?
Das liegt daran, dass die Fahrzeuge nicht so viel mit einem Charakter zu tun haben

Dabei fällt mir auf: meinst du vielleicht Player und nicht Character? Und statt "enemy" meinst du wohl eher "opponent".
kevind hat geschrieben:Code: Alles auswählen
...
autos_dude = [dict_opel, dict_mazda, dict_porsche, dict_audi]
autos_enemy = [dict_porsche, dict_audi]
...
Hier siehst du auch gleich, warum das benennen nach Datenstrukturen (dict_*) ein schlecte Idee: Datenstrukturen ändern sich gerne mal, besonders bei dynamischen Sprachen wie Python und dann müsstest du alle Namen anpassen oder hast falsche Namen.
kevind hat geschrieben:Und deine ´cars´ zuweisung macht das selbe wie meine for schleife "for index, obj..." nur kompakter oder ?
Ja, bis auf Ausgabe.
kevind hat geschrieben:(was ist mit LC gemeint?)
List Comprehension
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 16:42
von kevind
Danke EyDu,
kevind hat geschrieben:Code: Alles auswählen
...
autos_dude = [dict_opel, dict_mazda, dict_porsche, dict_audi]
autos_enemy = [dict_porsche, dict_audi]
...
Hier siehst du auch gleich, warum das benennen nach Datenstrukturen (dict_*) ein schlecte Idee: Datenstrukturen ändern sich gerne mal, besonders bei dynamischen Sprachen wie Python und dann müsstest du alle Namen anpassen oder hast falsche Namen.
Was gibt es hier denn für möglichkeiten ? Irgendwas muss ich ja angeben woher die Daten kommen sollen, ob ich es jetzt direkt als Liste einfüge wie cofi das geschrieben hat:
Code: Alles auswählen
cars = [Car(*attr) for attr in [('Opel', 300, 4),
...
]]
Oder ich es über Dicts mache macht doch kaum ein unterschied.
Irgendwie dreh ich mich im Kreis :K
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 19:48
von cofi
EyDu meint damit, dass `dict_opel` ein schlechter Name ist, weil er aussagen soll, dass sich dahinter ein Dictionary verbirgt. Das ist in dem Moment zwar kein Problem, wenn du die Daten weiterhin als Konstante behandelst, bringt aber auch keinen Mehrwert. Zum Problem wird es aber ganz schnell als Name eines Argumentes in einer Funktion, wo sich der Name ganz schnell als "Luege" herausstellen kann.
Und dann haben wir noch ein Kommunikationsproblem: Du redest eine andere Sprache als diejenigen, die deine Posts lesen. EyDu hat es schon angeschnitten: Was haben jetzt die Autos mit dem anderen Kram zu tun? Sind die Autos deine "Charakter" oder deine "Skills"? Und was soll das jeweils andere sein?
Wenn du eine Loesung fuer dein eigentliches Problem haben willst, dann musst du uns auch das - und genau das - Problem schildern. Nicht ueber halbgare Analogien, die du dann selbst wieder vermischst.
Re: Problem beim Aufruf von Methoden
Verfasst: Dienstag 12. Februar 2013, 22:06
von kevind
Nochmals danke,
ja das ich hier mit den Autos angefangen hab war beschissen. Hätte das erst Thread bezogen umbauen sollen.
Generell sollte ich mir angewöhnen gleich ordentliche Namen zu verwenden und mich in Style Guide einlesen... würde glaube ich einige Missverständnisse unterbinden
Greetz Kev.