码迷,mamicode.com
首页 > 其他好文 > 详细

飞行棋2.0--输完姓名后全自动,可修改为人机交互模式

时间:2015-09-11 00:10:59      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

 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

技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享

飞行棋2.0--输完姓名后全自动,可修改为人机交互模式

标签:

原文地址:http://www.cnblogs.com/Dast1/p/4799656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!