最近看見一個騎士飛行棋的小游戲代碼,感覺這個代碼中將大多數C#的基礎知識都運用到了,是一個新手檢驗學習成果的有效方法,特此將這個代碼整理一遍。這是一個控制台程式。這是代碼下載地址,代碼中的註釋非常詳細介紹了每段代碼的作用: http://files.cnblogs.com/files/xiaohua
最近看見一個騎士飛行棋的小游戲代碼,感覺這個代碼中將大多數C#的基礎知識都運用到了,是一個新手檢驗學習成果的有效方法,特此將這個代碼整理一遍。這是一個控制台程式。這是代碼下載地址,代碼中的註釋非常詳細介紹了每段代碼的作用:
http://files.cnblogs.com/files/xiaohua92/%E9%AA%91%E5%A3%AB%E9%A3%9E%E8%A1%8C%E6%A3%8B.zip
首先要瞭解一下 騎士飛行棋 這個游戲的游戲規則:
1)參與游戲的一共有兩個人,暫且稱之為A和B.兩個人輪流擲篩子,根據擲得的點數在地圖上移動
2)地圖上有5中元素,分別是無效果:□ 幸運輪盤:◎ 地雷:☆ 暫停:▲ 時空隧道:卍 。其中當走到□時候沒有任何特殊效果,當走到幸運輪盤的時候會讓你選擇是要跟對手交換位置還是要轟炸對手(轟炸效果為讓對手後退6格),當走到地雷的時候會自動倒退6格,當走到暫時的時候下一次暫停擲篩子一次,當走到時空隧道的時候會前進10格
3)如果A踩到了B,既A在B之後到了B所在的位置,此時B將要退回原點
4)為了調試方便,在代碼中給游戲加了一個作弊按鈕:在擲篩子的時候,按Tab鍵之後再按F1鍵的話,會讓玩家自主輸入想要擲的點數
代碼構成:
一共設立了5個類,分別是Program(Main函數所在類)\drawMap(用來繪製地圖)\baseUse(一些必要的基本函數)\Initial(初始化姓名以及地圖等)\match(比賽邏輯) 。其中:
Program類:定義了公共的靜態變數以及Main函數
drawMap類:定義了drawMaps()函數(用來繪製地圖),getMapString()函數(主要用來在繪製地圖的時候,確定當前位置圖標)
baseUse類:定義了ShowUI()函數(用來繪製飛行棋的名稱),ReadInt(int min, int max)函數(用來讀取用戶輸入的數字), checkPos()函數(用來檢查玩家當前位 置是否超出邊界)
Initial類:InitialMap()函數(用來初始化地圖信息),InitialName()函數(用來記錄玩家輸入的用戶名)
match類:Action(int playerNumber)類(用來玩家擲篩子之後的邏輯判斷)
下麵附上所有代碼 :
Program類
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 騎士飛行棋 7 { 8 class Program 9 { 10 //在下麵的數組存儲我們游戲地圖各各關卡 11 //數組的下標為0的元素對應地圖上的第1格 下標為1的元素對應元素第2格...下標為n的元素對應n+1格 12 //在數組中 1:表示幸運輪盤 ◎ 13 // 2: 表示地雷 ☆ 14 // 3: 表示暫停 ▲ 15 // 4: 表示時空隧道 卍 16 // 0: 表示普通 □ 17 public static int[] map = new int[100];//地圖中一共100個點 18 public static string[] names = new string[2];//names[0]中存儲玩家A的姓名,names[1]中存儲玩家B的姓名 19 public static int[] playerPos = { 0, 0 };//playerPos[0]中存儲玩家A的位置,playerPos[1]中存儲玩家B的位置 20 public static int step = 0;//用於存放產生的隨機數 21 public static string input = "";//用於存儲用戶的輸入 22 public static string msg = "";//用於存儲當用戶踩到某個關卡,輸出的話 23 public static bool[] isStop = { false, false };//isStop[0]表示玩家A是否上一次走到暫停,isStop[1]表示玩家B是否上一次走到暫停 24 public static Random r = new Random(); 25 26 27 static void Main(string[] args) 28 { 29 baseUse.ShowUI(); 30 Initial.InitialName(); 31 Console.Clear(); 32 baseUse.ShowUI(); 33 Console.WriteLine("對戰開始......"); 34 Console.WriteLine("{0}用A來表示", names[0]); 35 Console.WriteLine("{0}用B來表示", names[1]); 36 Console.WriteLine("如果AB在同一位置,用<>表示"); 37 Initial.InitialMap(); 38 drawMap.drawMaps(); 39 Console.WriteLine("開始游戲......"); 40 while (playerPos[0] < 99 && playerPos[1] < 99) 41 { 42 match.Action(0);//玩家A擲篩子 43 if (Program.playerPos[0] < 99)//當玩家沒有勝利的時候,玩家B可以繼續擲篩子 44 match.Action(1);//玩家B擲篩子 45 } 46 Console.ReadKey(); 47 } 48 } 49 }View Code
drawMap類
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 騎士飛行棋 7 { 8 class drawMap 9 { 10 public static void drawMaps() 11 { 12 Console.WriteLine("圖例:幸運輪盤:◎ 地雷:☆ 暫停:▲ 時空隧道:卍 ");//向玩家解釋各個圖標的含義 13 //繪製第一行 14 for(int i=0;i<30;i++) 15 Console.Write(getMapString(i)); 16 Console.WriteLine(); 17 //繪製右邊邊第一列 18 for (int i = 30; i < 35; i++) 19 { 20 for (int j = 0; j < 29; j++) 21 Console.Write(" "); 22 Console.Write(getMapString(i)); 23 Console.WriteLine(); 24 } 25 //繪製第二行 26 for (int i = 63; i >= 34; i--) 27 Console.Write(getMapString(i)); 28 Console.WriteLine(); 29 //繪製左邊第一列 30 for (int i = 65; i < 69; i++) 31 { 32 33 Console.Write(getMapString(i)); 34 Console.WriteLine(); 35 } 36 //繪製第三行 37 for (int i = 69; i < 100; i++) 38 Console.Write(getMapString(i)); 39 Console.WriteLine(); 40 } 41 42 static string getMapString(int pos) 43 { 44 string result = ""; 45 if (Program.playerPos[0] == pos&&Program.playerPos[1]==pos) 46 { 47 Console.ForegroundColor = ConsoleColor.Yellow; 48 result = "<>"; 49 } 50 else if (Program.playerPos[0] == pos) 51 { 52 Console.ForegroundColor = ConsoleColor.Yellow; 53 result = "A"; 54 } 55 else if (Program.playerPos[1] == pos) 56 { 57 Console.ForegroundColor = ConsoleColor.Yellow; 58 result = "B"; 59 } 60 else 61 { 62 switch (Program.map[pos]) 63 { 64 case 0: 65 Console.ForegroundColor = ConsoleColor.White;//設置控制台當前位置的顏色為白色 66 result = "□"; 67 break; 68 case 1: 69 Console.ForegroundColor = ConsoleColor.Red; 70 result = "◎"; 71 break; 72 case 2: 73 Console.ForegroundColor = ConsoleColor.Green; 74 result = "☆"; 75 break; 76 case 3: 77 Console.ForegroundColor = ConsoleColor.Blue; 78 result = "▲"; 79 break; 80 case 4: 81 Console.ForegroundColor = ConsoleColor.DarkBlue; 82 result = "卍"; 83 break; 84 } 85 } 86 return result; 87 } 88 } 89 }View Code
baseUse類:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 騎士飛行棋 7 { 8 class baseUse 9 { 10 11 public static void ShowUI() 12 { 13 Console.WriteLine("*******************************************************"); 14 Console.WriteLine("* *"); 15 Console.WriteLine("* 騎 士 飛 行 棋 *"); 16 Console.WriteLine("* *"); 17 Console.WriteLine("*******************************************************"); 18 19 } 20 /// <summary> 21 /// 用戶輸入一個min-max之間的數字 22 /// </summary> 23 /// <param name="min">最小值</param> 24 /// <param name="max">最大值</param> 25 /// <returns></returns> 26 public static int ReadInt(int min, int max) 27 { 28 while (true) 29 { 30 try 31 { 32 Console.WriteLine("請輸入{0}和{1}之間的數字!", min, max); 33 int number = Convert.ToInt32(Console.ReadLine()); 34 if (number < min || number > max) 35 { 36 Console.WriteLine("請輸入{0}和{1}之間的數字!", min, max); 37 continue; 38 } 39 return number; 40 } 41 catch 42 { 43 Console.WriteLine("輸入的不是數字,請重新輸入!"); 44 } 45 } 46 } 47 48 public static void checkPos() 49 { 50 for (int i = 0; i <= 1; i++) 51 { 52 if (Program.playerPos[i] > 99) 53 { 54 Program.playerPos[i] = 99; 55 } 56 if (Program.playerPos[i] < 0) 57 { 58 Program.playerPos[i] = 0; 59 } 60 } 61 } 62 } 63 }View Code
Initial類:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 騎士飛行棋 7 { 8 class Initial 9 { 10 public static void InitialName() 11 { 12 Console.WriteLine("請輸入玩家A的姓名"); 13 Program.names[0]=Console.ReadLine(); 14 //判斷輸入的姓名是否為空,如果為空的話則提示並要求用戶重新輸入 15 while(Program.names[0]=="") 16 { 17 Console.WriteLine("玩家A姓名不能為空,請重新輸入!"); 18 Program.names[0] = Console.ReadLine(); 19 } 20 21 22 Console.WriteLine("請輸入玩家B的姓名"); 23 Program.names[1] = Console.ReadLine(); 24 while (Program.names[1] == "" || Program.names[0] == Program.names[1]) 25 { 26 if (Program.names[1] == "") 27 { 28 Console.WriteLine("玩家B姓名不能為空,請重新輸入!"); 29 Program.names[1] = Console.ReadLine(); 30 } 31 else if (Program.names[0] == Program.names[1]) 32 { 33 Console.WriteLine("玩家A和玩家B的姓名不能一樣,請重新輸入!"); 34 Program.names[1] = Console.ReadLine(); 35 } 36 } 37 38 } 39 40 41 public static void InitialMap() 42 { 43 //下麵各組數據分別用於存儲幸運轉盤,地雷,暫停和時空隧道的坐標 44 int[] luckyTurn = { 6, 23, 40, 55, 69, 83 };//幸運輪盤 1 45 int[] landMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };//地雷 2 46 int[] pause = { 9, 27, 60, 93 };//暫停 3 47 int[] timeTunnel = { 20, 25, 45, 63, 72, 88, 90 };//時空隧道 4 48 49 //初始化map數組的數據 50 for (int i = 0; i < 100; i++) 51 Program.map[i] = 0; 52 53 //將幸運輪盤的位置填入地圖中 54 for (int i = 0; i < luckyTurn.Length; i++) 55 Program.map[luckyTurn[i]] = 1; 56 //將地雷的位置填入地圖中 57 for (int i = 0; i < landMine.Length; i++) 58 Program.map[landMine[i]] = 2; 59 //將暫停的位置填入地圖中 60 for (int i = 0; i < pause.Length; i++) 61 Program.map[pause[i]] = 3; 62 //將時空隧道的位置填入地圖中 63 for (int i = 0; i < timeTunnel.Length; i++) 64 Program.map[timeTunnel[i]] = 4; 65 66 } 67 68 } 69 }View Code
match類:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 騎士飛行棋 7 { 8 class match 9 { 10 public static void Action(int playerNumber) 11 { 12 if (Program.isStop[playerNumber] == false) 13 { 14 Console.WriteLine("{0}按任意鍵開始擲篩子......", Program.names[playerNumber]); 15 ConsoleKeyInfo sec = Console.ReadKey(true);//讀取用戶在鍵盤上鍵入的內容 16 Program.step = Program.r.Next(1, 7);//產生一個1到6之間的隨機數 17 18 //當用戶先輸入Tab,在輸入F1之後,就進入作弊環節,在狀態下用戶可以任意輸入一個1到100之間的數字來當做自己擲的點數 19 if (sec.Key == ConsoleKey.Tab)//如果用戶鍵入的內容為Tab鍵 20 { 21 ConsoleKeyInfo sec1 = Console.ReadKey(true);//新建一個變數用來讀取用戶在鍵盤上的輸入 22 //如果用戶按下了F1鍵 23 if (sec1.Key == ConsoleKey.F1) 24 { 25 Program.step = baseUse.ReadInt(1, 100);//讓用戶輸入一個1到100之間的數字 26 } 27 } 28 29 Console.WriteLine("{0}擲出了{1}", Program.names[playerNumber], Program.step); 30 Console.WriteLine("{0}按任意鍵開始行動......", Program.names[playerNumber]); 31 Console.ReadKey(); 32 33 Program.playerPos[playerNumber] += Program.step;//用戶向前走step步 34 baseUse.checkPos();//檢查是否超出了邊界 35 36 if (Program.playerPos[playerNumber] == Program.playerPos[1 - playerNumber])//當玩家A/B踩到了玩家B/A的時候 37 { 38 Program.playerPos[1 - playerNumber] = 0; 39 Program.msg = string.Format("{0}踩到了{1},{1}退回了原點", Program.names[playerNumber], Program.names[1 - playerNumber]); 40 } 41 else //如果沒有踩到的話 42 { 43 switch (Program.map[Program.playerPos[playerNumber]]) 44 { 45 case 0://沒有踩到任何機關 46 Program.msg = ""; 47 break; 48 case 1://進入了幸運輪盤 49 Console.Clear(); 50 Console.WriteLine("你走到了幸運輪盤,請選擇運氣?"); 51 Console.WriteLine("1 ---交換位置 2---轟炸對方"); 52 int userSelect = baseUse.ReadInt(1, 2); 53 if (userSelect == 1)//與對方交換位置 54 { 55 int temp = Program.playerPos[playerNumber]; 56 Program.playerPos[playerNumber] = Program.playerPos[1 - playerNumber]; 57 Program.playerPos[1 - playerNumber] = temp; 58 Program.msg = string.Format("{0}選了與對方交換位置", Program.names[playerNumber]); 59 } 60 else//轟炸對方 61 { 62 Program.playerPos[1 - playerNumber] -= 6; 63 Program.msg = string.Format("{0}轟炸了{1},{1}退回了6格", Program.names[playerNumber], Program.names[1 - playerNumber]); 64 baseUse.checkPos(); 65 } 66 break; 67 case 2://踩到了地雷 68 Program.playerPos[playerNumber] -= 6; 69 baseUse.checkPos(); 70 Program.msg = string.Format("{0}踩到了地雷,{0}退了6格", Program.names[playerNumber]); 71 break; 72 case 3: 73 //暫停一次 74 Program.isStop[playerNumber] = true; 75 Program.msg = string.Format("{0}走到了紅燈,下次暫停一次啊", Program.names[playerNumber]); 76 break; 77 case 4: 78 //踩到時空隧道 79 Program.playerPos[playerNumber] += 10; 80 baseUse.checkPos(); 81 Program.msg = string.Format("{0}進入了時空隧道,爽死了,進了10格", Program.names[playerNumber]); 82 break; 83 } 84