黑马程序员--C#控制台应用程序之骑士飞行棋
这个项目用到了面向过程中的所有我们所学的知识的综合,如:方法,参数,结构,数组还有三种循环结构等等技术点,做这个项目也是为了巩固这些知识点。下面简单讲述一下飞行棋的规则:
(1) 用户输入玩家的姓名不能为空,并且用户两次输入的玩家姓名不能相同。
(2) 绘制地图,地图上面有很多管卡,比如:☆表示地雷,如果走在上面将会后退6格,◎表示幸运轮盘,可以有两种选择(1 和对方交换位置, 2 可以轰炸对方,是对方后退6格), ▲表示用户暂停一次,而对方可以连续走两次,而 卐表示时空隧道,用户可以前进10格。
(3) 当任何一个用户走动最后就算胜利(只要走到最后就算胜利)
(4) 本游戏中只考虑每个用户第一次遇到的各种情况的结果。
(5) 游戏开始提示第一个用户执行过程,当地一个用户完成后,提示第二个用户执行过程,这样会一直循环下去。
下面来说下视频中讲解到的方法以及代码实现的过程
①.首先写的是主界面的代码,把其定义成一个方法,方便以后初始化地图的时候的调用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 static void ShowUi() 2 { 3 Console.WriteLine("******************************************"); 4 Console.WriteLine("* *"); 5 Console.WriteLine("* 骑 士 飞 行 棋 *"); 6 Console.WriteLine("* *"); 7 Console.WriteLine("******************************************"); 8 }
②.我们通过
static int[] Map = new int[100];//存放每一个地图元素的下标
static int[] playerPos = { 0, 0 };//初始化玩家A和B的坐标,playPos[0]表示A开始的坐标,playerPos[1]表示B开始的坐标
来把地图的下标存放在一个map数组里,每一位下标对应一个格,然后定义绘制地图中的元素的方法(把map数组中的元素替换为飞行棋地图中的元素)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void InitialMap() { int[] luckyTurn = { 6, 23, 40, 55, 69, 83, 98 };//幸运轮盘 1 int[] lanMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };//地雷 2 int[] pause = { 9, 27, 60, 93 };//暂停 3 int[] timeTunnel = { 20, 25, 45, 63, 72, 88, 90 };//时空隧道 4 for (int i = 0; i < luckyTurn.Length;i++ )//替换幸运轮盘的下标为1 { Map[luckyTurn[i]] = 1; } for (int i = 0; i < lanMine.Length;i++ )//替换地雷的下标为2 { Map[lanMine[i]] = 2; } for (int i = 0; i < pause.Length;i++ )//替换暂停的下标为3 { Map[pause[i]] = 3; } for (int i = 0; i < timeTunnel.Length; i++)//替换时空隧道的下标为4 { Map[timeTunnel[i]] = 4; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static string GetMapString(int pos) { string result = ""; if (playerPos[0] == pos && playerPos[1] == pos) { Console.ForegroundColor = ConsoleColor.Yellow; result ="<>"; } else if (playerPos[0] == pos) { Console.ForegroundColor = ConsoleColor.Yellow; result ="A"; } else if (playerPos[1] == pos) { Console.ForegroundColor= ConsoleColor.Yellow; result ="B"; } else { switch (Map[pos]) { case 0: Console.ForegroundColor= ConsoleColor.White; result ="□"; break; case 1: Console.ForegroundColor= ConsoleColor.DarkMagenta; result ="☆"; break; case 2: Console.ForegroundColor=ConsoleColor.Magenta; result ="▲"; break; case 3: Console.ForegroundColor = ConsoleColor.DarkGreen; result ="◎"; break; case 4: Console.ForegroundColor= ConsoleColor.Blue; result ="※"; break; } } return result; }
③.接着来绘制飞行棋的地图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void DrawMap() { Console.WriteLine("图例,※表示时空隧道,▲表示地雷,◎表示暂停一回合,☆表示幸运轮盘"); //画第一行 for (int i = 0; i <= 29;i++ ) { Console.Write(GetMapString(i)); } Console.WriteLine(); //绘制第二列 for (int i = 30; i <= 34;i++ ) { for (int j = 0; j < 29;j++ ) { Console.Write(" "); } Console.WriteLine(GetMapString(i)); } //第三行 for (int i = 64; i >= 35;i-- ) { Console.Write(GetMapString(i)); } Console.WriteLine(); //第四列 for (int i = 65; i <= 69; i++) { Console.WriteLine(GetMapString(i)); } //第五行 for (int i = 70; i <= 99;i++ ) { Console.Write(GetMapString(i)); } Console.WriteLine(); Console.ResetColor(); }
④.然后是检查越界和限制用户在选择命运轮盘时只能选择1或者2的实现方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void CheckPos()//检测越界的方法 { for(int i=0;i<2;i++) { if(playerPos[i]>99) { playerPos[i] = 99; } if(playerPos[i]<0) { playerPos[i] = 0; } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static int ReadInt(int min,int max) { do { int number = 0; try { number = Convert.ToInt32(Console.ReadLine()); if (number < min || number > max) { Console.WriteLine("您的输入有误,请输入1或者2来选择"); continue; } return number; } catch { Console.WriteLine("您的输入有误,请输入1或者2来选择"); } } while (true); }
⑤,最后就是来实现飞行棋游戏的主方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main(string[] args) { Random r = new Random();//掷骰子的变量 int pos = 0;//暂存掷出的骰子数 string[] names=new string[2];//定义一个长度为2数组来存储玩家A和玩家B的姓名 string msg = ""; bool[] isStop = { false, false };//存放上一次是否走到暂停的判断条件,为true时证明走到了暂停 ShowUi(); //调用界面UI Console.WriteLine("请输入玩家A的姓名:"); names[0] = Console.ReadLine(); while (names[0]=="")//判断names[0]即玩家A的姓名是否为空 { Console.WriteLine("玩家A的姓名不能为空格,请重新输入"); names[0] = Console.ReadLine(); } Console.WriteLine("请输入玩家B的姓名"); names[1] = Console.ReadLine(); while(names[1]==""||names[1]==names[0])//判断names[1]即玩家B的姓名是否为空或者与玩家A的姓名相同 { if (names[1] == "") { Console.WriteLine("玩家B的姓名不能为空,请重新输入"); names[1] = Console.ReadLine(); } //if(names[1]==names[0]) else { Console.WriteLine("{0}已被玩家A占用,请输入别的姓名",names[1]); names[1] = Console.ReadLine(); } } Console.Clear();//清屏 //ShowUi(); Console.WriteLine("对战开始......"); Console.WriteLine("玩家{0}的士兵为A",names[0]); Console.WriteLine("玩家{0}的士兵为B", names[1]); string name1 = "<>"; Console.WriteLine("如果玩家A和玩家B在一起,则用{0}表示",name1); InitialMap(); DrawMap(); Console.WriteLine("游戏开始....."); while (playerPos[0] < 99 && playerPos[1] < 99) { if (isStop[0] == false) { #region 玩家A掷骰子 Console.WriteLine("{0}按任意键开始掷骰子......", names[0]); //ConsoleKeyInfo rec = Console.ReadKey(true); Console.ReadKey(true); //if(rec.Key==ConsoleKey.Tab) //{ //} pos = r.Next(1, 7); Console.WriteLine("玩家{0}掷出了:{1}", names[0], pos); Console.ReadKey(true); //if(rec.Key==ConsoleKey.Tab) //{ // ConsoleKeyInfo cc = Console.ReadKey(true); // if(rec.Key==ConsoleKey.F1) // { // pos = ReadInt(1, 100); // } //} playerPos[0] += pos; CheckPos();//检测是否越界 if (playerPos[0] == playerPos[1])//检测A是否踩到B { playerPos[1] = 0; } else//没踩到,再检测是否遇到关卡 { switch (Map[playerPos[0]]) { case 0://普通,无变化 msg = ""; break; case 1://幸运轮盘 Console.Clear(); DrawMap(); //msg = string.Format("{0}踩到了幸运轮盘,请选择运气", names[0]); //msg = string.Format("1--和对方交换位置 2--轰炸对方"); Console.WriteLine("{0}踩到了幸运轮盘,请选择运气", names[0]); Console.WriteLine("1--和对方交换位置 2--轰炸对方"); int userSelect = ReadInt(1, 2); switch (userSelect) { case 1://用户选择1 和对方交换位置 msg = string.Format("{0}选择了和{1}交换位置", names[0], names[1]); //Console.WriteLine("你选择了交换位置......"); //Console.ReadKey(); int temp = playerPos[0]; playerPos[0] = playerPos[1]; playerPos[1] = temp; break; case 2: msg = string.Format("{0}选择了轰炸{1}", names[0], names[1]); //Console.WriteLine("你选择了轰炸对方......"); //Console.ReadKey(); playerPos[1] = playerPos[1] - 6; CheckPos(); break; } break; case 2: msg = string.Format("{0}踩到了地雷,退6格", names[0]); //Console.WriteLine("你踩到了地雷......"); //Console.ReadKey(); playerPos[0] -= 6; break; case 3: msg = string.Format("{0}碰到了暂停,暂停一回合", names[0]); isStop[0] = true; break; case 4: msg = string.Format("{0}进入了时空隧道,前进10格,哇塞,太爽了.....", names[0]); //Console.WriteLine("踩到了时空隧道,哇塞,太爽了....."); //Console.ReadKey(); playerPos[0] += 10; CheckPos(); break; } } #endregion } else { //证明走到了暂停,暂停一回合,然后把判断true改为false isStop[0] = false; } Console.Clear(); DrawMap(); if (isStop[0] == false) { #region 玩家B掷骰子 Console.WriteLine("{0}按任意键开始掷骰子......", names[1]); Console.ReadKey(true); pos = r.Next(1, 7); Console.WriteLine("玩家{0}掷出了:{1}", names[1], pos); Console.ReadKey(true); playerPos[1] += pos; CheckPos();//检测是否越界 if (playerPos[1] == playerPos[0])//检测B是否踩到A { playerPos[0] = 0; } else//没踩到,再检测是否遇到关卡 { switch (Map[playerPos[1]]) { case 0://普通,无变化 msg = ""; break; case 1://幸运轮盘 Console.Clear(); DrawMap(); //msg = string.Format("{0}踩到了幸运轮盘,请选择运气", names[0]); //msg = string.Format("1--和对方交换位置 2--轰炸对方"); Console.WriteLine("{0}踩到了幸运轮盘,请选择运气", names[1]); Console.WriteLine("1--和对方交换位置 2--轰炸对方"); int userSelect = ReadInt(1, 2); switch (userSelect) { case 1://用户选择1 和对方交换位置 msg = string.Format("{0}选择了和{1}交换位置", names[1], names[0]); //Console.WriteLine("你选择了交换位置......"); //Console.ReadKey(); int temp = playerPos[1]; playerPos[1] = playerPos[0]; playerPos[0] = temp; break; case 2: msg = string.Format("{0}选择了轰炸{1}", names[1], names[0]); //Console.WriteLine("你选择了轰炸对方......"); //Console.ReadKey(); playerPos[0] = playerPos[0] - 6; CheckPos(); break; } break; case 2: msg = string.Format("{0}踩到了地雷,退6格", names[1]); //Console.WriteLine("你踩到了地雷......"); //Console.ReadKey(); playerPos[1] -= 6; break; case 3: msg = string.Format("{0}碰到了暂停,暂停一回合", names[0]); isStop[0] = true; break; case 4: msg = string.Format("{0}进入了时空隧道,前进10格,哇塞,太爽了.....", names[1]); //Console.WriteLine("踩到了时空隧道,哇塞,太爽了....."); //Console.ReadKey(); playerPos[1] += 10; CheckPos(); break; } } #endregion } else { //证明走到了暂停,暂停一回合,然后把判断true改为false isStop[0] = false; } Console.Clear(); DrawMap(); if(msg!="") { Console.WriteLine(msg); } } if (playerPos[0] >= 99) { Console.WriteLine("{0}胜利了!!!!!!!", names[0]); } else { Console.WriteLine("{0}胜利了!!!!!!!",names[1]); } Console.ReadKey(); }
通过这个游戏我们要掌握方法,任何冗余的代码我们都能够封装成方法,这样的话我们在需要使用这个方法的时候直接调用就可以了。