/// 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); ;
}
}
}