标签:
1 // 2 // main.m 3 4 #import <Foundation/Foundation.h> 5 #import "GameController.h" 6 int main(int argc, const char * argv[]) 7 { 8 GameController *ctl = [GameController new]; 9 [ctl startGame]; 10 11 // GameMap *map = [GameMap new]; 12 // map = [map makeGameMapWithNums]; 13 14 return 0; 15 }
1 // 2 // GameController.h 3 4 #import <Foundation/Foundation.h> 5 #import "GamePlayer.h" 6 #import "GameMap.h" 7 #import "GameTools.h" 8 #import "GameView.h" 9 10 @interface GameController : NSObject 11 //所有model和view作为属性,才能管理 12 @property (nonatomic, strong) NSMutableArray *gamePlayers; 13 @property (nonatomic, strong) GameMap *gameMapC; 14 @property (nonatomic, strong) GameView *gameView; 15 //#warning gameTools要作为属性?不需要,工具是共享的,不是属性 16 17 /** 18 * 开始游戏 19 */ 20 - (void)startGame; 21 22 @end
1 /* 2 GameController.m 3 类:控制器,视图界面,玩家,地图,单例对象工具 4 1.控制器:拥有其他所有类,作为属性。玩家俩个用可变数组存储,方便读写数据。重写构造方法,把属性初始化。 5 2.视图界面:所有跟控制台相关的都在这实现,输入输出等。重写构造方法,传入控制器重构的地图。 6 3.地图类,打印地图(5中元素,枚举法0 - 4,遍历输出时先判断位置上是否有玩家、几个,没有的话才判断枚举的类型) 7 需要一个数组,重构,初始化一个数组给数组属性。(96个元素) 8 4.工具类:为了创建单例对象,写shared开头的类方法。重写allocWithZone方法 9 和init方法(初始化地图组成元素的共享数据) 10 5.玩家类:有姓名(空格无效,长度不能小于4,不能重名)、标志(sign)、地图中位置、步数。前进、后退方法, 11 初始化方法(name和sign作参数),掷骰子方法。 12 13 14 15 16 ps:.每实现一个小功能就测试一下 17 18 已解决: 19 1.移动时要有动画效果。 20 3.调试时,可手动修改玩家移动的步数。 21 4.私有方法写延展里。不确定的不写延展里。 22 7.按大框架走。先大局,后细节!初始化属性时,由高层到底层。 23 8.名字和标号在合适的地方显示。 24 9.玩家移动写成一个每次走一步的方法,方向枚举。 25 10.动画由for循环控制:玩家移动, 清屏并刷新地图 睡眠0.3s。 26 灵魂交换用动画方法效果不理想,故改为了基本方法搭积木实现。 27 */ 28 29 #import "GameController.h" 30 31 @interface GameController ()//私有方法 32 - (instancetype)init; 33 /** 34 * 初始化玩家 35 */ 36 - (void)initPlayers; 37 38 /** 39 * 显示地图 40 */ 41 - (void)showGameMap; 42 43 /** 44 * showMap判断代码 45 * 46 * @param index map数组下标 47 */ 48 - (void)switchOfShowGameMapWithNum:(int)index; 49 50 /** 51 * 清屏。showlogo 52 */ 53 - (void)F5; 54 55 /** 56 * CLM 57 */ 58 - (void)clearScreenAndshowLogoAndShowMap; 59 60 /** 61 玩家掷骰子 62 */ 63 - (void)playersPlayDice; 64 65 /** 66 * 动画效果 67 * 68 * @param drt 方向,枚举k开头 69 * @param steps 步数 70 * @param player 玩家对象 71 */ 72 - (void)animationOfMovingWithDirection:(Direction)drt andSteps:(NSUInteger)steps 73 andPlayer:(GamePlayer*)player; 74 75 /** 76 * 确定是哪一个玩家 77 * 78 * @param player 传入的玩家 79 * 80 * @return 哪一个玩家 81 */ 82 - (GamePlayer*)whichOneOfThePlayer:(GamePlayer*)player; 83 84 /** 85 * 取得另一个玩家对象 86 * 87 * @param player 当前玩家 88 * 89 * @return 另一个玩家 90 */ 91 - (GamePlayer*)getTheOtherPlayer:(GamePlayer*)player; 92 93 - (BOOL)processOfLuckyPlatewithNum:(int)num andPlayer:(GamePlayer*)player; 94 95 @end 96 97 98 @implementation GameController 99 100 101 - (BOOL)processOfLuckyPlatewithNum:(int)num andPlayer:(GamePlayer*)player 102 { 103 //1.灵魂互换 2.轰炸对方 104 [self.gameView showMsgWith:@"恭喜到达幸运轮盘:请选择一个愿望:1.灵魂互换 2.轰炸对方\n"]; 105 [NSThread sleepForTimeInterval:1]; 106 num = [self.gameView getPlayerInputNumber]; 107 GamePlayer *p1 = [self.gamePlayers firstObject]; 108 GamePlayer *p2 = [self.gamePlayers lastObject]; 109 int destance =(int) p1.position - (int)p2.position;//防越界,每个都强转 110 if (1 == num) 111 { 112 if (destance > 0) 113 { 114 { 115 //下两行效果是p1先移到p2处,p2再移到p1原来的位置,不太好看 116 // [self animationOfMovingWithDirection:0 andSteps:destance andPlayer:p1]; 117 // [self animationOfMovingWithDirection:1 andSteps:destance andPlayer:p2]; 118 } 119 for (int k = 0; k < destance; k++) 120 { 121 [p1 moveOneStepWithDirection:0]; 122 [p2 moveOneStepWithDirection:1]; 123 [self clearScreenAndshowLogoAndShowMap]; 124 [NSThread sleepForTimeInterval:0.3]; 125 } 126 127 }else 128 { 129 // //步数记得加负号 130 for (int k = 0; k < -destance; k++) 131 { 132 {//不能实现同步走,只能实现一个走一步,另一个走一步,循环,因为animat方法里 133 //NSThreat方法,故不能实现同步,改为下面方法,最原始方法搭积木 134 // [self animationOfMovingWithDirection:1 andSteps:1 andPlayer:p1]; 135 // [self animationOfMovingWithDirection:0 andSteps:1 andPlayer:p2]; 136 } 137 [p2 moveOneStepWithDirection:0]; 138 [p1 moveOneStepWithDirection:1]; 139 [self clearScreenAndshowLogoAndShowMap]; 140 [NSThread sleepForTimeInterval:0.3]; 141 } 142 143 } 144 }else 145 { 146 if ([player isEqualTo:p1]) 147 { 148 [self animationOfMovingWithDirection:kBackward andSteps:8 149 andPlayer:p2]; 150 }else 151 { 152 [self animationOfMovingWithDirection:kBackward andSteps:8 153 andPlayer:p1]; 154 } 155 } 156 return NO;//防止死循环switch 157 158 } 159 160 - (GamePlayer *)getTheOtherPlayer:(GamePlayer *)player 161 { 162 if (player == [self.gamePlayers firstObject]) 163 { 164 return self.gamePlayers.lastObject; 165 }else 166 { 167 return self.gamePlayers.firstObject; 168 } 169 } 170 171 - (GamePlayer*)whichOneOfThePlayer:(GamePlayer*)player 172 { 173 if (player == [self.gamePlayers firstObject]) 174 { 175 return self.gamePlayers.firstObject; 176 }else 177 { 178 return self.gamePlayers.lastObject; 179 } 180 } 181 182 //10.动画由for循环控制:玩家移动, 清屏并刷新地图 睡眠0.3s 183 - (void)animationOfMovingWithDirection:(Direction)drt andSteps:(NSUInteger)steps 184 andPlayer:(GamePlayer *)player 185 { 186 for (int i = 0; i < steps; i++) 187 { 188 //先判断是哪个玩家 189 GamePlayer *p = [self whichOneOfThePlayer:player]; 190 GamePlayer *pT = nil; 191 GamePlayer *pFirst = [self.gamePlayers firstObject]; 192 193 [p moveOneStepWithDirection:drt]; 194 [self clearScreenAndshowLogoAndShowMap]; 195 196 if (p.position >= [GameTools new].lengthOfMap - 1) 197 { 198 //每走一步都判定是否胜利,防隐形走位的bug 199 NSString *str= [NSString stringWithFormat:@"恭喜%@ 号玩家%@取得胜利" 200 , p.sign, p.name ]; 201 [self.gameView showMsgWith:str]; 202 203 //结束游戏,为防止玩家2继续for循环,把他的TrafficLight属性变为 非1 204 205 pT =[self.gamePlayers lastObject]; 206 207 //效果同下!汗,注意点语法在 = 左右的意思,左边是get方法赋值,右边get取值 208 // pT.trafficFlag = 0; 209 [pT setTrafficFlag:0]; 210 211 212 //让while循环掷骰子停止,不初始化默认为0,while执行 213 pFirst.isGameOver = 1; 214 215 break;//不能用return 0; 因为这是无返回值的方法。且这个break只能跳出本方法for循环 216 }else if (p.position == 0)//后退到初始位置时,也跳出本for循环,结束动画效果 217 { 218 break; 219 } 220 [NSThread sleepForTimeInterval:0.3]; 221 222 } 223 224 } 225 226 - (void)startGame 227 { 228 //清空视图 229 [self.gameView clearScreen]; 230 231 //showlogo 232 [self.gameView showLogo]; 233 234 //初始化玩家(2个) 235 [self initPlayers]; 236 237 //show map 238 [self showGameMap];//不需要传自己的地图了,初始化时候已经传过了 239 240 //玩家轮流掷骰子,按点数移动,判断移动后位置关卡类型并响应 241 [self playersPlayDice]; 242 243 //游戏结束:在上一步骤实现 244 245 246 247 } 248 249 - (void)playersPlayDice//如果响应方法封装了,可以在最后加一个switch判断方法,实现移动后所在文字关卡的判定! 250 { 251 //判断结束,为玩家增加一个属性isGameOver 252 while ([self.gamePlayers.firstObject isGameOver] == 0) 253 { 254 //玩家轮流掷骰子,按点数移动,判断移动后位置关卡类型并响应 255 for (GamePlayer *pTemp in self.gamePlayers) 256 { 257 if (pTemp.trafficFlag == 1) 258 { 259 //view提示玩家掷骰子 暂停 提示点数 260 NSString *str1_1 = [NSString stringWithFormat:@"请%@ 号玩家%@按enter掷骰子\n", 261 pTemp.sign, pTemp.name]; 262 [self.gameView showMsgWith:str1_1]; 263 [self.gameView waitForEnter]; 264 [pTemp playDice]; 265 NSString *str1 = [NSString stringWithFormat:@"您的点数是%ld,按回车移动\n",pTemp. 266 steps]; 267 [self.gameView showMsgWith:str1]; 268 [self.gameView waitForEnter]; 269 270 //按点数在玩家前进方法里修改小人位置 并返回位置给控制器(通过pTemp属性position可以访问) 271 272 [self animationOfMovingWithDirection:kforward andSteps:pTemp.steps andPlayer:pTemp]; 273 274 //控制器根据 小人位置 处关卡类型,来判断关卡响应(抽象方法) 275 NSUInteger position = pTemp.position; 276 GateType gateType = [self.gameMapC.gameMap[position] intValue]; 277 int num = 0;//case里面不能定义变量 278 BOOL flag = YES; 279 while (gateType != kRoads && flag) 280 { 281 switch (gateType)// 实现为了循环判定,在外层加一个循环。结束条件为当前的gateType == kRoad 282 { 283 case kBombs: 284 [self.gameView showMsgWith:@"踩到炸弹了,后退6步\n"]; 285 [NSThread sleepForTimeInterval:2]; 286 //东画面里的break只能跳出他方法里的for循环,这个for循环可能会执行p2后才结束循环 287 //故需要在动画里把另一玩家的 trafficFlag属性置为 非 1 288 289 //小人后退动画 290 [self animationOfMovingWithDirection:kBackward andSteps:6 291 andPlayer:pTemp]; 292 break; 293 case kPlanes: 294 [self.gameView showMsgWith:@"遇到飞机了,带你装x带你飞!前进10步\n"]; 295 [NSThread sleepForTimeInterval:2]; 296 297 [self animationOfMovingWithDirection:kforward andSteps:10 298 andPlayer:pTemp]; 299 break; 300 case kRoads: 301 //道路,不响应 302 break; 303 case kTrafficLights: 304 [self.gameView showMsgWith:@"红绿灯,被暂停两次!"]; 305 pTemp.trafficFlag = -1; 306 flag = NO; 307 break; 308 case kLuckyPlates: 309 flag = [self processOfLuckyPlatewithNum:num andPlayer:pTemp]; 310 break; 311 312 //里面是受诅咒的代码,打开就报错!换到其他位置不会报错。 313 { 314 // 遇到交通灯的人被停止2次(可通过改值设置),设置给玩家一个属trafficFlag(for下行加入这个参数的if == 1判断), 315 // // 遇到灯,赋值为 -1。 在else里flag++ 316 // 317 // case kTrafficLights: 318 // [self.gameView showMsgWith:@"遇到红绿灯了,暂停 2 次!"]; 319 // pTemp.trafficFlag = -1; 320 // break; 321 // case kRoads: 322 // break; 323 // 324 325 //#warning default必须去掉?why 326 } 327 } 328 //控制器根据 玩家位置 进行结束判定(已放到动画里面,更合适) 329 //增加下面语句,为了防止死循环,刷新gateType,才能使控制switch的循环正常判定 330 331 gateType = [self.gameMapC.gameMap[pTemp.position] intValue]; 332 } 333 } 334 else 335 { 336 pTemp.trafficFlag++; 337 } 338 } 339 } 340 } 341 342 - (void)showGameMap 343 { 344 //#warning 人物标志打印先不实现 345 //第一行: 正序打印,0-29 346 for (int i = 0; i <= 29; i++) 347 { 348 //打印函数 349 [self switchOfShowGameMapWithNum:i]; 350 } 351 [self.gameView showMsgWith:@"\n"]; 352 353 354 //第2-4行:前29个时空格,最后一个是map数组元素 30-32 355 for (int i = 30; i <= 32; i++) 356 { 357 for (int j = 0; j < 29; j++) 358 { 359 [self.gameView showMsgWith:@" "]; 360 } 361 [self switchOfShowGameMapWithNum:i]; 362 [self.gameView showMsgWith:@"\n"]; 363 } 364 365 //第5行: 倒序打印 62-33 366 for (int i = 62; i >= 33 ; i--) 367 { 368 [self switchOfShowGameMapWithNum:i]; 369 } 370 [self.gameView showMsgWith:@"\n"]; 371 //第6-8行:每行一个元素:63 - 65 372 for (int i = 63; i <= 65; i++) 373 { 374 [self switchOfShowGameMapWithNum:i]; 375 [self.gameView showMsgWith:@"\n"]; 376 } 377 378 //第9行: 正序打印 66 - 95 379 for (int i = 66; i <= [GameTools new].lengthOfMap - 1; i++) 380 { 381 //打印函数 382 [self switchOfShowGameMapWithNum:i]; 383 } 384 [self.gameView showMsgWith:@"\n"]; 385 386 387 388 } 389 390 - (void)switchOfShowGameMapWithNum:(int)index//不必引入人物对象,控制器能直接拿到的啊! 391 { 392 //先判断小人,if 两人重叠 else 某一人 393 //打印函数 394 NSUInteger positionOfP1 = [[self.gamePlayers firstObject] position]; 395 NSUInteger positionOfP2 = [[self.gamePlayers lastObject] position]; 396 NSString *strTemp = nil; 397 if (positionOfP1 == index && positionOfP2 == index) 398 { 399 [self.gameView showMsgWith:@"?? "]; 400 }else if(positionOfP1 == index) 401 { 402 strTemp = [NSString stringWithFormat:@"%@ ",[[self.gamePlayers firstObject] sign]]; 403 [self.gameView showMsgWith:strTemp]; 404 }else if (positionOfP2 == index) 405 { 406 strTemp = [NSString stringWithFormat:@"%@ ",[[self.gamePlayers lastObject] sign]]; 407 [self.gameView showMsgWith:strTemp]; 408 }else 409 { 410 int numOfgameMap = [self.gameView.mapOfView.gameMap[index] intValue]; 411 switch (numOfgameMap) 412 { 413 case 0: 414 [self.gameView showMsgWith:@"?? "]; 415 break; 416 case 1: 417 [self.gameView showMsgWith:@"?? "]; 418 break; 419 case 2: 420 [self.gameView showMsgWith:@"?? "]; 421 break; 422 case 3: 423 [self.gameView showMsgWith:@"?? "]; 424 break; 425 case 4: 426 [self.gameView showMsgWith:@"?? "]; 427 break; 428 default: 429 break; 430 } 431 432 433 } 434 } 435 436 - (void)F5 437 { 438 [self.gameView clearScreen]; 439 [self.gameView showLogo]; 440 } 441 442 - (void)clearScreenAndshowLogoAndShowMap 443 { 444 [self F5]; 445 [self showGameMap]; 446 } 447 448 - (void)initPlayers 449 { 450 //获取姓名:提示输入玩家1姓名,接收,判断 451 self.gamePlayers = [self.gameView getNameOfPlayers]; 452 453 } 454 455 - (instancetype)init 456 { 457 if (self = [super init]) 458 { 459 self.gameMapC = [[GameMap new] makeGameMapWithNums];//初始化好里面的数字 460 461 //#warning 不传地图可? 不可以,打印地图是由GameView打印的,所以必须给他自己控制器里产生的地图才正确。 462 self.gameView = [GameView gameViewWithMap:self.gameMapC]; 463 464 self.gamePlayers = [NSMutableArray array]; 465 } 466 return self; 467 } 468 469 470 @end
// // GameView.h // 150908飞行棋第二遍 #import <Foundation/Foundation.h> #import "GameMap.h" #import "GamePlayer.h" @interface GameView : NSObject @property (nonatomic,strong) GameMap* mapOfView;//要打印地图,所以要有这个属性 - (void)showMsgWith:(NSString*)msg; /** * 清空终端屏幕 */ - (void)clearScreen; /** * 显示图标 */ - (void)showLogo; /** * 获取玩家姓名 * * @return 有符合条件的两个玩家姓名的可变数组 */ - (NSMutableArray*)getNameOfPlayers; - (void)waitForEnter; /** * 接收玩家输入的数字 * * @return 玩家输入的数字 */ - (int)getPlayerInputNumber; + (instancetype)gameViewWithMap:(GameMap*)map; @end
1 // 2 // GameView.m 3 // 150908飞行棋第二遍 4 // 5 // Created by LongMa on 15/9/8. 6 // Copyright (c) 2015年 Dast. All rights reserved. 7 // 8 9 #import "GameView.h" 10 11 @interface GameView () 12 - (instancetype)initWithMap:(GameMap*)map; 13 14 @end 15 @implementation GameView 16 17 18 - (int)getPlayerInputNumber 19 { 20 int num = 0; 21 // rewind(stdin); 22 // scanf("%d",&num ); 23 24 //全自动实现的代码 25 num = arc4random_uniform(2) + 1; 26 NSString *str1 = [NSString stringWithFormat:@"我的选择是%@\n",num == 1 ? @"灵魂互换" : @"轰炸对方"]; 27 [self showMsgWith:str1]; 28 [NSThread sleepForTimeInterval:1]; 29 30 return num; 31 } 32 - (instancetype)initWithMap:(GameMap*)map 33 { 34 if (self = [super init]) 35 { 36 _mapOfView = map; 37 } 38 return self; 39 } 40 41 /** 42 * 初始化传入的map给_gameMap; 43 * 44 * @param map 传入的 45 * 46 * @return 推荐使用 47 */ 48 + (instancetype)gameViewWithMap:(GameMap *)map 49 { 50 return [[self alloc]initWithMap:map]; 51 } 52 53 /** 54 * 打印单条信息,不换行 55 * 56 * @param msg 传入的OC字符串 57 */ 58 - (void)showMsgWith:(NSString *)msg 59 { 60 printf("%s",[msg UTF8String]); 61 } 62 63 /** 64 * 清空终端屏幕 65 */ 66 - (void)clearScreen 67 { 68 system("clear"); 69 } 70 71 72 73 /** 74 * 获取玩家姓名 75 */ 76 - (NSMutableArray*)getNameOfPlayers 77 { 78 NSMutableArray *arr1 = [NSMutableArray array]; 79 GamePlayer *p1 = [GamePlayer new]; 80 GamePlayer *p2 = [GamePlayer new]; 81 NSString *name = nil; 82 char ch1[30]; 83 NSUInteger len = 0; 84 while (2) 85 { 86 [self showMsgWith:@"请输入玩家1姓名,长度不小于4,输入的空格无效\n"]; 87 rewind(stdin); 88 fgets(ch1, 30, stdin); 89 if (ch1[strlen(ch1) - 1] == ‘\n‘) 90 { 91 ch1[strlen(ch1) - 1] = ‘\0‘; 92 } 93 name = [NSString stringWithUTF8String:ch1];// 转为OC,用withFormat也可以,用%s 94 name = [name stringByReplacingOccurrencesOfString:@" " withString:@""]; 95 len = [name length]; 96 if (len < 4) 97 { 98 [self showMsgWith:@"长度小于4,不符合要求"]; 99 }else 100 { 101 [self showMsgWith:@"玩家1初始化成功,按会车继续\n\n"]; 102 p1 = [GamePlayer gamePlayerWithName:name andSigh:@"1??"]; 103 [arr1 addObject:p1]; 104 //waitForEnter 105 [self waitForEnter]; 106 [self clearScreen]; 107 [self showLogo]; 108 break; 109 } 110 } 111 112 while (2) 113 { 114 [self showMsgWith:@"请输入玩家2姓名,长度不小于4,输入的空格无效,不能与玩家1重名\n"]; 115 rewind(stdin); 116 fgets(ch1, 30, stdin); 117 if (ch1[strlen(ch1) - 1] == ‘\n‘) 118 { 119 ch1[strlen(ch1) - 1] = ‘\0‘; 120 } 121 name = [NSString stringWithUTF8String:ch1];// 转为OC,用withFormat也可以,用%s 122 name = [name stringByReplacingOccurrencesOfString:@" " withString:@""]; 123 len = [name length]; 124 if (len < 4) 125 { 126 [self showMsgWith:@"长度小于4,不符合要求"]; 127 }else if([name isEqualToString:[[arr1 firstObject] name]]) 128 { 129 [self showMsgWith:@"与玩家1重名"]; 130 }else 131 { 132 [self showMsgWith:@"玩家2初始化成功\n"]; 133 p2 = [GamePlayer gamePlayerWithName:name andSigh:@"2??"]; 134 [arr1 addObject:p2]; 135 [self waitForEnter]; 136 [self clearScreen]; 137 [self showLogo]; 138 break; 139 } 140 } 141 142 return arr1; 143 } 144 145 146 - (void)waitForEnter 147 { 148 // char c1 = ‘a‘; 149 // rewind(stdin); 150 // scanf("%c",&c1); 151 [NSThread sleepForTimeInterval:1]; 152 153 } 154 155 - (void)showLogo 156 { 157 [self showMsgWith:@"############################################################\n"]; 158 [self showMsgWith:@"# #\n"]; 159 [self showMsgWith:@"# 广州传智播客iOS学科OOP项目之-飞行棋 #\n"]; 160 [self showMsgWith:@"# 1?? 玩家1 2?? 玩家2 ?? 平路 ?? 幸运轮盘 #\n"]; 161 [self showMsgWith:@"# ?? 炸弹 ?? 交通故障 ?? 飞机穿越 #\n"]; 162 [self showMsgWith:@"############################################################\n"]; 163 } 164 165 @end
1 // 2 // GamePlayer.h 3 // 150908飞行棋第二遍 4 //5.玩家类:有姓名(空格无效,长度不能小于4,不能重名)、标志(sign)、地图中位置。前进、后退方法,初始化方法(name和sign作参数),掷骰子方法。 5 6 #import <Foundation/Foundation.h> 7 #import "GameTools.h" 8 typedef enum 9 { 10 kBackward = 0, 11 kforward = 1 12 }Direction; 13 14 @interface GamePlayer : NSObject 15 16 @property (nonatomic, copy) NSString *name, *sign; 17 @property (nonatomic, assign) NSUInteger position,steps, trafficFlag, isGameOver;//trafficFlag,遇到交通灯下次是否执行的判断标准 18 19 - (void)playDice; 20 - (void)moveForwardWithSteps:(NSUInteger)steps; 21 - (void)moveBackwardWithSteps:(NSUInteger)steps; 22 /** 23 * 在前进和后退方法的基础上,创建的 走一步的、可选方向的 方法 24 * 25 * @param direction 玩家方向,枚举类型 26 */ 27 - (void)moveOneStepWithDirection:(Direction)direction; 28 29 + (instancetype)gamePlayerWithName:(NSString*)name andSigh:(NSString*)sign; 30 31 @end
1 // 2 // GamePlayer.m 3 // 150908飞行棋第二遍 4 // 5 // Created by LongMa on 15/9/8. 6 // Copyright (c) 2015年 Dast. All rights reserved. 7 // 8 9 #import "GamePlayer.h" 10 @interface GamePlayer () 11 - (instancetype) initWithName:(NSString*)name andSigh:(NSString*)sign; 12 13 @end 14 15 @implementation GamePlayer 16 17 - (void)moveOneStepWithDirection:(Direction)direction 18 { 19 if (direction == kforward) 20 { 21 [self moveForwardWithSteps:1]; 22 }else 23 { 24 [self moveBackwardWithSteps:1]; 25 } 26 } 27 28 //重构-对象方法 29 - (instancetype) initWithName:(NSString*)name andSigh:(NSString*)sign 30 { 31 if (self = [super init]) 32 { 33 _name = name; 34 _sign = sign; 35 } 36 return self; 37 } 38 39 //重构-类方法 40 + (instancetype)gamePlayerWithName:(NSString*)name andSigh:(NSString*)sign 41 { 42 43 return [[self alloc]initWithName:name andSigh:sign ]; 44 45 46 } 47 48 /** 49 * 掷骰子,随机产生1 - 6的数;手动:接收用户输入 50 */ 51 - (void)playDice 52 { 53 //手动 54 { 55 // printf("请输入步数:"); 56 // rewind(stdin); 57 // scanf("%lu",&_steps); 58 // printf("您输入的步数是%lu",_steps); 59 } 60 //自动生成 61 _steps = arc4random_uniform(6) + 1;//没引入stdlib。不报错?不会 62 #warning 上一行,不会。OC框架应该有包含随机数产生方法 63 64 } 65 /** 66 * 玩家向前移动 67 * 68 * @param steps 步数 69 */ 70 - (void)moveForwardWithSteps:(NSUInteger)steps 71 { 72 int temp = (int)(self.position + steps); 73 self.position = (temp > [GameTools new].lengthOfMap) ? [GameTools new].lengthOfMap : temp; 74 //#warning waiting 75 76 } 77 78 /** 79 * 玩家向后移动 80 * 81 * @param steps 步数 82 */ 83 - (void)moveBackwardWithSteps:(NSUInteger)steps 84 { 85 int temp = (int)(self.position - steps); 86 self.position = (temp < 0) ? 0 : temp; 87 } 88 89 90 91 92 93 @end
1 // 2 // GameMap.h 3 // 150908飞行棋第二遍 4 // 3.地图类,打印地图(5种元素,枚举法0 - 4,遍历输出时先判断位置上是否有玩家、几个,没有的话才判断枚举的类型)需要一个数组,重构,初始化一个数组给数组属性。(96个元素) 5 #import <Foundation/Foundation.h> 6 #import "GameTools.h"//构造随机过数字1-6的数组地图时,引入,需要用到关卡的数量 7 8 typedef enum 9 { 10 kRoads = 0, 11 kBombs = 1, 12 kPlanes = 2, 13 kLuckyPlates = 3, 14 kTrafficLights = 4 15 }GateType; 16 17 @interface GameMap : NSObject 18 19 @property (nonatomic, strong) NSMutableArray *gameMap;//96个元素 20 21 22 //构造随机过数字1-4的数组地图,没随机产生的默认为0 23 - (instancetype)makeGameMapWithNums; 24 25 + (instancetype)map; 26 27 28 @end
1 // 2 // GameMap.m 3 // 150908飞行棋第二遍 4 /* 5 { 6 kRoad = 0, 7 kBomb = 1, 8 kPlane = 2, 9 kLuckyPlate = 3, 10 kTrafficLight = 4 11 }GateType; 12 */ 13 // 14 15 #import "GameMap.h" 16 17 @interface GameMap () 18 - (instancetype)init; 19 #warning 迷糊!可变,长度96,明白了,花了好长时间 20 21 @end 22 23 @implementation GameMap 24 25 26 /** 27 * 重构可变数组 28 * 29 * @param map 外界可变map 30 * 31 * @return <#return value description#> 32 */ 33 - (instancetype)init 34 { 35 NSMutableArray *arr = [NSMutableArray array]; 36 for (int i = 0; i < [GameTools new].lengthOfMap ; i++) 37 { 38 [arr addObject:@0];//全初始化为@0,方便initGameMapWithNums 方法里被其他类型的关卡替换 39 } 40 41 if (self = [super init]) 42 { 43 _gameMap = arr; 44 } 45 return self; 46 } 47 48 //类方法重构 49 + (instancetype)map 50 { 51 return [[GameMap alloc]init]; 52 } 53 54 /** 55 * //构造 随机过数字1-6的 数组地图,每种数字的数量由tools决定 56 57 为防止被 alloc后直接调用(此方法没有为属性——gameMap初始化,需要先用init或new方法创建好对象,才能调用),改名为make开头。 58 * 59 * @return <#return value description#> 60 */ 61 #warning 只有初始化(init或new)了得对象才能调用。故没有以init开头 62 - (instancetype)makeGameMapWithNums 63 64 { 65 int temp = 0; 66 int len = (int)[[GameTools new] lengthOfMap]; 67 GameTools *gameTools = [GameTools sharedTools]; 68 for (int i = 0; i < gameTools.numOfBombs; i++) 69 { 70 //#warning 对比老师方法 老师是把i++ 放到if里面,很吊! 71 while (2) 72 { 73 temp = arc4random_uniform(len - 2) + 1;//产生1 - 95的下标,第零位是人 74 75 //是道路,才赋值,如果不是,不赋值,这样实际产生的数目比预期的少! 76 //故在if基础上加了 while死循环和if内break;语句 ,确保for每循环一次必须产生一个有效地位置,然后把关卡赋值到这个位置。 77 if ([self.gameMap[temp] intValue] == 0) 78 { 79 self.gameMap[temp] = @(kBombs); 80 // NSLog(@"第%d个炸弹",i );// 验证是否正确 81 break; 82 } 83 } 84 } 85 86 for (int i = 0; i < gameTools.numOfPlanes; i++) 87 { 88 while (2) 89 { 90 temp = arc4random_uniform(len - 2) + 1;//产生1 - 95的下标,第零位是人 91 if ([self.gameMap[temp] intValue] == 0) 92 { 93 self.gameMap[temp] = @(kPlanes); 94 // NSLog(@"第%d个",i );// 验证是否正确 95 break; 96 } 97 } 98 99 } 100 101 for (int i = 0; i < gameTools.numOfLuckyPlates; i++) 102 { 103 while (2) 104 { 105 temp = arc4random_uniform(len - 2) + 1;//产生1 - 95的下标,第零位是人 106 if ([self.gameMap[temp] intValue] == 0) 107 { 108 self.gameMap[temp] = @(kLuckyPlates); 109 break; 110 } 111 } 112 113 114 } 115 116 for (int i = 0; i < gameTools.numOfTrafficLights; i++) 117 { 118 while (2) 119 { 120 temp = arc4random_uniform(len - 2) + 1;//产生1 - 95的下标,第零位是人 121 if ([self.gameMap[temp] intValue] == 0) 122 { 123 self.gameMap[temp] = @(kTrafficLights); 124 break; 125 } 126 } 127 128 } 129 return self; 130 } 131 132 133 134 135 136 137 138 @end
1 // 2 // GameTools.h 3 // 150908飞行棋第二遍 4 //4.工具类:为了创建单例对象,写shared开头的类方法。重写allocWithZone方法和init方法(初始化地图组成元素的共享数据) 5 6 7 #import <Foundation/Foundation.h> 8 9 @interface GameTools : NSObject 10 @property (nonatomic, assign) NSUInteger numOfBombs; 11 @property (nonatomic, assign) NSUInteger numOfPlanes; 12 @property (nonatomic, assign) NSUInteger numOfLuckyPlates; 13 @property (nonatomic, assign) NSUInteger numOfTrafficLights; 14 @property (nonatomic, assign) NSUInteger lengthOfMap; 15 16 17 + (instancetype)sharedTools; 18 @end
1 // 2 // GameTools.m 3 // 150908飞行棋第二遍 4 // 5 // Created by LongMa on 15/9/8. 6 // Copyright (c) 2015年 Dast. All rights reserved. 7 // 8 9 #import "GameTools.h" 10 11 @interface GameTools () 12 - (instancetype)init; 13 + (instancetype)allocWithZone:(struct _NSZone *)zone; 14 15 16 @end 17 18 @implementation GameTools 19 20 - (instancetype)init 21 { 22 if (self = [super init]) 23 { 24 _numOfBombs = 10; 25 _numOfPlanes = 30; 26 _numOfTrafficLights = 8; 27 _numOfLuckyPlates = 13; 28 _lengthOfMap = 96; 29 } 30 return self; 31 } 32 33 + (instancetype)allocWithZone:(struct _NSZone *)zone 34 { 35 static id instance = nil; 36 if (nil == instance) 37 { 38 instance = [super allocWithZone:zone]; 39 } 40 return instance; 41 } 42 43 + (instancetype)sharedTools 44 { 45 return [[self alloc]init]; 46 47 } 48 49 50 @end
标签:
原文地址:http://www.cnblogs.com/Dast1/p/4799656.html