Programmieren mit Swift - Für macOS und iOS
Programmieren mit Swift - Für macOS und iOS
Ermitteln der Rasse

Ausser den Menschen haben alle Rasse gewisse Mindestanforderungen an die Charaktereigenschaften, so dass eine vollkommen freie Wahl nicht den Regeln entspricht. Da es aber nicht zu kompliziert ist, lässt sich diese Auswahl mit einigen if-Strukturen schnell erledigen. Die für die ausgewürfelten Charaktereigenschaften möglichen Rassen sollen in einem NSMutableArray mit dem Namen racesArray gespeichert werden, welches später mit einem NSArrayController an einen NSPopUpButton gebunden werden soll. Wie die anderen Klassen auch wird das NSMutableArray in der Header-Datei von MyController deklariert und in der init-Methode initialisiert.
- init
{
    if (self = [super init])
    {
        rpgDice = [[Dice alloc] init];
        rpgCharacter = [[Character alloc] init];
        racesArray = [[NSMutableArray alloc] init];
    }
   
return self;
}
Um das Programm übersichtlich zu halten, soll eine separate Methode die möglichen Rassen ermitteln und mit ihnen das Array füllen. Die Methode soll determinePossibleRaces heissen, und muss am Ende der rollCharacterAttributes-Methode aufgerufen werden. So wird sichergestellt, dass immer, wenn neue Attribute gewürfelt wurden, die dafür möglichen Rassen ermittelt werden.
[self determinePossibleRaces];
Die ersten Anweisungen dieser Methode sind einfach. Zuerst müssen alle Objekte im Array entfernt werden, es könnten sich ja noch die Rassen des letzten Würfeln dort befinden. Anschliessend wird ein Objekt der Rasse Mensch ohne jede Bedingung hinzugefügt.
- (void)determinePossibleRaces
{
    [racesArray removeAllObjects];
    [racesArray addObject: [[Race alloc] initWithName:
@"Mensch"] ];
}
Für alle anderen Rassen gibt es allerdings Mindestanforderungen, die jetzt im Programm umgesetzt werden müssen. Hat eine Figur zum Beispiel eine Stärke unter 6, kann sie kein Zwerg werden. Zunächst werden aber die Eigenschaftswerte wieder in einen einfachen Datentyp (int) umgewandelt. Das ist nicht unbedingt nötig, mach aber die Vergleiche überschaubarer, da man mit kürzeren Bezeichnern arbeiten kann.
- (void)determinePossibleRaces
{
    [racesArray removeAllObjects];
    [racesArray addObject: [[Race alloc] initWithName:@"Mensch"] ];

    int strength = [[rpgCharacter strength] intValue];
    int dexterity = [[rpgCharacter dexterity] intValue];
    int constitution = [[rpgCharacter constitution] intValue];
    int intelligence = [[rpgCharacter intelligence] intValue];
    int wisdom = [[rpgCharacter wisdom] intValue];
    int charisma = [[rpgCharacter charisma] intValue];

    if(strength >= 3 && dexterity >= 6 && constitution >= 7
     && intelligence >= 8 && wisdom >= 3 && charisma >= 8)
    {
        [racesArray addObject:[[Race alloc] initWithName:@"Elfe"] ];
    }

    if(strength >= 6 && dexterity >= 3 && constitution >= 8
     && intelligence >= 6 && wisdom >= 3 && charisma >= 3)
    {
        [racesArray addObject:[[Race alloc] initWithName:@"Gnom"] ];
    }

    if(strength >= 3 && dexterity >= 6 && constitution >= 6
     && intelligence >= 4 && wisdom >= 3 && charisma >= 3)
    {
        [racesArray addObject:[[Race alloc] initWithName:@"Halbelfe"] ];
    }

    if(strength >= 7 && dexterity >= 7 && constitution >= 10
     && intelligence >= 6 && wisdom >= 3 && charisma >= 3)
    {
        [racesArray addObject:[[Race alloc] initWithName:@"Halbling"] ];
    }

    if(strength >= 8 && dexterity >= 7 && constitution >= 11
     && intelligence >= 3 && wisdom >= 3 && charisma >= 3)
    {
        [racesArray addObject:[[Race alloc] initWithName:@"Zwerg"] ];
    }
}

stacks_image_8901C84A-F031-47E8-971C-CD0B61B969CB
Die Vorgehensweise in dieser Methode ist nicht optimal. Besser wäre ein Programmablauf, bei dem generell alle Rassen erzeugt werden und dann nur noch entschieden wird, ob diese Rassen in das racesArray aufgenommen werden oder nicht. Im Moment werden immer wieder neue Objekte instanziert, was aus technischem Gesichtspunkt nicht sehr clever ist und zusätzliche Arbeit für den Garbage Collector bedeutet. Wollte man den anderen Weg gehen, wäre es aber nötig, dass die Rasse-Objekte ausserhalb von einer Methode deklariert würden, da man ja von mehreren Methoden auf sie zugreifen möchte. Dadurch würden aber alle Rassen zu einer Eigenschaft von MyController. Das soll aber nicht passieren, deshalb lassen Sie den Code wie er ist. Wichtig ist es aber, dass Sie sich der Problematik bewusst sind.

nächste Seite