Есть ли какой-либо способ выбора конкретных случаев, основанных на конкретных ситуациях? - PullRequest
0 голосов
/ 17 февраля 2019
 Direction := TDirection(Random(Succ(Ord(High(TDirection)))));
case Direction of
up:
  begin
    CurrentCell := maze[i, j - 1];
    CurrentCell.Wall := false;
  end;
down:
  begin
    CurrentCell := maze[i, j + 1];
    CurrentCell.Wall := false;
  end;
left:
  begin
    CurrentCell := maze[i - 1, j];
    CurrentCell.Wall := false;
  end;
right:
  begin
    CurrentCell := maze[i + 1, j];
    CurrentCell.Wall := false;
  end;

У меня в основном есть двумерный массив, называемый лабиринтом ([0..19, 0.19]), в котором из maze[0,0] выбирается случайное направление.Если указатель CurrentCell находится в любой из ячеек по краям maze, являющихся столбцом 0, строкой 0, строкой 19 и столбцом 19, существуют определенные направления, которые нельзя выбрать.У меня есть вопрос, могу ли я сообщить программе, какие направления рандомизировать, если указатель CurrentCell находится в какой-либо из строк и столбцов, перечисленных выше?

Направления создаются с помощью перечисления

TDirection = (up, down, left, right);
var
    Direction : TDirection;

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Добавьте каждое возможное направление в массив TDirection и выберите случайный элемент из массива.

Вот функция, в которой входами являются границы лабиринта и фактическая позиция:

Type
  TDirection = (up, down, left, right);
  TMazeRect = record lowX,lowY,highX,highY : integer; end;
const
  MyMazeRect : TMazeRect = (lowX:0;lowY:0;highX:19;highY:19);

function RandomRestrictedDirection( const area : TMazeRect; posX,posY : Integer) : TDirection;
var
  dirArray : array[0..3] of TDirection;
  count : Integer;
begin
  count := 0;
  if (posY < area.highY) then begin
    dirArray[count] := up;
    Inc(count);
  end;
  if (posY > area.lowY) then begin
    dirArray[count] := down;
    Inc(count);
  end;
  if (posX > area.lowX) then begin
    dirArray[count] := left;
    Inc(count);
  end;
  if (posX < area.highX) then begin
    dirArray[count] := right;
    Inc(count);
  end;
  Result := dirArray[Random(count)];
end;

Назовите это так:

NewDirection := RandomRestrictedDirection(MyMazeRect,i,j);
0 голосов
/ 18 февраля 2019

В зависимости от текущей координаты вы можете определить, какие направления доступны: накапливать доступные направления и затем выбирать случайные.Например:

var
  ..
  DirList: TList<TDirection>;
begin
  ..

  DirList := TList<TDirection>.Create;
  try
    if i > 0 then
      DirList.Add(mdUp);
    if i < 19 then
      DirList.Add(mdDown);
    if j > 0 then
      DirList.Add(mdRight);
    if j < 19 then
      DirList.Add(mdLeft);

    case DirList[Random(DirList.Count)] of
      mdUp:    CurrentCell := maze[i, j - 1];
      mdDown:  CurrentCell := maze[i, j + 1];
      mdLeft:  CurrentCell := maze[i - 1, j];
      mdRight: CurrentCell := maze[i + 1, j];
    end;
    CurrentCell.Wall := False;

    ...

Без общего списка это будет выглядеть так:

var
  ..
  DirList: TList;
begin
  ..

  DirList := TList.Create;
  try
    if i > 0 then
      DirList.Add(Pointer(mdUp));
    if i < 19 then
      DirList.Add(Pointer(mdDown));
    if j < 19 then
      DirList.Add(Pointer(mdLeft));
    if j > 0 then
      DirList.Add(Pointer(mdRight));

    Direction := TDirection(DirList[Random(DirList.Count)]);
    ...

Мне бы очень хотелось сделать это с набором, который лучше соответствовал бы контексту, но для этого потребовались бы случайные помощники.

Чтобы ответить на заглавный вопрос, необходимо прочитать исходное сообщение.Ответ - нет, после того, как case скомпилирован в двоичный файл, нет способа повлиять на существование отдельных веток во время выполнения.Вы также не можете воздействовать на значения ветвления, они должны быть константами, которые разрешаются во время компиляции.К счастью, это вообще не требуется, ведь вы решаете во время выполнения, какое значение будет иметь селектор и, следовательно, какая ветвь будет выбрана.

...