MARS ROVERS问题

一小队机器人探测器将由NASA送上火星高原,探测器将在这个奇特的矩形高原上行驶。用它们携带的照相机将周围的全景地势图发回到地球。每个探测器的方向和位置将由一个x,y系坐标图和一个表示地理方向的字母表示出来。为了方便导航,平原将被划分为网格状。位置坐标示例:0,0,N,表示探测器在坐标图的左下角,且面朝北方。为控制探测器,NASA会传送一串简单的字母。可能传送的字母为: ‘L ‘, ‘R ‘和 ‘M ‘。 ‘L ‘,和 ‘R ‘分别表示使探测器向左、向右旋转90度,但不离开他所在地点。 ‘M ‘ 表示向前开进一个网格的距离,且保持方向不变。假设以广场(高原)的直北方向为y轴的指向。

输入:首先输入的line是坐标图的右上方,假定左下方顶点的坐标为0,0。剩下的要输入的是被分布好的探测器的信息。每个探测器需要输入wo lines。第一条line 提供探测器的位置,第二条是关于这个探测器怎样进行高原探测的一系列说明。位置是由两个整数和一个区分方向的字母组成,对应了探测器的(x,y)坐标和方向。每个探测器的移动将按序完成,即后一个探测器不能在前一个探测器完成移动之前开始移动。

输出:每个探测器的输出应该为它行进到的最终位置坐标和方向。输入和输出 测试如下:

地图边界:5 5

当前位置:1 2 N

移动指令:LMLMLMLMM

当前位置:3 3 E

移动指令:MMRMMRMRRM

期待的输出

1 3 N

5 1 E

思路: 1、该问题传达我们这样几个关键实例:“一队探测器”、“矩形高原”、“xy系坐标”、“当前位置”、“方向”、“左|右”。 2、当前位置代表这对探测器在矩形高原的位置。而这个位置信息除了包含x、y坐标值以外还包含一个朝向,而指令是通过[左转|右转]控制。但结果输出需要的是方向。 3、我们需要的”类”,究竟是什么? No1、方向 我们需要一个方向的枚举,用以代表四个方向。 ``\` public enum TowardEnum { N, S, W, E }

 这里我们必须停一下,指令是通过"L"/"R"传达的,也就是左转右转可以代表任意方向。这里我们需要一个转换一下思路。 先来观察一下这个图例 N->W->S->E的指令为LLL N->E-->S->E的指令为RRR [![](http://www.abelzhou.com/wp-content/uploads/2012/02/20120227130906.jpg "20120227130906")](http://www.abelzhou.com/wp-content/uploads/2012/02/20120227130906.jpg) 可以理解为L:逆时针 R:顺时针 一个L或者R标识一个90°旋转。那么我们可以认为以90°为一个标量。没执行一个L/R则自增或者自减了1。那么这个枚举就会变成这个样子。 public enum TowardEnum {   N=0,   W=1,   S=2,   E=3 }

 这段代码就有点意思了,假设当前朝向为N,L和R分别代表的方位为 L--> (TowardEnum.N+1)%4 -->TowardEnum.W R--> (TowardEnum.N+3)%4 -->TowardEnum.E No2、地图边界。 车辆是不能够超出(0~n,0~n)这个范围的,所以需要有个地图坐标范围。 public class Map {   int x;   int y; }

 No3、当前位置 小车当前的位置信息。 public class Position {   int x,   int y,   TowardEnum towardEnum; }

 No4、控制类。 根据当前位置,以及朝向(这个在上面已经大概说明了),区分到底是该操作x还是操作y。由于是单指令控制一次移动、每次移动一个单位。故可以用自增或者自减判断。 No5、处理类 既处理传入的参数以及最终获得完成指令的车辆位置出口。 完整代码 namespace MarsExploration {
class Program
{
    static void Main(string[] args)
    {
        Console.Write("请输入右上角边界值x(5 5 ):");
        String mapStr = Console.ReadLine();
        Console.WriteLine();
        Console.Write("请输入当前车辆的位置(1 2 N):");
        String positionStr = Console.ReadLine();
        Console.WriteLine();
        Console.Write("请输入指令(LMLMLMLMM):");
        String insStr = Console.ReadLine();
        Console.WriteLine();

        //暂未处理异常信息
        string[] strChar = mapStr.Split(' ');
        int xMax = Int32.Parse(strChar[0]);
        int yMax = Int32.Parse(strChar[1]);
        strChar = positionStr.Split(' ');
        int x = Int32.Parse(strChar[0]);
        int y = Int32.Parse(strChar[1]);
        string toward = strChar[2];

        //构造地图信息
        Map map = new Map(xMax, yMax);
        Position position = new Position();
        position.X = x;
        position.Y = y;
        position.TowardEnum = (TowardEnum)Enum.Parse(typeof(TowardEnum), toward);

        try
        {
            Progress progress = new Progress(insStr, map, position);
            Position resultPosition = progress.GetPosition();
            Console.WriteLine(resultPosition.X + " " + resultPosition.Y + " " + resultPosition.TowardEnum.ToString());
        }
        catch (Exception e)
        {

            Console.WriteLine(e.Message);
        }

        Console.ReadKey();
    }
}

//处理类
public class Progress
{
    //指令集
    private char[] instructions;
    //位置信息
    private Position position;
    //地图边界
    private Map map;
    //车辆控制中心
    private CarContorller contorller;

    ///
/// 初始化处理方法 ///
    ///指令
    ///地图
    ///当前位置
    public Progress(string instruction, Map map, Position position)
    {
        this.instructions = instruction.ToCharArray();
        this.position = position;
        this.map = map;
    }

    ///
/// 得到执行完毕后车辆的位置 ///
    ///
    public Position GetPosition()
    {
        this.contorller = new CarContorller(this.position, this.map);
        Position resultPosition = new Position();
        foreach (var item in instructions)
        {
            resultPosition = contorller.ExecInstruction(item);
        }
        return resultPosition;
    }
}

//控制类
public class CarContorller
{
    private Position position;
    private Map map;

    public CarContorller(Position position, Map map)
    {
        this.position = position;
        this.map = map;
    }

    ///
/// 执行指令 ///
    /// 当前位置
    public Position ExecInstruction(char instruction)
    {
        switch (instruction)
        {
            case 'L':
                this.position.TowardEnum = (TowardEnum)((int)(this.position.TowardEnum + 1) % 4);
                break;
            case 'R':
                this.position.TowardEnum = (TowardEnum)((int)(this.position.TowardEnum + 3) % 4);
                break;
            case 'M':
                this.Move();
                break;
            default:
                throw new Exception("无法识别的指令" + instruction);
        }
        return this.position;
    }

    ///
/// 移动车辆 ///
    private void Move()
    {
        switch (this.position.TowardEnum)
        {
            case TowardEnum.N:
                this.position.Y++;
                break;
            case TowardEnum.W:
                this.position.X--;
                break;
            case TowardEnum.S:
                this.position.Y--;
                break;
            case TowardEnum.E:
                this.position.X++;
                break;
            default:
                break;
        }
        if (this.position.X < 0 || this.position.X > map.XMax || this.position.Y < 0 || this.position.Y > map.YMax)
        {
            throw new Exception("数据错误,该车辆将走出地图边界!");
        }
    }
}

//地图边界
public class Map
{
    //初始化右上角X坐标
    private int xMax;
    //初始化右上角Y坐标
    private int yMax;

    public int XMax
    {
        get { return xMax; }
        set { xMax = value; }
    }
    public int YMax
    {
        get { return yMax; }
        set { yMax = value; }
    }

    public Map(int xInit, int yInit)
    {
        this.xMax = xInit;
        this.yMax = yInit;
    }
}

//位置
public class Position
{
    private int x;

    public int X
    {
        get { return x; }
        set { x = value; }
    }
    private int y;

    public int Y
    {
        get { return y; }
        set { y = value; }
    }

    private TowardEnum towardEnum;
    public TowardEnum TowardEnum
    {
        get { return towardEnum; }
        set { towardEnum = value; }
    }
}

//朝向
public enum TowardEnum
{
    N = 0,
    W = 1,
    S = 2,
    E = 3
} } \`\`\\\`

测试结果为: