Sinnvolle Aufteilung in Klassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

Mhh okay. Bis jetzt bin ich relativ überfordert und verstehs ned ganz :? Werds aber mal weiter versuchen.
Aber sonst kann man das GalileoComputing Openbook einigermasen gebrauchen? Hab die ersten paar Kapitel auch mal angeschaut, waren zwar nur eher simplere Themen die ich auch begreifen aber trotzdem, lerne nur ungern falsche Sachen.

Und danke euch für die Hilfe.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

heal.p hat geschrieben:Aber sonst kann man das GalileoComputing Openbook einigermasen gebrauchen? Hab die ersten paar Kapitel auch mal angeschaut, waren zwar nur eher simplere Themen die ich auch begreifen aber trotzdem, lerne nur ungern falsche Sachen.
Nein, auch sonst finde ich es relativ unbrauchbar. Die Autoren kennen sich auch mit Modulen nicht sonderlich aus und schreiben auch keinen Idiomatischen Code, weil sie Python offenbar selbst nicht wirklich können. Es ist ja nicht so als ob es nicht eine Menge tatsächlich auch guter Python-Einführungen gäbe.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

heal.p hat geschrieben:Mhh okay. Bis jetzt bin ich relativ überfordert und verstehs ned ganz :? Werds aber mal weiter versuchen.
Nimm dir kleine Beispiele und vorallem die im Tutorial vor und für weitere Fragen kannst du ja jederzeit das Forum konsultieren.
heal.p hat geschrieben:Aber sonst kann man das GalileoComputing Openbook einigermasen gebrauchen? Hab die ersten paar Kapitel auch mal angeschaut, waren zwar nur eher simplere Themen die ich auch begreifen aber trotzdem, lerne nur ungern falsche Sachen.
Mach dir keinen Kopf wenn du was falsches aufschnappst, wirst du hier im Forum wieder zurecht gerückt. :mrgreen:

@Leonidas
Naja, das Openbook ist "gut" illustriert, aber das wars dann schon.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

Leonidas hat geschrieben:Nein, auch sonst finde ich es relativ unbrauchbar. Die Autoren kennen sich auch mit Modulen nicht sonderlich aus und schreiben auch keinen Idiomatischen Code, weil sie Python offenbar selbst nicht wirklich können. Es ist ja nicht so als ob es nicht eine Menge tatsächlich auch guter Python-Einführungen gäbe.

Xynon1 hat geschrieben: Nimm dir kleine Beispiele und vorallem die im Tutorial vor und für weitere Fragen kannst du ja jederzeit das Forum konsultieren.

Mach dir keinen Kopf wenn du was falsches aufschnappst, wirst du hier im Forum wieder zurecht gerückt. :mrgreen:
Jo werd mich die Tage damit beschäftigen und sicherlich Fragen dazu stellen, denke werde weiterhin diesen Thread benutzen und einfach umbenennen :)

Jedoch finde ich das einige Tutorials sehr "hochgestochen" schreiben und das ist nicht immer ganz verständlich. Wenn ich jedes 3te Wort googlen muss damit ich den Satz verstehe macht es mir auch keine Freunde und man lernt doch am schnellsten wenn man Freude an etwas hat.

Das man hier zurecht gerückt wird fiel mir schon sehr oft auf :) und ich finde es auch gut.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

heal.p hat geschrieben: Jedoch finde ich das einige Tutorials sehr "hochgestochen" schreiben und das ist nicht immer ganz verständlich. Wenn ich jedes 3te Wort googlen muss damit ich den Satz verstehe macht es mir auch keine Freunde und man lernt doch am schnellsten wenn man Freude an etwas hat.
Naja, als Autor kann man ja nicht exakt die Vorbildung eines Lesers wissen. Beschreibt und erklärt man ausführlich jeden eventuellen begrifflichen Stolperstein, so wird ein Werk schnell ausufernd und ausladend groß. Exakte Terminologie ist eben wichtig - da muss man als Anfänger natürlich viel auf einmal lernen. Aber dazu gibt es ja keine Alternative.

Aber die Menge a la jedes dritte Wort zweifel ich doch mal stark an ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

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 :?: :?
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Dann solltest du nochmal genau nachlesen :D
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.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

Xynon1 hat geschrieben:Dann solltest du nochmal genau nachlesen :D
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.
:shock: 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.
Benutzeravatar
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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

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)
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

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.
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:
- 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.
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)
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?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

heal.p hat geschrieben: Danke dir Xynon1. Was macht genau das self?
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>
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

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>
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.
das In [2] heisst das, das dein zweiter Input (in die Shell) f = Foo() ist? Oder wie muss ich das verstehen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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?
Jupp. Öffne doch mal ne Shell und probiere das aus ;-) Ich verwende ipython als Shell; daher die Nummerierung und so.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

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.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Vielleicht kann dies http://www.python-forum.de/viewtopic.ph ... 30#p112630 noch eine Anregung sein.

Stefan
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

sma hat geschrieben:Vielleicht kann dies http://www.python-forum.de/viewtopic.ph ... 30#p112630 noch eine Anregung sein.

Stefan
Interessanter Thread, danke fürs Gedächtnis auffrischen :-)

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
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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:

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
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:

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
Stefan
heal.p
User
Beiträge: 30
Registriert: Freitag 3. Dezember 2010, 12:28

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.
Antworten