/// 112 年工科賽第 4 題 /// 多台無人機操控系統 /// 漆家豪 於海青資訊科 2024/2/8 using System; using System.IO; using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices; namespace DroneControl { public struct Coordinate { public static readonly Coordinate MAX = new Coordinate(50, 50);//最大範圍坐標 public static readonly string NESW = "NESW"; public static readonly Coordinate[] dDirection = new Coordinate[4]//坐標偏移量 { new Coordinate(0 , 1), //北方向 new Coordinate(1 , 0), //東方向 new Coordinate(0 ,-1), //南方向 new Coordinate(-1, 0) //西方向 }; public int x, y , direction; public Coordinate() { x = y = direction = 0; } public Coordinate(int _x, int _y) { x = _x; y = _y; } public Coordinate(int _x, int _y , int d) { x = _x; y = _y; direction = d; } } class Drone { public const int CommandLength = 100;//最長指令數 public Coordinate coordinate; public Drone() { coordinate = new Coordinate(0, 0 , 0); } public Drone(int x, int y, int direction) { coordinate = new Coordinate(x , y , direction); } /// /// 讀取檔案資訊,並執行資訊內容,將結果送到 outputF /// /// 檔案名稱。(可省略後面附屬名 .TXT) /// 無人機數量 /// 飛行空間資訊 public void inputFile(string filename, ref StringBuilder outputF) { try { int[] spaceBoundary;//解讀坐標範圍 Drone drone;//無人機物件 string[] initialPosition;//讀取兩列無人機指令 string commands;//無人機指令碼 filename += (filename.ToUpper().IndexOf(".TXT") >= 0 ? "" : ".TXT"); string[] inputF = File.ReadAllLines("../../../" + filename); int numDrones = int.Parse(inputF[0]);//解讀第 1 列無人機數量 spaceBoundary = Array.ConvertAll(inputF[1].Split(' '), int.Parse);//解讀第 2 列坐標範圍 if ((spaceBoundary[0] > Coordinate.MAX.x) || (spaceBoundary[1] > Coordinate.MAX.y)) { Console.WriteLine($"區域空間超出範圍 ({Coordinate.MAX.x},{Coordinate.MAX.y})\n請更新檔案內容。"); Environment.Exit(0); } Coordinate space = new Coordinate(spaceBoundary[0], spaceBoundary[1]);//建立空間範圍 int currentLine = 2; for (int i = 0; i < numDrones; i++) { initialPosition = inputF[currentLine].Split(' '); drone = new Drone(int.Parse(initialPosition[0]), int.Parse(initialPosition[1]), Coordinate.NESW.IndexOf(initialPosition[2][0])); if ((drone.coordinate.x > Coordinate.MAX.x) || (drone.coordinate.y > Coordinate.MAX.y)) { Console.WriteLine($"第 {currentLine} 列,無人機坐標超出範圍 ({Coordinate.MAX.x},{Coordinate.MAX.y})\n請更新檔案內容。"); Environment.Exit(0); } commands = inputF[currentLine + 1]; if(commands.Length > Drone.CommandLength) { Console.WriteLine($"第 {currentLine + 1} 列,無人機指令超過長度 {Drone.CommandLength}\n請更新檔案內容。"); Environment.Exit(0); } drone.ExecuteCommands(commands , space , ref outputF); currentLine += 2; } Console.WriteLine(outputF.ToString()); File.WriteAllText("../../../out" + filename , outputF.ToString()); } catch (Exception ex) { Console.WriteLine("An error occurred: " + ex.Message); } } /// /// 傳回數字對應文字方向 /// /// /// 0:北,1:東,2:南,3:西 public string getDirection(int direction) { return (Coordinate.NESW.Substring(direction, 1)); } /// /// 傳回是否超出範圍 /// /// 範圍空間 /// 超出範圍為真 public bool outOfRange(Coordinate space) { return ((coordinate.x < 0) || (coordinate.x >= space.x) || (coordinate.y < 0) || (coordinate.y >= space.y)); } /// /// 執行命令字串 /// /// 命令字串 /// 飛行允許空間 /// 飛行狀態紀錄 public void ExecuteCommands(string commands , Coordinate space , ref StringBuilder outputF) { foreach (char command in commands) { switch (command) { case 'L': coordinate.direction = (coordinate.direction + 3) % 4;//逆時針轉 -1 break; case 'R': coordinate.direction = (coordinate.direction + 1) % 4;//順時針轉 +1 break; case 'F': coordinate.x += Coordinate.dDirection[coordinate.direction].x; coordinate.y += Coordinate.dDirection[coordinate.direction].y; if (outOfRange(space)) { outputF.AppendLine($"{coordinate.x} {coordinate.y} {getDirection(coordinate.direction)} Destroyed"); return; } break; } } outputF.AppendLine($"{coordinate.x} {coordinate.y} {getDirection(coordinate.direction)}"); } } class Program { static void Main(string[] args) { Drone drone = new Drone(); StringBuilder outputF = new StringBuilder(); drone.inputFile("inp2",ref outputF); ; } } }