三國英雄對戰——控制檯輸出模擬

Kha_Zix_1發表於2020-10-10

MOSAD_HW1

UML類圖

在這裡插入圖片描述

類的設計及其實現

Skill——技能類

參照現代遊戲的設計,技能可分為傷害類技能恢復類技能,因此變數設計為

  • 技能標識
    • 名字
  • 施放代價
    • 法力消耗
    • 血量消耗
  • 施放效果
    • 法力恢復
    • 血量恢復
    • 傷害值

這個類只需要一個建構函式,用於初始化這個技能的六個資訊即可。由於只是簡單的賦值語句,因此不再贅述。

Hero——英雄類

英雄類依賴於技能類,即一個英雄可以擁有多個技能,因此英雄類會有一個技能類陣列來維護一個英雄的技能資訊。除此之外,一個英雄除了技能外還有其他資訊,因此成員變數設計如下:

  • 國家
  • 初始法力值
  • 初始血量
  • 姓名
  • 技能數量
  • 技能陣列

同理可利用一個簡單的建構函式來初始化這些資訊,其中陣列的初始化可以採用以下方式:

self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];

其中s1,s2均是指向一個技能的指標。這裡採用指標的原因是尚未摸清楚objc中類似於C++的引用變數的使用方式,為了避免過多的記憶體使用,因此採用指標的方式。

由於英雄需要選擇另一名英雄來單挑,因此英雄類應該有一個成員函式來完成單挑的過程並輸出單挑過程中的關鍵結果。因此設計了一個方法:

- (void)PKOneUnit:(Hero *)vs {
    int rand_num = arc4random() % 2;        //隨機選擇兩個技能中的一個
    
    Skill* current_skill = self->skills[rand_num];
    
    if Current skill can be launched {
        ...
        Console output information
        Hero attribute changes after maintenance skill is launched
        ...
    }
    else {
        ...
        Output the information that the skill cannot activate
        the hero attribute does not change
        ...
    }
    
    The console outputs the key attributes of each hero in each round.

主函式呼叫

主函式的設計較為簡單,主要思路是利用隨機數選擇英雄,然後最多迴圈10個回合,在每個回合中依次呼叫每個英雄的PKOneUnit方法,直到某一方血量降到0或0以下或者超過10個回合仍然沒有分出勝負,迴圈跳出。

Hero* h1 = getHero(rand1);  //getHero方法是通過隨機數返回對應的英雄例項
Hero* h2 = getHero(rand2);  //這裡在取rand2時保證 rand2!=rand1

while (雙方血量大於0 && 回合數小於10) {
  [h1 PKOneUnit:h2];
  [h2 PKOneUnit:h1];
}

...
控制檯輸出勝負資訊
...

執行結果

在這裡插入圖片描述

專案心得

本次專案是對objc的簡單應用,由於有了大一C++的基礎,理解起來並不是特別困難,總結主要不同點如下:

  • 類的宣告與實現
    • C++中類的宣告為class,實現時可以在類外使用作用域符 :: 來告訴編譯器是哪個類的方法
    • objc中宣告為 @interface@end 中間的程式碼塊,而實現時通過 @implementation@end 的程式碼塊來實現
  • 方法的宣告
    • C++方法的宣告為Type function(Type1 arg1, ...)
    • objc方法的宣告為(Type) function: (Type1) arg1 ...
  • 方法的呼叫
    • C++中通過指標->方法的形式呼叫
    • objc中通過[指標 方法]的形式呼叫

除此之外C++和objc大同小異。總的來說,這一次作業讓我加深了對上課objc語法點和麵向物件設計思想的理解,期待下一次更有意思的作業!

附錄:原始碼

main.m

#import <UIKit/UIKit.h>
#import "Hero.h"

Hero* getHero(int rand_num) {
    
    switch (rand_num) {
        case 0:
            return [ZhangFei new];
            break;
        case 1:
            return [JiaWen new];
            break;
        case 2:
            return [GaiLun new];
            break;
        case 3:
            return [YaSuo new];
            break;
        case 4:
            return [LiBai new];
            break;
        case 5:
            return [LiQing new];
            break;
        case 6:
            return [HuaMuLan new];
            break;
        case 7:
            return [LvDongBin new];
            break;
        case 8:
            return [GuanYu new];
            break;
        case 9:
            return [ZhaoYun new];
            break;
        case 10:
            return [DeLaiESi new];
            break;
        default:
            break;
    }
    
    return nil;
}

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        const int hero_num = 11;
        int rand1, rand2, total = 0;
        rand1 = arc4random() % hero_num;
        do {
            rand2 = arc4random() % hero_num;
        }while (rand1 == rand2);
        Hero* h1 = getHero(rand1);
        Hero* h2 = getHero(rand2);
        
        printf("遊戲開始!\n%s vs %s\n", [h1->name UTF8String], [h2->name UTF8String]);
        
        while (++total <= 10) {
            printf("\n----------當前為第%i回合---------\n", total);
            [h1 PKOneUnit:h2];
            if (h2->blood_value <= 0) {
                printf("\n遊戲結束, %s獲勝!", [h1->name UTF8String]);
                break;
            }
            [h2 PKOneUnit:h1];
            if (h1->blood_value <= 0) {
                printf("\n遊戲結束, %s獲勝!", [h2->name UTF8String]);
                break;
            }
            
        }
        
        if (total > 10) {
            printf("\n遊戲結束,無人出局!");
        }
    }
}

Hero.h

#ifndef Hero_h
#define Hero_h

#import <Foundation/Foundation.h>

@interface Skill : NSObject {
    @public
    NSInteger mana_cost;
    NSInteger blood_cost;
    NSInteger power;
    NSInteger mana_regen;
    NSInteger blood_regen;
    NSString* name;
}

- (id) initSkill: (NSString*) _name
       mana_cost: (NSInteger) _mana_cost
      blood_cost: (NSInteger) _blood_cost
           power: (NSInteger) _power
      mana_regen: (NSInteger) _mana_regen
     blood_regen: (NSInteger) _blood_regen;
@end

@interface Hero : NSObject {
    @public
    NSString* country;
    NSInteger blood_value;
    NSInteger energy_value;
    NSString* name;
    NSInteger skill_num;
    NSArray* skills;
}

- (void)PKOneUnit: (Hero*) vs;
- (NSInteger)getBlood_value;
- (NSInteger)getEnergy_value;
- (NSString *)getCountry;
- (NSString *)getName;

@end

@interface ZhangFei: Hero {
    
}

@end

@interface ZhaoYun: Hero {
    
}

@end

@interface JiaWen: Hero {
    
}

@end

@interface GaiLun: Hero {
    
}

@end

@interface YaSuo: Hero {
    
}

@end

@interface LiQing: Hero {
    
}

@end

@interface HuaMuLan: Hero {
    
}

@end

@interface LiBai: Hero {
    
}

@end

@interface LvDongBin: Hero {
    
}

@end

@interface GuanYu: Hero {
    
}

@end

@interface DeLaiESi: Hero {
    
}

@end

#endif /* Header_h */

Hero.m

#import <Foundation/Foundation.h>
#import "Hero.h"

@implementation Skill
- (id) initSkill: (NSString*) _name
       mana_cost: (NSInteger) _mana_cost
      blood_cost: (NSInteger) _blood_cost
           power: (NSInteger) _power
      mana_regen: (NSInteger) _mana_regen
     blood_regen: (NSInteger) _blood_regen {
    self = [super init];
    if (self) {
        self->mana_cost = _mana_cost;
        self->blood_cost = _blood_cost;
        self->power = _power;
        self->mana_regen = _mana_regen;
        self->blood_regen = _blood_regen;
        self->name = _name;
    }
    
    return self;
}

@end

@implementation Hero
- (NSInteger)getBlood_value {
    return blood_value;
}

- (NSInteger)getEnergy_value {
    return energy_value;
}

- (NSString *)getCountry {
    return country;
}

- (NSString *)getName {
    return name;
}

- (void)PKOneUnit:(Hero *)vs {
    int rand_num = arc4random() % 2;
    
    Skill* now_skill = self->skills[rand_num];
    
    if (self->energy_value > now_skill->mana_cost && self->blood_value > now_skill->blood_cost) {
        printf("\n%s發動技能: %s\n對%s造成%li點傷害\n", [[self getName] UTF8String], [now_skill->name UTF8String], [vs->name UTF8String], now_skill->power);
        vs->blood_value -= now_skill->power;
        self->energy_value -= now_skill->mana_cost;
        self->energy_value += now_skill->mana_regen;
        self->blood_value -= now_skill->blood_cost;
        self->blood_value += now_skill->blood_regen;
    
        
    }
    else {
        printf("\n%s無法發動當前技能: %s\n", [[self getName] UTF8String], [now_skill->name UTF8String]);
    }
    
    printf("\n%s剩餘血量: %li\n剩餘藍量: %li\n\n%s剩餘血量: %li\n剩餘藍量: %li\n", [self->name UTF8String], (long)self->blood_value, (long)self->energy_value, [vs->name UTF8String], (long)vs->blood_value, (long)vs->energy_value);
    
}
@end

@implementation ZhangFei

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"張飛";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"肉彈衝擊" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"醉酒狂暴" mana_cost:2 blood_cost:0 power:0 mana_regen:0 blood_regen:2];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation ZhaoYun

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"趙雲";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"三重爪擊" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"長槍依在" mana_cost:2 blood_cost:0 power:3 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation JiaWen

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"嘉文";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"巨龍撞擊" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"天崩地裂" mana_cost:2 blood_cost:0 power:3 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation GaiLun

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"蓋倫";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"致命打擊" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"德瑪西亞正義" mana_cost:2 blood_cost:0 power:4 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation YaSuo

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"亞索";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"斬鋼閃" mana_cost:2 blood_cost:0 power:3 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"狂風絕息斬" mana_cost:2 blood_cost:0 power:5 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation LiBai

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"李白";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"俠客行" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"三尺青鋒" mana_cost:2 blood_cost:0 power:3 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation LiQing

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"李青";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"天音波" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"猛龍擺尾" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation HuaMuLan

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"花木蘭";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"孤注一擲" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"木蘭之心" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation LvDongBin

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"呂洞賓";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"驚鴻游龍" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"迴魂仙夢" mana_cost:2 blood_cost:0 power:0 mana_regen:0 blood_regen:3];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end

@implementation GuanYu

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"關羽";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"順劈" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"拖刀" mana_cost:0 blood_cost:0 power:0 mana_regen:2 blood_regen:2];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}
@end


@implementation DeLaiESi

-(id) init {
    self = [super init];
    
    if (self) {
        self->name = @"德萊厄斯";
        self->country = @"蜀國";
        self->blood_value = 20;
        self->energy_value = 20;
        self->skill_num = 2;
        Skill* s1 = [[Skill alloc]initSkill: @"大殺四方" mana_cost:2 blood_cost:0 power:2 mana_regen:0 blood_regen:0];
        Skill* s2 = [[Skill alloc]initSkill: @"諾克薩斯斷頭臺" mana_cost:8 blood_cost:0 power:8 mana_regen:0 blood_regen:0];
        self->skills = [[NSArray alloc]initWithObjects:s1, s2, nil];
        
    }
    
    return self;
}

@end

相關文章