在dinamic板运动

时间:2017-09-22 21:02:40

标签: c#

我必须创建一个具有给定长度x和y(“xBoardLenght”和“yBoardLenght”)的板。我将在元组“地雷”中定义几个地雷。我还有一对x和y用于开始游戏并完成(“开始”和“退出”。我将必须在另一个m列表中移动“运动”的“secuence”(向前移动1个位置)或r (向右旋转90度)从变量“initialDirection”的方向开始(可以是N,S,W,E)。我迷路了,因为我不知道如何在板上移动位置检查董事会中的方框是免费的还是有我的。如果到达出口,此代码必须返回成功,如果到达我的地方则返回失败,如果它仍然在董事会或超出限制,则不能完成。有人可以帮助我吗?谢谢很多。

        string[] secuence = new string[] { "m", "m", "m", "r", "m", "m" };
        int[,] starting = new int[0, 1];
        int[,] exit = new int[4, 2];

        string initialDirection = "N";

        int xBoardLenght = 4;
        int yBoardLenght = 5;

        Tuple<int, int>[] mines =
            {
            Tuple.Create(1, 1),
            Tuple.Create(3, 1),
            Tuple.Create(3, 3)
        };


        int[,] boardTurtle = new int[4, 5];

        //populating 2D Array
        for (int m = 1; m < xBoardLenght; m++)
        {
            for (int n = 1; n < yBoardLenght; n++)
            {
                boardTurtle[m, n] = 0;
            }
        }

        foreach (var item in mines)
        {
            boardTurtle[item.Item1, item.Item2] = 1;
        }

1 个答案:

答案 0 :(得分:0)

您可以使用Point来保留棋盘上的位置。 它们具有XY坐标的属性。 我使用自定义Point结构,可以直接添加它们:

public struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
    public Point(int x, int y) { X = x; Y = y; }

    public static Point operator +(Point left, Point right)
        => new Point(left.X + right.X, left.Y + right.Y);
}

现在,您可以使用Point来表示移动 在这里,我还使用enum来表示路线(该命令对以后的使用非常重要)

public enum Direction { North, East, South, West }

// On a board which is an array the Y axis points downwards,
// so e.g. North direction is (X: 0, Y: -1)
Dictionary<Direction, Point> moves = new Dictionary<Direction, Point>
{
    { Direction.North, new Point(0, -1) },
    { Direction.East,  new Point(1,  0) },
    { Direction.South, new Point(0,  1) },
    { Direction.West,  new Point(-1, 0) },
};

董事会是一个独立的实体,应该驻留在自己的类中 - 这是一个简单的实现,你可以添加其他功能

public class Board
{
    // Enumeration representing the outcome of a move on the board
    public enum MoveResult { Good, OutOfBounds, MineHit, Exit }

    // State of individual points on the board
    enum State { Empty, Mine, Exit }

    public Point CurrentPosition { get; private set; }
    public int Height { get; }
    public int Width { get; }
    State[,] board;

    public Board(int width, int height, Point initialPosition, Point exitPosition)
    {
        Width = width;
        Height = height;
        // Usually multidimensional arrays are represented in a way 
        // contrary to a normal (X,Y) coordinate system,
        // usually someArray[row(Y coordinate), column(X coordinate)], not the other way around.
        // This also makes printing the array simpler if you need it.
        board = new State[Height, Width];
        CurrentPosition = initialPosition;
        board[exitPosition.Y, exitPosition.X] = State.Exit;
    }

    public Board(int width, int height, Point initialPosition, Point exitPosition, IEnumerable<Point> minePositions)
        : this(width, height, initialPosition, exitPosition)
    {
        foreach(var pos in minePositions)
        {
            board[pos.Y, pos.X] = State.Mine;
        }
    }

    // Make a move on the board and return a value indicating if the move was successful
    public MoveResult Move(Direction direction)
    {
        // Get the move from the dictionary
        Point newPosition = CurrentPosition + moves[direction];

        if(newPosition.X < 0 || newPosition.Y < 0 || newPosition.X >= Width || newPosition.Y >= Height)
        {
            return MoveResult.OutOfBounds;
        }
        if(board[newPosition.Y, newPosition.X] == State.Mine)
        {
            return MoveResult.MineHit;
        }
        if(board[newPosition.Y, newPosition.X] == State.Exit)
        {
            return MoveResult.Exit;
        }

        CurrentPosition = newPosition;
        return MoveResult.Good;
    }

    static readonly Dictionary<Direction, Point> moves = new Dictionary<Direction, Point>
    {
        { Direction.North, new Point(0, -1) },
        { Direction.East,  new Point(1,  0) },
        { Direction.South, new Point(0,  1) },
        { Direction.West,  new Point(-1, 0) },
    };
}

然后您可以将此课程用于您需要的电路板:

// using a Queue here as it fits better
// var sequence = new Queue<string>(new[] { "m", "m", "m", "r", "m", "m" }); // loss in this scenario
// var sequence = new Queue<string>(new[] { "m", "r", "m", "m", "r", "m", "m", "r", "r", "r", "m"}); // win
// a quicker way is to use chars instead of strings
var sequence = new Queue<char>("mrmmrmmrrrm");

var start = new Point(0, 1);
var exit = new Point(3, 2);

var initialDirection = Direction.North;
var currentDirection = initialDirection;

int boardWidth = 4;
int boardHeight = 5;

var mines = new List<Point>
{
    new Point(1, 1),
    new Point(3, 1),
    new Point(3, 3),
};

var board = new Board(boardWidth, boardHeight, start, exit, mines);

while(sequence.Count > 0)
{
    var move = sequence.Dequeue();
    if(move == 'm')
    {
        switch(board.Move(currentDirection))
        {
        case Board.MoveResult.Good:
            // normal move - do nothing
            break;
        case Board.MoveResult.OutOfBounds:
            // moved beyond the board - loss
            return;
        case Board.MoveResult.MineHit:
            // moved on top of a mine - loss
            return;
        case Board.MoveResult.Exit:
            // if you require the moves to go exactly to the exit, not beyond,
            // check whether the queue is empty here:
            if(sequence.Count == 0)
            {
                // win
            }
            return;
        }
    }
    else if(move == 'r')
    {
        // Rotate the direction 90° clockwise by adding 1 modulo 4 as there are 4 directions.
        // This requires the Direction enum to have directions in the right order.
        currentDirection = (Direction)((int)(currentDirection + 1) % 4);
    }
}

查看所有这项工作here