[C#]控制台小游戏:骑士飞行棋

 一个控制台的小游戏,看了传智播客的视频制作的,增加一些功能,最多支持4人同时玩。(作弊程序:掷骰子时使用(Ctrl+F12)可以输入1至100步。)

自己第一个编写的作品,花了很多时间调试,可能还有bug。

感觉就是编程确实不容易(对于我这样的零基础菜鸟,哈哈)。

附件是游戏的可执行文件,双击运行就可以玩了。代码也贴出来。

  1. using System; 
  2.  
  3. namespace FlightGame 
  4.     /// <summary> 
  5.     /// ************************************************ 
  6.     /// 
  7.     /// 飞行棋游戏 v1.0 
  8.     ///  
  9.     /// 编写:五子连星(http://stwzlx.blog.51cto.com) 
  10.     /// 
  11.     /// ************************************************ 
  12.     /// </summary> 
  13.     internal class Program 
  14.     { 
  15.         //数组的下标为0的元素对应地图上的第1格,下标为1的元素对应第2格…下标为n的元素对应第n+1格 
  16.  
  17.         /// <summary> 
  18.         /// Map数组用来存放地图的格数 
  19.         /// </summary> 
  20.         private static int[] Map = new int[100]; 
  21.  
  22.         /// <summary> 
  23.         /// playerPos数组存放玩家的座标 
  24.         /// </summary> 
  25.         private static int[] playerPos; 
  26.  
  27.         /// <summary> 
  28.         /// playerIco数组用来存放玩家的标识字符(不能小于玩家人数) 
  29.         /// </summary> 
  30.         private static string[] playerIco = { "A""B""C""D" }; 
  31.  
  32.         /// <summary> 
  33.         /// playerNum变量用来存放玩家的人数 
  34.         /// </summary> 
  35.         private static int playerNum = 0; 
  36.  
  37.         private static void Main(string[] args) 
  38.         { 
  39.             Random r = new Random();    //产生一个随机数 
  40.             int step = 0;   //用于存放临时产生的随机数 
  41.  
  42.             string msg = "";    //设置msg变量用来接收玩家掷骰子后的信息 
  43.  
  44.             bool win = false;   //设置win变量来存放是否有玩家获胜 
  45.  
  46.             ShowUI(); 
  47.  
  48.             playerNum = PlayerNum();    //调用PlayerNum()方法获得用户输入的人数 
  49.  
  50.             playerPos = new int[playerNum];     //根据玩家人数产生初始座标 
  51.  
  52.             string[] name = PlayerName(playerNum);  //调用PlayerName()方法得到每一个玩家的暱称 
  53.  
  54.             bool[] isStop = new bool[playerNum];  //根据玩家人数产生一个数组,存放玩家是否处于暂停状态 
  55.  
  56.             Console.Clear(); 
  57.  
  58.             ShowUI(); 
  59.  
  60.             //初始化地图数据 
  61.             InitialMap(); 
  62.  
  63.             //绘制地图 
  64.             DrawMap(); 
  65.  
  66.             Console.WriteLine("开始游戏……"); 
  67.  
  68.             while (win == false)    //判断是否有人胜出 
  69.             { 
  70.                 for (int i = 0; i < playerNum; i++)     //根据玩家人数循环游戏 
  71.                 { 
  72.                     if (isStop[i] == true)      //当前玩家是否暂停一次 
  73.                     { 
  74.                         isStop[i] = false;      //恢复暂停标记为未暂停 
  75.                         Console.WriteLine("{0}暂停一次!", name[i]); 
  76.                         Console.WriteLine("*****************************"); 
  77.                         continue;  //当前玩家暂停一次,继续循环 
  78.                     } 
  79.                     else 
  80.                     { 
  81.                         Console.WriteLine("{0}按任意键开始掷骰子……", name[i]); 
  82.  
  83.                         //取得用户按下的键 
  84.                         ConsoleKeyInfo rec = Console.ReadKey(true);    //Console.ReadKey(true)不显示用户按下的键 
  85.  
  86.                         //作弊键 
  87.                         if (rec.Key == ConsoleKey.F12 && rec.Modifiers==ConsoleModifiers.Control)  //按下 Ctrl + F12 键 
  88.                         { 
  89.                             step = Num(1, 100); 
  90.                         } 
  91.                         else 
  92.                         { 
  93.                             step = r.Next(1, 7);    //得到一个1到6之间的随机数 
  94.                         } 
  95.  
  96.                         Console.WriteLine("{0}掷出了:{1}", name[i], step); 
  97.  
  98.                         Console.WriteLine("按任意键开始行动……"); 
  99.  
  100.                         Console.ReadKey(true); 
  101.  
  102.                         playerPos[i] += step;   //玩家向前走了掷出点数的格数 
  103.                         CheckPos(); //判断玩家走动后的格数是否超界 
  104.  
  105.                         bool encounter = false;     //用来存储是否有玩家被踩到 
  106.  
  107.                         //判断当前玩家是否踩到某一位玩家 
  108.                         for (int j = 0; j < playerNum; j++) 
  109.                         { 
  110.                             if (i != j && playerPos[i] == playerPos[j]) 
  111.                             { 
  112.                                 playerPos[j] = 0;       //被踩到的玩家退回到起点 
  113.                                 encounter = true;       //标志有玩家被踩到 
  114.                                 msg = string.Format("{0}踩到了{1},{1}退回起点!", name[i], name[j]); 
  115.                                 break
  116.                             } 
  117.                         } 
  118.  
  119.                         //没人被踩到 
  120.                         if (encounter == false
  121.                         { 
  122.                             switch (Map[playerPos[i]])  //当前玩家位置 
  123.                             { 
  124.                                 case 1:     //幸运轮盘 
  125.                                     Console.Clear(); 
  126.                                     ShowUI(); 
  127.                                     DrawMap(); 
  128.  
  129.                                     //获得前一个玩家的编号 
  130.                                     int ex; 
  131.                                     if (i == 0) 
  132.                                     { 
  133.                                         ex = playerNum - 1; 
  134.                                     } 
  135.                                     else 
  136.                                     { 
  137.                                         ex = i - 1; 
  138.                                     } 
  139.  
  140.                                     Console.WriteLine("请选择运气(1:和{0}交换位置;2:轰炸{0}):", name[ex]); 
  141.  
  142.                                     int userSelect = Num(1, 2);     //让用户选择使用哪种运气 
  143.  
  144.                                     if (userSelect == 1)    //和前一位玩家交换位置 
  145.                                     { 
  146.                                         int temp = playerPos[i]; 
  147.                                         playerPos[i] = playerPos[ex]; 
  148.                                         playerPos[ex] = temp; 
  149.  
  150.                                         msg = string.Format("{0}和{1}交换了位置", name[i], name[ex]); 
  151.                                     } 
  152.                                     else   //轰炸前一位玩家,使其退6格 
  153.                                     { 
  154.                                         playerPos[ex] = playerPos[ex] - 6; 
  155.                                         CheckPos(); 
  156.                                         msg = string.Format("{0}轰炸{1},{1}退六格", name[i], name[ex]); 
  157.                                     } 
  158.  
  159.                                     break
  160.  
  161.                                 case 2:     //地雷 
  162.                                     playerPos[i] = playerPos[i] - 6;    //当前玩家退后六格 
  163.                                     CheckPos(); 
  164.                                     msg = string.Format("{0}踩到了\"地雷\"退六格", name[i]); 
  165.                                     break
  166.  
  167.                                 case 3:     //暂停 
  168.                                     isStop[i] = true;   //设置当前玩家暂停标记 
  169.                                     break
  170.  
  171.                                 case 4:     //时空隧道 
  172.                                     playerPos[i] = playerPos[i] + 10;   //当前玩家前进10格 
  173.                                     CheckPos(); 
  174.                                     msg = string.Format("{0}走到了\"时空隧道\"前进十格", name[i]); 
  175.                                     break
  176.  
  177.                                 default
  178.                                     msg = ""
  179.                                     break
  180.                             } 
  181.                         } 
  182.                     } 
  183.  
  184.                     Console.Clear(); 
  185.                     ShowUI(); 
  186.                     DrawMap(); 
  187.  
  188.                     //显示玩家遇到关卡等信息 
  189.                     if (msg != ""
  190.                     { 
  191.                         Console.WriteLine(msg); 
  192.                         Console.WriteLine("*****************************"); 
  193.                     } 
  194.  
  195.                     if (playerPos[i] == 99)   //如果当前玩家走到终点,则游戏结束 
  196.                     { 
  197.                         Console.Clear(); 
  198.                         ShowUI(); 
  199.                         DrawMap(); 
  200.                         Console.WriteLine("{0}最先走到终点,获得胜利!!!!", name[i]); 
  201.                         win = true
  202.                         Console.ReadKey(); 
  203.                         break
  204.                     } 
  205.                 } 
  206.             } 
  207.  
  208.             Console.ReadKey(); 
  209.         } 
  210.  
  211.         /// <summary> 
  212.         /// 游戏名称及规则等介绍 
  213.         /// </summary> 
  214.         private static void ShowUI() 
  215.         { 
  216.             Console.SetWindowSize(80, 50); 
  217.  
  218.             Console.WriteLine("*********************************************************************"); 
  219.             Console.WriteLine("*                     骑    士    飞    行    棋                    *"); 
  220.             Console.WriteLine("*         游戏制作:五子连星(http://stwzlx.blog.51cto.com)        *"); 
  221.             Console.WriteLine("*                                                                   *"); 
  222.             Console.WriteLine("*最多4名玩家,轮流掷骰子,有一位先达到终点结束游戏。                *"); 
  223.             Console.WriteLine("*被踩到的玩家退回起点                                               *"); 
  224.             Console.WriteLine("*走到“幸运轮盘”可以选择和前一位玩家交换位置或者轰炸他(使其退6格)*"); 
  225.             Console.WriteLine("*走到“地雷”需要退后6格                                            *"); 
  226.             Console.WriteLine("*走到“暂停”需要暂停掷骰子一次                                     *"); 
  227.             Console.WriteLine("*走到“时空隧道”可以往前移动10格                                   *"); 
  228.             Console.WriteLine("*********************************************************************"); 
  229.         } 
  230.  
  231.         /// <summary> 
  232.         /// 得到用户输入的一个minValue和maxValue之间的整数 
  233.         /// </summary> 
  234.         /// <param name="minValue">最小值</param> 
  235.         /// <param name="maxValue">最大值</param> 
  236.         /// <returns></returns> 
  237.         private static int Num(int minValue, int maxValue) 
  238.         { 
  239.             while (true
  240.             { 
  241.                 try 
  242.                 { 
  243.                     int number = Convert.ToInt32(Console.ReadLine()); 
  244.                     if (number < minValue || number > maxValue) 
  245.                     { 
  246.                         Console.WriteLine("必须输入一个{0}到{1}之间的整数!请重新输入:", minValue, maxValue); 
  247.  
  248.                         continue
  249.                     } 
  250.  
  251.                     return number; 
  252.                 } 
  253.                 catch 
  254.                 { 
  255.                     Console.WriteLine("只能输入一个整数!请重新输入:"); 
  256.                     continue
  257.                 } 
  258.             } 
  259.         } 
  260.  
  261.         /// <summary> 
  262.         /// 获得参加游戏的人数。 
  263.         /// 最小人数为1,playerMax控制最大人数。 
  264.         /// </summary> 
  265.         /// <returns>参加的人数</returns> 
  266.         private static int PlayerNum() 
  267.         { 
  268.             int playerMax = 4;  //最大参加人数 
  269.  
  270.             Console.WriteLine("请输入参加的人数(1—{0}人):", playerMax); 
  271.  
  272.             return Num(1, playerMax);    //返回游戏人数 
  273.         } 
  274.  
  275.         /// <summary> 
  276.         /// 让用户输入每一个玩家的姓名,并返回所有玩家的姓名。 
  277.         /// </summary> 
  278.         /// <param name="number">玩家的人数</param> 
  279.         /// <returns>所有玩家的暱称</returns> 
  280.         private static string[] PlayerName(int number) 
  281.         { 
  282.             //定义一个数组存放玩家姓名 
  283.             string[] name = new string[number]; 
  284.  
  285.             for (int i = 0; i < name.Length; i++) 
  286.             { 
  287.                 Console.WriteLine("请输入第{0}位玩家的姓名:", i + 1); 
  288.                 name[i] = Console.ReadLine(); 
  289.                 while (name[i] == "")   //判断玩家姓名是否为空,为空则重新输入 
  290.                 { 
  291.                     Console.WriteLine("姓名不能为空,请重新输入第{0}位玩家姓名:", i + 1); 
  292.                     name[i] = Console.ReadLine(); 
  293.                 } 
  294.                 if (i > 0)  //判断玩家人数,两位以上需要核对姓名是否相同 
  295.                 { 
  296.                     for (int j = 0; j < i; j++)     //当前输入的玩家姓名与已经存在的所有玩家姓名进行对照,看是否相同 
  297.                     { 
  298.                         if (name[i] == name[j]) 
  299.                         { 
  300.                             Console.WriteLine("该姓名与第{0}位玩家相同,请重新输入第{1}位玩家姓名:", j + 1, i + 1); 
  301.                             name[i] = Console.ReadLine(); 
  302.                         } 
  303.                     } 
  304.                 } 
  305.             } 
  306.             return (string[])name;      //返回玩家姓名 
  307.         } 
  308.  
  309.         /// <summary> 
  310.         /// 设置地图关卡的位置 
  311.         /// </summary> 
  312.         private static void InitialMap() 
  313.         { 
  314.             //在下面的数组存储我们游戏地图各个关卡 
  315.  
  316.             //在数组中用以下数字表示相关图标 
  317.             //1:幸运轮盘—◎ 
  318.             //2:地雷—★ 
  319.             //3:暂停—▲ 
  320.             //4:时空隧道—※ 
  321.             //0:普通—□ 
  322.  
  323.             //定义相关关卡的位置 
  324.             int[] luckyTurn = { 6, 23, 40, 55, 69, 83 };      //幸运轮盘1 
  325.             int[] landMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };      //地雷2 
  326.             int[] pause = { 9, 27, 60, 93 };        //暂停3 
  327.             int[] timeTunel = { 20, 25, 45, 63, 72, 88, 90 };      //时空隧道4 
  328.  
  329.             for (int i = 0; i < luckyTurn.Length; i++) 
  330.             { 
  331.                 Map[luckyTurn[i]] = 1;  //把地图Map的第luckyTurn[i]格设置为1(幸运轮盘) 
  332.             } 
  333.  
  334.             for (int i = 0; i < landMine.Length; i++) 
  335.             { 
  336.                 Map[landMine[i]] = 2;   //把地图Map的第landMine[i]格设置为2(地雷) 
  337.             } 
  338.  
  339.             for (int i = 0; i < pause.Length; i++)  //把地图Map的第pause[i]格设置为3(暂停) 
  340.             { 
  341.                 Map[pause[i]] = 3; 
  342.             } 
  343.  
  344.             for (int i = 0; i < timeTunel.Length; i++)  //把地图Map的第timeTunel[i]格设置为4(时空隧道) 
  345.             { 
  346.                 Map[timeTunel[i]] = 4; 
  347.             } 
  348.         } 
  349.  
  350.         /// <summary> 
  351.         /// 判断当前格应该绘制的图标 
  352.         /// </summary> 
  353.         /// <param name="pos">当前格位置</param> 
  354.         /// <returns>当前格图标</returns> 
  355.         private static string MapIco(int pos) 
  356.         { 
  357.             string ico = "";     //存放要绘制的图标字符 
  358.  
  359.             //判断是否有两个以上的玩家处于当前格上 
  360.             int j = 0; 
  361.             for (int i = 0; i < playerNum; i++) 
  362.             { 
  363.                 if (playerPos[i] == pos)     //判断玩家是否在当前格上 
  364.                 { 
  365.                     j++; 
  366.                     if (j >= 2)     //有两个以上玩家在同一个格上 
  367.                     { 
  368.                         Console.ForegroundColor = ConsoleColor.Yellow;  //设置图标颜色 
  369.                         ico = ("<>"); 
  370.                         return ico; 
  371.                     } 
  372.                 } 
  373.             } 
  374.  
  375.             //判断当前格上是否有某一位玩家存在 
  376.             for (int i = 0; i < playerNum; i++) 
  377.             { 
  378.                 if (playerPos[i] == pos)    //当前格有玩家playerPos[i]存在 
  379.                 { 
  380.                     Console.ForegroundColor = ConsoleColor.Yellow;  //设置图标颜色 
  381.                     ico = playerIco[i];     //获得该玩家的标识字符 
  382.                     return ico; 
  383.                 } 
  384.             } 
  385.  
  386.             switch (Map[pos])     //根据当前格的值来显示相应的图标 
  387.             { 
  388.                 case 1: 
  389.                     Console.ForegroundColor = ConsoleColor.Magenta; //设置图标颜色 
  390.                     ico = ("◎");     //1:幸运轮盘—◎ 
  391.                     break
  392.  
  393.                 case 2: 
  394.                     Console.ForegroundColor = ConsoleColor.Red;    //设置图标颜色 
  395.                     ico = ("★");     //2:地雷—★ 
  396.                     break
  397.  
  398.                 case 3: 
  399.                     Console.ForegroundColor = ConsoleColor.Cyan;    //设置图标颜色 
  400.                     ico = ("▲");     //3:暂停—▲ 
  401.                     break
  402.  
  403.                 case 4: 
  404.                     Console.ForegroundColor = ConsoleColor.Green;   //设置图标颜色 
  405.                     ico = ("※");     //4:时空隧道—※ 
  406.                     break
  407.  
  408.                 default
  409.                     Console.ForegroundColor = ConsoleColor.White;   //设置图标颜色 
  410.                     ico = ("□");     //0:普通—□ 
  411.                     break
  412.             } 
  413.             return ico; 
  414.         } 
  415.  
  416.         /// <summary> 
  417.         /// 绘制地图 
  418.         /// </summary> 
  419.         private static void DrawMap() 
  420.         { 
  421.             //图例及玩家说明文字 
  422.             Console.WriteLine("图例说明:幸运轮盘—◎   地雷—★   暂停—▲   时空隧道—※   普通—□"); 
  423.             Console.Write("玩家说明:多名玩家—<>  "); 
  424.             for (int i = 0; i < playerNum; i++) 
  425.             { 
  426.                 Console.Write("第{0}位玩家:{1}  ", i + 1, playerIco[i]); 
  427.             } 
  428.             Console.WriteLine();    //新起一行 
  429.  
  430.             //画第一行 
  431.             for (int i = 0; i <= 29; i++) 
  432.             { 
  433.                 Console.Write(MapIco(i));       //绘制当前格的图标 
  434.             } 
  435.  
  436.             Console.WriteLine();    //第一行结束,换行 
  437.  
  438.             //画第右边列(包含5行,每行前29格为空字符) 
  439.             for (int i = 30; i <= 34; i++)      //循环绘制5行 
  440.             { 
  441.                 for (int j = 0; j < 29; j++)    //有图标的字符串需要绘制在第30格,因此需要每行前29格绘制两个空字符串 
  442.                 { 
  443.                     Console.Write("  "); 
  444.                 } 
  445.                 Console.WriteLine(MapIco(i)); ;      //绘制当前格的图标,并换行 
  446.             } 
  447.  
  448.             //画第二行 
  449.             for (int i = 64; i >= 35; i--) 
  450.             { 
  451.                 Console.Write(MapIco(i));     //绘制当前格的图标 
  452.             } 
  453.  
  454.             Console.WriteLine();    //第二行结束,换行 
  455.  
  456.             //画第左边列 
  457.             for (int i = 65; i <= 69; i++) 
  458.             { 
  459.                 Console.WriteLine(MapIco(i));      //绘制当前格的图标,并换行 
  460.             } 
  461.  
  462.             //画第三行 
  463.             for (int i = 70; i <= 99; i++) 
  464.             { 
  465.                 Console.Write(MapIco(i));       //绘制当前格的图标 
  466.             } 
  467.  
  468.             Console.WriteLine(); 
  469.  
  470.             Console.ResetColor();   //重置控制台的前景色为默认 
  471.         } 
  472.  
  473.         /// <summary> 
  474.         /// 对玩家的座标是否越界进行判断 
  475.         /// </summary> 
  476.         private static void CheckPos() 
  477.         { 
  478.             for (int i = 0; i < playerNum; i++) 
  479.             { 
  480.                 if (playerPos[i] > 99)      //如果座标超过99格则设置为到99格 
  481.                 { 
  482.                     playerPos[i] = 99; 
  483.                 } 
  484.                 else if (playerPos[i] <= 0) //如果座标超过0格则设置为到0格 
  485.                 { 
  486.                     playerPos[i] = 0; 
  487.                 } 
  488.             } 
  489.         } 
  490.     } 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章