Hab mich nun ins Thema eingelesen und würde das gerne auch gleich ausprobieren. Wäre es nun sinnvoll wenn ich für jeweil eine eigene Klasse für
- Meine Charakter
- Den Gegner
mache und dann die Aktionen wie Angreifen global definiere? Oder Sollte ich diese Sachen jeweil in die Charakter / Gegner Klasse einfügen
Sinnvolle Aufteilung in Klassen
Dann solltest du nochmal genau nachlesen
Wenn du eine Klasse Character schreibst, dann kannst du davon mehrere Instanzen anlegen. Ob du von der Klassen dann nochmal ableitest, also spezialisierst, liegt daran wie unterschiedlich die Eigenschaften des Gegners und die deines Heros sind.
"global" definieren, sollte man nach Möglichkeit gar nichts.
Die Schlacht-/Kampfberechnung könnte man in einer Funktion machen, wie komplex diese ist musst du abwägen.
Wenn du eine Klasse Character schreibst, dann kannst du davon mehrere Instanzen anlegen. Ob du von der Klassen dann nochmal ableitest, also spezialisierst, liegt daran wie unterschiedlich die Eigenschaften des Gegners und die deines Heros sind.
"global" definieren, sollte man nach Möglichkeit gar nichts.
Die Schlacht-/Kampfberechnung könnte man in einer Funktion machen, wie komplex diese ist musst du abwägen.
fühl mich bisschen erschlagen. Heisst das ich habe dann nur eine Klasse? Jedoch versteh ich au ned ganz was es mit diesen Instanzen auf sich hat, hab nun http://tutorial.pocoo.org/classes.html#instanzobjekte schon 2x durchgelesen, und bin immer noch ned weiter. Auch das Beispiel hilft mir nicht gerade zu verstehen, was Sie mir mitteilchen wollen.Xynon1 hat geschrieben:Dann solltest du nochmal genau nachlesen
Wenn du eine Klasse Character schreibst, dann kannst du davon mehrere Instanzen anlegen, ob du davon dann Ableitest, also spezialisierst, liegt daran wie unterschiedlich die Eigenschaften des Gegners und die deines Heros sind.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ich denke auch man sollte auf jeden Fall einmal genau durchdenken, inwiefern sich denn SCs von NSCs unterscheiden, evtl. benötigt man gar nur eine Klasse, mit der sich alle denkbaren Charaktere abbilden lassen.
Aktionen wie Kämpfe usw. sollten imho nicht direkt in die Charakterklassen integriert werden. Schließlich finden diese ja in einer "Umwelt" statt, die ggf. auch Einfluss auf das Geschehen hat, aber vor allem steuert und die Kontrolle über die Aktionen besitzt. All das müßte man ja sonst irgend wie einem Charakter zuweisen... imho keine gute Idee.
Bei meinem DSA-Kampfsimulator habe ich das ganze mit mehreren Funktionen gelöst. Ein Charakter hatte da eher eine passive Rolle und lieferte nur simple Werte und ggf. mal einen kumulierten Wert. Willst Du da so was wie eine KI draufstülpen, so dass die Chars Entscheidungen treffen können, so wären das wohl schon Kandidaten für Methoden, die mit von außen übergebenen Daten Charakter bezogene Entscheidungen treffen können.
Aktionen wie Kämpfe usw. sollten imho nicht direkt in die Charakterklassen integriert werden. Schließlich finden diese ja in einer "Umwelt" statt, die ggf. auch Einfluss auf das Geschehen hat, aber vor allem steuert und die Kontrolle über die Aktionen besitzt. All das müßte man ja sonst irgend wie einem Charakter zuweisen... imho keine gute Idee.
Bei meinem DSA-Kampfsimulator habe ich das ganze mit mehreren Funktionen gelöst. Ein Charakter hatte da eher eine passive Rolle und lieferte nur simple Werte und ggf. mal einen kumulierten Wert. Willst Du da so was wie eine KI draufstülpen, so dass die Chars Entscheidungen treffen können, so wären das wohl schon Kandidaten für Methoden, die mit von außen übergebenen Daten Charakter bezogene Entscheidungen treffen können.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Hier mal ein kleines Beispiel damit du ein wenig Überblick bekommst.
Code: Alles auswählen
# Klassenobjekt
class Character(object):
# Konstrucktor
def __init__(self, name="Nameless"):
# Attribute
self.name = name
self.hp = 10
self.max_hp = 100
# Methode
def sleep(self):
self.hp = self.max_hp
if __name__ == "__main__":
# Instanzen player und mob1
player = Character("Ich")
mob1 = Character("Ratte")
print(player.hp)
# Methodenaufruf
player.sleep()
print(player.hp)
print(mob1.hp)
Denke soweit bin ich noch ned das ich da ne KI einstülpen werde. Auch das die Umwelt bereits einfluss in den Kampf haben wird, denke ich nicht das ich das schon tun werde. Ich habe mir mehr gedacht, das man 3 Aktionen zur Auswahl hat:Hyperion hat geschrieben:Ich denke auch man sollte auf jeden Fall einmal genau durchdenken, inwiefern sich denn SCs von NSCs unterscheiden, evtl. benötigt man gar nur eine Klasse, mit der sich alle denkbaren Charaktere abbilden lassen.
Aktionen wie Kämpfe usw. sollten imho nicht direkt in die Charakterklassen integriert werden. Schließlich finden diese ja in einer "Umwelt" statt, die ggf. auch Einfluss auf das Geschehen hat, aber vor allem steuert und die Kontrolle über die Aktionen besitzt. All das müßte man ja sonst irgend wie einem Charakter zuweisen... imho keine gute Idee.
Bei meinem DSA-Kampfsimulator habe ich das ganze mit mehreren Funktionen gelöst. Ein Charakter hatte da eher eine passive Rolle und lieferte nur simple Werte und ggf. mal einen kumulierten Wert. Willst Du da so was wie eine KI draufstülpen, so dass die Chars Entscheidungen treffen können, so wären das wohl schon Kandidaten für Methoden, die mit von außen übergebenen Daten Charakter bezogene Entscheidungen treffen können.
- physischer Angriff (wird von Stärke beeinflusst)
- Abwehren (wird von Beweglichkeit beeinflusst)
- magischer Angriff (wird von Intelligenz beeinflusst)
Den Gegner hätte ich einfach über Zufallszahl gesteurt.
Danke dir Xynon1. Was macht genau das self? Unten rufst du ja dann die hp des Spieler mit player.hp auf und oben definierst du player soll der Character sein der Ich heisst, richtig?Xynon1 hat geschrieben:Hier mal ein kleines Beispiel damit du ein wenig Überblick bekommst.
Code: Alles auswählen
# Klassenobjekt class Character(object): # Konstrucktor def __init__(self, name="Nameless"): # Attribute self.name = name self.hp = 10 self.max_hp = 100 # Methode def sleep(self): self.hp = self.max_hp if __name__ == "__main__": # Instanzen player und mob1 player = Character("Ich") mob1 = Character("Ratte") print(player.hp) # Methodenaufruf player.sleep() print(player.hp) print(mob1.hp)
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Dazu solltest Du Dir noch einmal Kapitel 9 im Tutorial gründlich angucken Kurz gesagt ist der Name reine Konvention und dahinter verbirgt sich immer das aufrufende Objekt, welches implizit an die Methode weitergegeben wird. Hier mal ein kurzes Beispiel zum Nachdenken:heal.p hat geschrieben: Danke dir Xynon1. Was macht genau das self?
Code: Alles auswählen
In [1]: class Foo(object):
...:
...: def bar(self):
...: print self
...:
...:
In [2]: f = Foo()
In [3]: f.bar()
<__main__.Foo object at 0x9f1a60c>
In [4]: f
Out[4]: <__main__.Foo object at 0x9f1a60c>
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Les das Kapitel ja immer und immer wieder aber weiss nicht, begreif es immer noch nicht so ganz. Und dein Beispiel verwirrt mich mehr als das es mir etwas hilft.Hyperion hat geschrieben: Dazu solltest Du Dir noch einmal Kapitel 9 im Tutorial gründlich angucken Kurz gesagt ist der Name reine Konvention und dahinter verbirgt sich immer das aufrufende Objekt, welches implizit an die Methode weitergegeben wird. Hier mal ein kurzes Beispiel zum Nachdenken:Code: Alles auswählen
In [1]: class Foo(object): ...: ...: def bar(self): ...: print self ...: ...: In [2]: f = Foo() In [3]: f.bar() <__main__.Foo object at 0x9f1a60c> In [4]: f Out[4]: <__main__.Foo object at 0x9f1a60c>
das In [2] heisst das, das dein zweiter Input (in die Shell) f = Foo() ist? Oder wie muss ich das verstehen?
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Jupp. Öffne doch mal ne Shell und probiere das aus Ich verwende ipython als Shell; daher die Nummerierung und so.heal.p hat geschrieben: das In [2] heisst das, das dein zweiter Input (in die Shell) f = Foo() ist? Oder wie muss ich das verstehen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ich benutz die normale Python Shell. Mhh glaube solange kapier ichs. Aber wirklich nur langsam.
Danke dir/euch für die Hilfe.
Edit: Kumpel hat mir das nun nochmal erklärt. Ich glaube jetzt den grössten Teil verstanden zu haben. Werd mich nun nächste Woche dran versuchen, ob was gescheites raus kommt wen ich es umsetze. Denke ich werde Mittwochs meinen nächsten Codeansatz veröffentlichen.
Danke dir/euch für die Hilfe.
Edit: Kumpel hat mir das nun nochmal erklärt. Ich glaube jetzt den grössten Teil verstanden zu haben. Werd mich nun nächste Woche dran versuchen, ob was gescheites raus kommt wen ich es umsetze. Denke ich werde Mittwochs meinen nächsten Codeansatz veröffentlichen.
Vielleicht kann dies http://www.python-forum.de/viewtopic.ph ... 30#p112630 noch eine Anregung sein.
Stefan
Stefan
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Interessanter Thread, danke fürs Gedächtnis auffrischensma hat geschrieben:Vielleicht kann dies http://www.python-forum.de/viewtopic.ph ... 30#p112630 noch eine Anregung sein.
Stefan
Speziell über die attack-Methode ließe sich imho streiten. Bei Deinem simplen Ansatz wie bei Dir ist es bestimmt eine gute Wahl, das in die Helden-Klasse zu packen und nicht als externe Funktion zu implementieren. Kommen jedoch Dinge wie mehrere Gegner, verschiedene Anzahlen an Aktionen, usw. hinzu, so würde ich da ggf. eben doch eine externe Berechnung einer Kampfaktion bevorzugen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Bei einem Versuch, ein komplexeres Kampfsystem zu implementieren kam ich ganz schnell bei dem Wunsch an, Multimethoden zu haben, denn wenn an einem Angriff der Angreifer, der Gegner, eine Waffe, vielleicht noch eine Rüstung, Talente und aktive Zauber beteiligt sind, dann ist eigentlich keines dieser Objekte jetzt ein geeigneter Platz, um da den Kampf-Algorithmus zu implementieren.
Andererseits muss man's auch nicht komplizierter machen als nötig.
Ich wollte mal ein Programm schreiben, dass mir folgenden Dialog erlaubt:
Als ich das auf deutsch versucht habe, bin ich an den verschiedenen Fällen und Pronomen gestorben. Auf englisch ist es einfacher. Dennoch, abhängig von den hier nur implizit erwähnten Regeln ist es relativ kompliziert, eine Kampfrunde durchzuführen. Ich hatte dafür eine Klasse `Battle` vorgesehen, die sich um alles kümmert:
Stefan
Andererseits muss man's auch nicht komplizierter machen als nötig.
Ich wollte mal ein Programm schreiben, dass mir folgenden Dialog erlaubt:
Code: Alles auswählen
Scene: At the border of the Qua'atl jungle [4]
Description:
The dense forest opens to a small clearing.
In the north, a mountain range is visible, but the path that you've
been followed for days outs over a narrow suspension bridge,
their moorings looking all but trustworthy.
Exits:
1. Back to the jungle [3]
2. Over the suspension bridge [5]
Random encounters: Jungle. Triggered.
Your startle a Jaguar on search for prey.
He seems to be hungry and attacks.
Opponents:
1. Jaguar (Health 4/4)
Party (in order of initiative):
1. Thomu (Health 5/5, Bow, behind)
2. Greog (Health 3/3, Sword, front)
3. Adali (Health 2/4, Quarterstaff, behind)
[ask player for actions, then sumarize]
Actions:
- Adali casts "Protection" on Greog
and casts "Strength" on Greog
- Thomu attacks the jaguar with his bow
- Greog does a wild attack on the jaguar with his sword
Combat:
Thomu shoots and misses the jaguar.
The jaguar attacks Greog and inflicts 1 wound
and it attacks Thomu and inflicts 2 wounds.
Greog swings and hits the jaguar, inflicting 2 wounds
and he swings again and misses the jaguar.
Adali casts "Protection" on Greog
and she casts "Strength" on Greog.
Summary:
Opponents:
1. Jaguar (Health 2/4)
Party (in order of initiative):
1. Thomu (Health 3/5, Bow, behind)
2. Greog (Health 2/3, Sword, front)
3. Adali (Health 2/4, Quarterstaff, behind)
Actions:
- Thomu draws his dagger
and he attacks the jaguar
- Greog attacks the jaguar
- Adali casts "Healing" on Thomu
Combat:
Thomu stabs and misses the jaguar.
The jaguar attacks Andali and inflicts 3 wounds.
Adali is deadly wounded and does down.
Greog interrupts his action (automatic action)
and uses a healing potion on Andali (+1 health)
and so on
Code: Alles auswählen
battle = Battle(location=jungle_border, party=[thomu, greog, adali], opponents=[jaguar])
battle.perform()
class Battle:
def perform(self):
self.determine_initiatives()
self.sort_combatants_by_initiative()
for combatant in self.combatants:
self.perform_actions(combatant)
self.print_combat()
self.print_summary()
def perform_actions(self, combatant):
for action in combatant.actions:
action.perform(self)
class AttackAction:
def __init__(self, actor, target, weapon):
self.actor, self.target, self.weapon = actor, target, weapon
def perform(self, battle):
battle.attack(self.actor, self.target, self.weapon)
class CastAction:
def __init__(self, actor, target, spell):
self.actor, self.target, self.spell = actor, target, spell
def perform(self, battle):
battle.cast(self.actor, self.target, self.spell)
class Battle...
def attack(self, actor, target, weapon):
attack_bonus = actor.attack_bonus_against(target) + weapon.attack_bonus_against(target)
defense_bonus = target.defense_bonus_against(weapon)
damage_bonus = weapon.damage_bonus_against(target)
if roll(actor.attack_skill + attack_bonus) > roll(target.defense_skill + defense_bonus):
wounds = roll(weapon.damage + damage_bonus)
self.report.report_attack_hit(actor, target, weapon, wounds)
self.apply_wounds(target, wounds)
else:
self.report.report_attack_miss(actor, target, weapon)
def apply_wounds(target, wounds):
target.health -= wounds
if target.health < 0:
self.report.report_deadly_wound(target)
self.change_action_to_help(target)
and so on
Danke dir Stefan fürs posten.
Mein Script soll jedoch lange nicht so komplex werden. Vll realisiere ich soetwas einmal später.
Bei meinem Script soll es im Moment sowieso nur beschränkte Möglichkeiten geben.
- Skillpunkte verteilen
- Gegner Angreifen und kämpfen
- Zusätzliche Skillpunkte erlangen und verteilen.
Mein Script soll jedoch lange nicht so komplex werden. Vll realisiere ich soetwas einmal später.
Bei meinem Script soll es im Moment sowieso nur beschränkte Möglichkeiten geben.
- Skillpunkte verteilen
- Gegner Angreifen und kämpfen
- Zusätzliche Skillpunkte erlangen und verteilen.