MOSAD第一次作业
介绍
创建第一个XCode项目、面向对象与Objective-C语法学习
开发环境
Mac OS
Objective-C
Xcode
任务
安装配置Mac OS和Xcode
熟悉Mac OS按键操作
熟悉Xcode项目结构,编译运行第一个Xcode项目,项目创建流程详见tutorial
选取并设计N(N>10)个三国英雄
实现场景输出(log形式即可):随机选择两名英雄,挑战M(M<=10)个回合,其中每个回合各英雄可发动不同技能,从而导致不同的结果发生(英雄各属性变化及每个回合的输赢)。
要求
输出随机选择的英雄及其关键属性,输出单挑中每回合的过程、结果,以及最终胜负结果
需要用到多态
输出程序设计和运行过程中,相关设计体现的oo特性(数据隐秘性、封装性、继承、多态)
验收要点
输出随机选择的英雄及其关键属性,输出单挑中每回合的过程、结果,以及最终胜负结果
类的设计与封装
类与类之间的继承关系与多态的体现
设计思路
大体上先把英雄的属性想好了
大概就是名字、所属的国家地区(魏蜀吴群)、血量、攻击力
和技能以及技能发动条件
魏蜀吴群各3个英雄,攻击12个英雄
我经过斟酌最后决定让这个游戏的大部分操作都经由骰子来驱动
例如能否发动攻击(双方各掷一个骰子),能否发动技能(再掷一个骰子)
骰子用随机数实现
刚开始写的时候认为重点难点应该在于人物的平衡性以及技能的生效方式。
编写一个Hero类作为所有英雄的父类,其中PKOneUnit函数和skill函数体现多态。
具体实现
Hero.h
#ifndef Hero_h
#define Hero_h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Hero: NSObject
{
NSString* name;
NSString* country;
int blood_value;
int attack;
}
-(void)PKOneUnit;//这里我把这个函数用作初始化人物属性
-(NSString*)getName;
-(NSString*)getCountry;
-(NSInteger)getBLood_value;
-(NSInteger)getAttack;
-(void)changeBlood:(NSInteger)blood;//扣血或加血
-(NSInteger)skill:(NSInteger) di andAtt:(NSInteger) att;//技能
-(NSInteger)dice;//掷骰子
@end
@interface LiuBei : Hero
{
}
@end
@interface GuanYu:Hero
{
}
@end
@interface Zhangfei: Hero
{
}
@end
@interface CaoCao:Hero
{
}
@end
@interface XiaHoudun:Hero
{
}
@end
@interface SiMayi:Hero
{
}
@end
@interface SunCe:Hero
{
}
@end
@interface ZhouYu:Hero
{
}
@end
@interface SunQuan: Hero
{
}
@end
@interface LvBu:Hero
{
}
@end
@interface DongZhuo: Hero
{
}
@end
@interface HuaTuo:Hero
{
}
@end
NS_ASSUME_NONNULL_END
#endif /* Hero_h */
Hero.m
//
// Hero.m
// homework1
//
// Created by itlab on 2020/10/6.
// Copyright © 2020 itlab. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Hero.h"
@implementation Hero
-(void)PKOneUnit{}
-(NSString*)getName
{
return name;
}
-(NSString*)getCountry
{
return country;
}
-(NSInteger)getAttack
{
return attack;
}
-(NSInteger)getBLood_value
{
return blood_value;
}
-(NSInteger)skill:(NSInteger) di andAtt:(NSInteger) att
{
return 0;
}
-(void)changeBlood:(NSInteger)blood
{
blood_value-=blood;
if(blood_value<0)
blood_value=0;
}
-(NSInteger)dice
{
NSInteger di=(arc4random()% 6)+1;
return di;
}
@end
@implementation LiuBei
-(void)PKOneUnit
{
name=@"刘备";
country=@"蜀";
blood_value=4000;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("刘备发动技能:一波多折,骰子重铸\n");
return 5;
}
return 0;
}
@end
@implementation GuanYu
-(void)PKOneUnit
{
name=@"关羽";
country=@"蜀";
blood_value=4000;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=4)
{
printf("关羽发动技能:赤兔马,攻击力永久+500\n");
attack+=500;
return 4;
}
return 0;
}
@end
@implementation Zhangfei
-(void)PKOneUnit
{
name=@"张飞";
country=@"蜀";
blood_value=4500;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=6)
{
printf("张飞发动技能:莽夫,血量-1000\n");
blood_value-=1000;
if(blood_value<0)
blood_value=0;
}
return 0;
}
@end
@implementation CaoCao
-(void)PKOneUnit
{
name=@"曹操";
country=@"魏";
blood_value=4000;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("曹操发动技能:奸雄,骰子点数+2\n");
return 6;
}
return 0;
}
@end
@implementation XiaHoudun
-(void)PKOneUnit
{
name=@"夏侯惇";
country=@"魏";
blood_value=4500;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=6)
{
printf("夏侯惇发动技能:硬汉,血量+1000\n");
blood_value+=1000;
if(blood_value>4500)
blood_value=4500;
}
return 0;
}
@end
@implementation SiMayi
-(void)PKOneUnit
{
name=@"司马懿";
country=@"魏";
blood_value=3500;
attack=1500;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("司马懿发动技能:路人皆知,敌方骰子点数-2\n");
return 7;
}
return 0;
}
@end
@implementation SunCe
-(void)PKOneUnit
{
name=@"孙策";
country=@"吴";
blood_value=5000;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=6)
{
printf("孙策发动技能:遇刺,血量-1000\n");
blood_value-=1000;
if(blood_value<0)
blood_value=0;
}
return 0;
}
@end
@implementation SunQuan
-(void)PKOneUnit
{
name=@"孙权";
country=@"吴";
blood_value=3500;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("孙权发动技能:运气好,骰子点数变6\n");
return 2;
}
return 0;
}
@end
@implementation ZhouYu
-(void)PKOneUnit
{
name=@"周瑜";
country=@"吴";
blood_value=3500;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("周瑜发动技能:妙计,双方互换骰子点数\n");
return 8;
}
return 0;
}
@end
@implementation LvBu
-(void)PKOneUnit
{
name=@"吕布";
country=@"群";
blood_value=5000;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=6)
{
printf("吕布发动技能:方天画戟,攻击力翻倍\n");
return 1;
}
return 0;
}
@end
@implementation DongZhuo
-(void)PKOneUnit
{
name=@"董卓";
country=@"群";
blood_value=9000;
attack=500;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=2)
{
printf("董卓发动技能:被针对,血量-1000\n");
blood_value-=1000;
if(blood_value<0)
blood_value=0;
}
return 0;
}
@end
@implementation HuaTuo
-(void)PKOneUnit
{
name=@"华佗";
country=@"群";
blood_value=3500;
attack=1000;
}
-(NSInteger)skill:(NSInteger)di andAtt:(NSInteger)att
{
NSInteger d=(arc4random()%6)+1;
if(d>=5)
{
printf("华佗发动技能:回血,血量+500\n");
blood_value+=500;
if(blood_value>3500)
blood_value=3500;
}
return 0;
}
@end
main.m
//
// main.m
// homework1
//
// Created by itlab on 2020/10/6.
// Copyright © 2020 itlab. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Hero.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
printf("Game start!\n");
Hero* one;
Hero* two;
//以下为随机挑选英雄阶段
NSInteger di=(arc4random() % 12)+1;
if(di==1)
{
one=[[LiuBei alloc]init];
}
else if(di==2)
{
one=[[GuanYu alloc]init];
}
else if(di==3)
{
one=[[Zhangfei alloc]init];
}
else if(di==4)
{
one=[[CaoCao alloc]init];
}
else if(di==5)
{
one=[[XiaHoudun alloc]init];
}
else if(di==6)
{
one=[[SiMayi alloc]init];
}
else if(di==7)
{
one=[[SunCe alloc]init];
}
else if(di==8)
{
one=[[SunQuan alloc]init];
}
else if(di==9)
{
one=[[LvBu alloc]init];
}
else if(di==10)
{
one=[[DongZhuo alloc]init];
}
else if(di==11)
{
one=[[ZhouYu alloc]init];
}
else
{
one=[[HuaTuo alloc]init];
}
di=(arc4random() % 12)+1;
if(di==1)
{
two=[[LiuBei alloc]init];
}
else if(di==2)
{
two=[[GuanYu alloc]init];
}
else if(di==3)
{
two=[[Zhangfei alloc]init];
}
else if(di==4)
{
two=[[CaoCao alloc]init];
}
else if(di==5)
{
two=[[XiaHoudun alloc]init];
}
else if(di==6)
{
two=[[SiMayi alloc]init];
}
else if(di==7)
{
two=[[SunCe alloc]init];
}
else if(di==8)
{
two=[[SunQuan alloc]init];
}
else if(di==9)
{
two=[[LvBu alloc]init];
}
else if(di==10)
{
two=[[DongZhuo alloc]init];
}
else if(di==11)
{
two=[[ZhouYu alloc]init];
}
else
{
two=[[HuaTuo alloc]init];
}
//初始化英雄
[one PKOneUnit];
[two PKOneUnit];
//输出英雄信息
NSString *name1=[one getName];
NSString *name2=[two getName];
printf("%svs%s\n\n", [name1 UTF8String], [name2 UTF8String]);
printf("%s信息:\n", [name1 UTF8String]);
printf("国家:%s\n", [[one getCountry] UTF8String]);
printf("血量:%ld\n", [one getBLood_value]);
printf("攻击力:%ld\n\n", [one getAttack]);
printf("%s信息:\n", [name2 UTF8String]);
printf("国家:%s\n", [[two getCountry] UTF8String]);
printf("血量:%ld\n", [two getBLood_value]);
printf("攻击力:%ld\n\n", [two getAttack]);
//开始战斗
NSInteger round;
for(round=1;;round++)
{
//掷骰子决定谁可以攻击,点数平就不攻击
printf("Round %ld\n", round);
NSInteger d1=[one dice];
NSInteger d2=[two dice];
NSInteger att1=[one getAttack];
NSInteger att2=[two getAttack];
printf("骰子点数:%ld : %ld\n", d1, d2);
//判断技能是否发动,根据返回值不同对属性进行更改
NSInteger check1=[one skill:d1 andAtt:att1];
NSInteger check2=[two skill:d2 andAtt:att2];
if(check1==1)
{
att1+=att1;
}
else if(check1==2)
{
d1=6;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check1==3)
{
att2=att2/2;
}
else if(check1==4)
{
att1=[one getAttack];
}
else if(check1==5)
{
d1=[one dice];
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check1==6)
{
d1+=2;
if(d1>6)
d1=6;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check1==7)
{
d2-=2;
if(d2<1)
d2=1;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check1==8)
{
NSInteger temp=d1;
d1=d2;
d2=temp;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
if(check2==1)
{
att2+=att2;
}
else if(check2==2)
{
d2=6;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check2==3)
{
att1=att1/2;
}
else if(check2==4)
{
att2=[two getAttack];
}
else if(check2==5)
{
d2=[two dice];
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check2==6)
{
d2+=2;
if(d2>6)
d2=6;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check2==7)
{
d1-=2;
if(d1<1)
d1=1;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
else if(check2==8)
{
NSInteger temp=d1;
d1=d2;
d2=temp;
printf("骰子点数:%ld : %ld\n", d1, d2);
}
//攻击阶段
if(d1>d2)
{
printf("%s对%s造成%ld点伤害!", [name1 UTF8String], [name2 UTF8String], att1);
[two changeBlood:att1];
}
else if(d1<d2)
{
printf("%s对%s造成%ld点伤害!\n", [name2 UTF8String], [name1 UTF8String], att2);
[one changeBlood:att2];
}
//检测是否存活
printf("剩余血量:%ld:%ld\n\n", [one getBLood_value], [two getBLood_value]);
if([one getBLood_value]==0 && [two getBLood_value]!=0)
{
printf("%s获胜!\n", [name2 UTF8String]);
break;
}
else if([two getBLood_value]==0 && [one getBLood_value]!=0)
{
printf("%s获胜!\n", [name1 UTF8String]);
break;
}
else if([one getBLood_value]==0 && [two getBLood_value]==0)
{
printf("平局!\n");
break;
}
}
}
return 0;
}
总结
首先我掌握了object-c的类如何实现,了解了多态继承的实现方式
不足之处在于main函数代码过多,原因在于我没有学会怎么定义一个函数。