您可以使用Point
s到持有主板上的位置。 他们有属性X
和Y
坐标。 我会使用一个自定义的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
s为移动。
在这里,我也使用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。
为什么变量是'starting'和'exit'数组?我相信你希望他们代表点,所以让他们'tuple's。或者更好的是,让他们“点”来表达他们应该是什么。您可以使用'System.Drawing.Point'或自定义实现,因为它非常简单(如果您不需要其他任何东西,可能'X'和'Y'属性就足够了) –
因为起始和退出位置是动态。我不知道每次如何移动这个点。用Point做更好吗?你能解释一下吗?谢谢 – TibyDublin
你打算如何移动位置阵列时? –