1. 程式人生 > 實用技巧 >第10天c#實現飛行棋

第10天c#實現飛行棋

程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace week2
{
    class Program
    {
        /// <summary>
        /// 座標軸
        /// </summary>
        struct Pos
        {
            public int
X; //x軸座標 public int Y; //y軸座標 } /// <summary> /// 事件型別 /// </summary> enum MapType { none_, //無事件 mine_, //地雷 退6格 spatio_, //
時空隧道 進10格 debar_, //暫停1回合 swap_ //幸運轉盤 p1和pc交換位置 } /// <summary> /// 地圖元素 /// </summary> struct Map { public Pos pos; //方格所在位置的座標 public
string icon; //繪製方格的圖示 方塊□ 地雷● 時空隧道卍 暫停▲ 幸運轉盤◎ public MapType mapType; //事件型別 } /// <summary> /// 玩家 /// </summary> /// <param name="args"></param> struct Player { public Pos pos; //玩家座標 public string icon; //玩家的圖示 ★ public int index; //玩家所在的地圖元素的位置 public bool isDebar; //玩家是否暫停 true表示暫停 false表示否 public int id; //玩家編號 } /// <summary> /// 圍牆 /// </summary> struct Wall { public Pos pos; //圍牆座標 public string icon; //圍牆圖示 # } /// <summary> /// 建立圍牆 /// </summary> /// <param name="walls"></param> static void CreatWall(Wall[,] walls) { Console.ForegroundColor = ConsoleColor.Green; //給圍牆設定綠色 for (int i = 0; i < walls.GetLength(0); i++) { for (int j = 0; j < walls.GetLength(1); j++) { if (i == 0||i==walls.GetLength(0)-1) //第0行和最後1行設定圍牆 { Console.Write("#"); } else if(j==0||j==walls.GetLength(1)-1 || j==walls.GetLength(1)-30) //第0列、最後1列、47列設定圍牆 { Console.Write("#"); } else if(i==walls.GetLength(0)/2-1 && j>walls.GetLength(1)-30) //右側中間隔開 { Console.Write("#"); } else { Console.Write(" "); } } Console.WriteLine(); } Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("圖案說明:無事件□ 地雷● 時空隧道卍 暫停▲ 幸運轉盤◎"); Console.ForegroundColor = ConsoleColor.Gray; //建立好圍牆後顏色設為預設 } /// <summary> /// 建立地圖元素 /// </summary> /// <param name="maps"></param> static void CreatMap(Map[] maps) { Pos startPos; //設定起點座標 startPos.X = 2; //起點x周為2 startPos.Y = 2; //起點y軸為2 maps[0].pos = startPos; //起點座標賦值給地圖第一個元素座標 for (int i = 1; i < 19; i++) //建立第一條路元素 x軸 { maps[i].pos.X = maps[i - 1].pos.X + 1; maps[i].pos.Y = maps[i - 1].pos.Y; maps[i].icon = ""; maps[i].mapType = MapType.none_; } for (int i = 19; i < 19*2; i++) //建立第二條路,y軸 { maps[i].pos.X = maps[i - 1].pos.X; maps[i].pos.Y = maps[i - 1].pos.Y+1; maps[i].icon = ""; maps[i].mapType = MapType.none_; } for (int i = 19*2; i < 19*3-1; i++) //建立第3條路,x軸反方向 { maps[i].pos.X = maps[i - 1].pos.X-1; maps[i].pos.Y = maps[i - 1].pos.Y; maps[i].icon = ""; maps[i].mapType = MapType.none_; } for (int i = 19*3-1; i < maps.Length; i++) //建立第4條路,y軸反方向 { maps[i].pos.X = maps[i - 1].pos.X; maps[i].pos.Y = maps[i - 1].pos.Y-1; maps[i].icon = ""; maps[i].mapType = MapType.none_; } } /// <summary> /// 繪製地圖 /// </summary> /// <param name="args"></param> static void DropMap(Map[] maps) { for (int i = 0; i < maps.Length; i++) { maps[i].icon = GetIcon(maps[i]); //獲取地圖元素的圖示 Console.SetCursorPosition(maps[i].pos.X * 2, maps[i].pos.Y); //設定游標位置 Console.Write(maps[i].icon); //繪製地圖元素 } Console.SetCursorPosition(40, 23); //游標位置移至下方 } /// <summary> /// 獲取圖形 /// </summary> /// <param name="map"></param> static string GetIcon(Map map) { switch (map.mapType) //根據地圖元素的型別,返回不同的元素圖示 { case MapType.none_: map.icon = ""; break; case MapType.mine_: map.icon = ""; break; case MapType.spatio_: map.icon = ""; break; case MapType.debar_: map.icon = ""; break; case MapType.swap_: map.icon = ""; break; default: break; } return map.icon; } /// <summary> /// 設定隨機事件 /// </summary> /// <param name="args"></param> static void MapEvent(Map[] maps, Random r) { //設定地圖元素型別 for (int i = 0; i < maps.Length; i++) { int rn = r.Next(0, 101); if (rn > 90) { maps[i].mapType = MapType.mine_; //地雷概率10% } else if (rn > 85) { maps[i].mapType = MapType.spatio_; //時空隧道 5% } else if (rn > 80) { maps[i].mapType = MapType.swap_; //幸運轉盤5% } else if (rn > 70) { maps[i].mapType = MapType.debar_; //暫停10% } else { maps[i].mapType = MapType.none_; } } } /// <summary> /// 建立角色 /// </summary> /// <param name="players"></param> /// <param name="map"></param> static void CreatPlayer(Player[] players, Map[] map) { for (int i = 0; i < players.Length; i++) { players[i].pos = map[0].pos; //定義玩家起始位置座標為地圖元素第0個座標 players[i].id = i+1; //定義玩家編號 players[i].icon = ""; //玩家圖示 players[i].isDebar = false; //是否暫停 false為否 true為暫停 players[i].index = 0; //玩家當前所在位置 } } /// <summary> /// 繪製角色 /// </summary> /// <param name="args"></param> static void DropPlayer(Player[] players, Map[] maps) { for (int i = 0; i < players.Length; i++) { Console.SetCursorPosition(maps[players[i].index].pos.X * 2, maps[players[i].index].pos.Y); switch(players[i].id) { case 1: Console.ForegroundColor = ConsoleColor.Yellow; //第一個玩家顏色 Console.Write(players[i].icon); //繪製玩家圖示 Console.ForegroundColor = ConsoleColor.Gray; //清除顏色 break; case 2: Console.ForegroundColor = ConsoleColor.Red; //第2個玩家顏色 Console.Write(players[i].icon); //繪製第2個玩家圖示 Console.ForegroundColor = ConsoleColor.Gray; //清除顏色 break; } } Console.SetCursorPosition(40, 22); } /// <summary> /// 角色移動 /// </summary> /// <param name="args"></param> static void MovePlayer(Map[] maps , ref Player player,int num) { player.index += num; //玩家索引位置往前移動幾個位置 //判斷界限 if(player.index>=maps.Length-1) { player.index = maps.Length - 1; //當玩家所以位置超過地圖元素的最後一個位置,則定義玩家索引位置為元素的末尾 } else if(player.index<=0) { player.index = 0; //當玩家所以位置小於地圖元素的第一個位置,則定義玩家索引位置為地圖元素的起始 } else { player.index = player.index; } } /// <summary> /// 交換位置 /// </summary> /// <param name="maps"></param> /// <param name="players"></param> /// <param name="player"></param> static void SwapPos(Map[] maps, Player[] players, ref Player player) { for (int i = 0; i < players.Length; i++) { if (player.id == players[i].id) { #region 交換位置提示資訊 Console.SetCursorPosition(50, 5); //提示資訊 Console.WriteLine("{0}踩中了幸運輪盤,", player.id); int swapId = i == 0 ? players[i + 1].id : players[i - 1].id; //判斷玩家id Console.SetCursorPosition(50, 5); Console.WriteLine("和玩家{0}交換了位置", swapId); #endregion int tmp = player.index; //定義暫存變數接收當前玩家的索引 player.index = i == 0 ? players[i + 1].index : players[i - 1].index; //判斷當前玩家是不是玩家陣列的第一個便利出來的, if (i == 0) //如果是,則跟後一個玩家交換,如果不是,則跟前一個玩家交換 { players[i + 1].index = tmp; } else { players[i - 1].index = tmp; } } } DropMap(maps); //重置地圖 DropPlayer(players, maps); //重置玩家 Console.WriteLine("\a"); //提示交換音 } static void MoveDrop(Map[] maps, Player[] players, ref Player player, int num) { if (num >= 0) { if (player.isDebar == false) { num = player.index + num - maps.Length + 1 >= 0 ? maps.Length -1-player.index : num; //判斷最後一步,如果骰子點數大於所剩格子,則有幾個格子走幾步 for (int j = 0; j < num; j++) { //TODO:玩家移動 MovePlayer(maps, ref player, 1); //實現玩家一步一步前進或倒退的效果 DropMap(maps); DropPlayer(players, maps); Console.WriteLine("\a"); Thread.Sleep(300); } } } else { num = player.index+num <= 0 ? player.index : -num; //判斷玩家所在位置距離起點是否大於所需要退的格子數,如果不足,則退回起點 //num = -num; for (int j = 0; j < num; j++) { //TODO:玩家移動 MovePlayer(maps, ref player, -1); //實現玩家一步一步前進或倒退的效果 DropMap(maps); DropPlayer(players, maps); Console.WriteLine("\a"); Thread.Sleep(300); } } } /// <summary> /// 判斷是否勝出 /// </summary> /// <param name="args"></param> static bool IsWin(ref Player player, Map[] maps) { if(player.index==maps.Length-1) //判斷玩家是否到達終點 { Console.SetCursorPosition(50,5); Console.WriteLine("玩家{0}獲得了勝利",player.id); return true; //如果是則返回true } else { return false; //如果不是則返回false } } /// <summary> /// 突發事件 /// </summary> /// <param name="args"></param> static void GameEvent(Player[] players, ref Player player, Map[] maps,ref bool isGameOver) { Map map = maps[player.index]; //接收玩家所在的地圖元素 switch (map.mapType) { case MapType.none_: //無事件發生 break; case MapType.mine_: //踩中地雷 Clear(); //清除突發狀況前的遊戲情況 #region 踩中地雷提示 Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}踩到了地雷,",player.id); Console.SetCursorPosition(50, 6); Console.WriteLine("後退了6格"); #endregion MoveDrop(maps,players, ref player, -6); //呼叫方法後退6格 isGameOver = IsWin(ref player, maps); //判斷該玩家是否勝出 if (isGameOver == true) { Clear(); //清屏,退出 break; } GameEvent(players, ref player, maps,ref isGameOver); //判斷是否再次有突發事件 break; case MapType.spatio_: //踩中時空隧道 Clear(); //清除突發狀況前的遊戲情況 #region 時空隧道提示資訊 Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}踩到了時光隧道,", player.id); Console.SetCursorPosition(50, 6); Console.WriteLine("前進了10格"); #endregion MoveDrop(maps, players, ref player, 10); //呼叫方法前進10格 isGameOver = IsWin(ref player, maps); //判斷該玩家是否勝出 if (isGameOver == true) //如果勝出,清屏退出 { Clear(); break; } GameEvent(players, ref player, maps,ref isGameOver); //如果沒勝出,判斷是否再次有突發事件 break; case MapType.debar_: //暫停事件 Clear(); //清除突發狀況前的遊戲情況 if (player.isDebar==false) //判斷是否是暫停狀態,如果不是,則狀態轉為暫停 { #region MyRegion Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}踩到了暫停,", player.id); Console.SetCursorPosition(50, 6); Console.WriteLine("暫停1回合"); #endregion player.isDebar = true; } else //如果不是,則清除暫停狀態 { #region 暫停結束提示 Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}解除了暫停", player.id); Console.SetCursorPosition(50, 6); Console.WriteLine("{0,27}"," "); #endregion player.isDebar = false; //狀態改為非暫停 } break; case MapType.swap_: Clear(); //清除突發狀況前的遊戲情況 SwapPos(maps, players, ref player); //GameEvent(players, ref player, maps); break; default: break; } } /// <summary> /// 清理上一回合資訊 /// </summary> /// <param name="args"></param> static void Clear() { Console.SetCursorPosition(50, 2); Console.WriteLine("{0,27}", " "); Console.SetCursorPosition(50, 5); Console.WriteLine("{0,27}", " "); Console.SetCursorPosition(50, 6); Console.WriteLine("{0,27}", " "); } /// <summary> /// 建立骰子 /// </summary> /// <param name="args"></param> static string[,] CreatDice(int num) { string[,] one = { {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, }; string[,] two = { {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, }; string[,] three = { {"■■", " ", " " ," "," "}, {"■■", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", " " ," "," "}, {" ", " ", " " ," ","■■"}, {" ", " ", " " ," ","■■"}, }; string[,] four = { {" ", " ", " " ," "," "}, {" ", " ", " " ," "," "}, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, {" ", " ", " " ," "," "}, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, {" ", " ", " " ," "," "}, }; string[,] five = { {"■■", " ", " " ," ","■■"}, {"■■", " ", " " ," ","■■"}, {" ", " ", " " ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", "■■" ," "," "}, {" ", " ", " " ," "," "}, {"■■", " ", " " ," ","■■"}, {"■■", " ", " " ," ","■■"}, }; string[,] six = { //{"■■", " ", "■■" }, //{"■■", " ", "■■" }, //{" ", " ", " " }, //{"■■", " ", "■■" }, //{"■■", " ", "■■" }, //{" ", " ", " " }, //{"■■", " ", "■■" }, //{"■■", " ", "■■" }, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, {" ", " ", " " ," "," "}, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, {" ", " ", " " ," "," "}, {" ", "■■", " " ,"■■"," "}, {" ", "■■", " " ,"■■"," "}, }; switch (num) { case 1: return one; break; case 2: return two; break; case 3: return three; break; case 4: return four; break; case 5: return five; break; default: return six; break; } } /// <summary> /// 繪製骰子 /// </summary> /// <param name="args"></param> static void DropDice(string[,] dice_, int num) { if (num == 1 || num == 4) { Console.ForegroundColor = ConsoleColor.Red; //如果是1點和4點,骰子是紅色 } else { Console.ForegroundColor = ConsoleColor.Blue; //如果不是1和4點,則都是藍色 } for (int j = 0; j < dice_.GetLength(0); j++) { Console.SetCursorPosition(53, 13 + j); for (int k = 0; k < dice_.GetLength(1); k++) //遍歷二維陣列,繪製骰子 { Console.Write(dice_[j, k]); } Console.WriteLine(); } Console.ForegroundColor = ConsoleColor.Gray; } /// <summary> /// 開機畫面 /// </summary> /// <param name="args"></param> static void StartGame() { Console.SetCursorPosition(10, 3); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine(" iv r: :X :QBq"); Console.WriteLine(" isdMBBBZr .BBBB :SBBBB. DBB BBD .rXQBr"); Console.WriteLine(" BBBBBQBBBBJ MBQQsi XBBBg25. BR gBQJMBQBBJ"); Console.WriteLine(" LBP: BB Q 7BBv :J iv7qvBS:. .J"); Console.WriteLine(" IBrBBQ B5 :BM i5BBBBBQ 7BBBBBQBi7.BBiiBQBQ:"); Console.WriteLine(" BBs. BBBB.PBBQBBBuJ5 KD:BZ . iRBBBdXBgP"); Console.WriteLine(" Bg5YiLi 5BBB 2: B: BBRX Bsr7.B"); Console.WriteLine(" :B BBB. BB 7B .BQ BB..BB B:.:UB"); Console.WriteLine(" SQ7 : bB. LBB gBY BB BUiIBB.vr"); Console.WriteLine(" iBBP: .7 QB2 BBB .QB .Bv YuBBgQBBBB."); Console.WriteLine(" SBBBBBBBQ BQB QBBB QBB rBQ iMR :QL "); Console.WriteLine(" r1dRBB gBBI :BE YBI: BBg .BB .BB "); Console.WriteLine(" :"); Console.SetCursorPosition(32, 21); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("請按任意鍵開始"); Console.SetCursorPosition(32, 25); } static void Main(string[] args) { //TODO:定義開機畫面 StartGame(); //1:定義座標結構體:x軸 y軸 //2:定義事件的列舉型別:方塊none_ 地雷mine_ 時空隧道spatio_ 暫停debar_ 幸運轉盤swap_ //3:定義地圖方格結構體:座標,圖示,事件型別 方塊□ 地雷● 時空隧道卍 暫停▲ 幸運轉盤◎ //4:定義玩家結構體:座標,圖示,所在位置,是否暫停,編號id //5:定義圍牆結構體:座標,圖示 Console.ReadKey(true); Console.Clear(); //6:製作圍牆 Wall[,] walls = new Wall[24,78]; CreatWall(walls); //建立圍牆 //7:製作地圖 先全部實現無特殊事件 一維陣列儲存地圖 Map[] maps = new Map[74]; CreatMap(maps); //呼叫方法繪製圍牆 //8:遍歷地圖,給地圖新增隨機事件 Random r = new Random(); MapEvent(maps, r); //9:繪製地圖 DropMap(maps); //呼叫方法繪製地圖 //10:繪製玩家 Player[] players = new Player[2]; //建立玩家陣列 CreatPlayer(players,maps); //呼叫方法建立角色 DropPlayer(players, maps); //呼叫方法繪製角色 bool isGameOver = false; //11:開始遊戲 右側上顯示玩家事件,右下顯示擲骰子點數 while (true) { //遍歷每個玩家流程 for (int i = 0; i < players.Length; i++) { Console.SetCursorPosition(50, 1); Console.WriteLine("玩家{0}請投擲", players[i].id); //提示哪個玩家開始投擲 if (players[i].isDebar==true) { Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}無法行動", players[i].id); //提示哪個玩家開始投擲 GameEvent(players, ref players[i], maps,ref isGameOver); players[i].isDebar = false; continue; } Console.ReadKey(true); //按任意鍵投擲 Clear(); //清理上回合資訊 int num = r.Next(1, 7); //骰子隨機數 string[,] dice_ = CreatDice(num); //建立骰子 DropDice(dice_, num); //繪製骰子 Console.SetCursorPosition(50, 2); Console.WriteLine("玩家{0}投出了{1}點", players[i].id, num); //提示玩家投出幾點 MoveDrop(maps, players, ref players[i], num); //12:判斷是否有玩家勝出 isGameOver = IsWin(ref players[i], maps); //判斷該玩家到終點 if (isGameOver==true) { Console.SetCursorPosition(50, 1); Console.WriteLine("玩家{0}獲得勝利",players[i].id); Clear(); break; //退出for迴圈 } //13:實現突發事件邏輯 GameEvent(players, ref players[i], maps, ref isGameOver); //突發事件 if (isGameOver == true) //再次判斷是否玩家勝出 { Console.SetCursorPosition(50, 1); Console.WriteLine("玩家{0}獲得勝利", players[i].id); Clear(); break; //退出for迴圈 } //踩中玩家後退6格事件 if (i==0) //判斷當前玩家是1還是2號 { if (players[i].index == players[i + 1].index && players[i+1].index!=0) //判斷玩家所在索引是否跟另一個玩家相同,而且不在起點 { #region 互踩提示資訊 Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}踩到了玩家{1},", players[i].id, players[i + 1].id); Console.SetCursorPosition(50, 6); Console.WriteLine("玩家{0}倒退了6格", players[i + 1].id); #endregion MoveDrop(maps, players, ref players[i+1], -6); //被踩玩家後退6格 GameEvent(players, ref players[i+1], maps,ref isGameOver); //判斷後退後的突發事件 } } else { if (players[i].index == players[i - 1].index && players[i - 1].index != 0) //2號玩家流程 { #region 互踩提示資訊 Console.SetCursorPosition(50, 5); Console.WriteLine("玩家{0}踩到了玩家{1},", players[i].id, players[i - 1].id); Console.SetCursorPosition(50, 6); Console.WriteLine("玩家{0}倒退了6格", players[i - 1].id); #endregion MoveDrop(maps, players, ref players[i - 1], -6); GameEvent(players, ref players[i-1], maps,ref isGameOver); } } } //結束遊戲 if (isGameOver == true) { break; } } Console.ReadKey(); } } }

結果: