2016-12-13 4 views
-1

Я создаю игру командной строки, которая включает в себя массив 10 х 10 char, представлен следующим образом:Как я могу найти последовательно «занятые» элементы в массиве C++?

0 1 2 3 4 5 6 7 8 9 
0 . . . . . . . . . . 
1 . . . . . . . . . . 
2 . . . . . . . . . . 
3 . . . . . . . b . . 
4 . . A B C . 1 2 3 . 
5 . . . . . . . . . . 
6 . . . . . . . . . . 
7 . . . . . C c 3 . . 
8 . . . . . . . . . . 
9 . . . . . . . . . . 

Каждый . представляет незанятую точку на доске, а буквы и цифры являются частями, которые уже были играл. Цифры на верхнем краю и левом краю предназначены только для справки.

Чтобы вычислить точки и убедиться, что части воспроизводятся в правильных местах, я хотел бы создать «подматрицу» последовательных частей, смежных с частью, которая только что была воспроизведена. В приведенном выше примере, если только B был воспроизведен, тогда массив char будет содержать A, B и C.

Мне сложно найти «стартовые» (левые) и «завершающие» (правые) части этого последовательного подматрица. Как только у меня есть это, это легко решить. Очевидно, я мог бы начать с одного конца доски и просто добавить к массиву любую фигуру, которая не ., но тогда я бы закончил все части этой строки, а не только те, которые смежны с частью, которая только что была сыграна ,

Я попытался следующие, но он по-прежнему печатает неправильный вывод (выключение одной с обеих сторон):

void Board::createHorizontalRun(int row, int column) { 
    int i = column; 
    int j = column; 

    while (array[row][i] != '.' && i >= 0 && i <= 9) { 
     i--; 
    } 
    while (array[row][j] != '.' && j >= 0 && j <= 9) { 
     j++; 
    } 
    cout << "run begins at " << i << endl; 
    cout << "run ends at " << j << endl; 
} 

Как я могу найти начальную и конечную точки из последовательных частей, прилегающих к часть, которая только что была сыграна?

+1

Похоже, что вы ищете заливка: https://en.wikipedia.org/wiki/Flood_fill. То есть, если вы не ищете только горизонтальную или вертикальную работу одной ячейки сетки, в этом случае проблема проще. – NPE

+7

Выньте лист бумаги и ручку. Запишите, используя простой английский, короче говоря, логические предложения, поэтапный процесс реализации вашего алгоритма. [Обсудив предложенную вами логику с вашей резиновой утиной] (https://en.wikipedia.org/wiki/Rubber_duck_debugging), как только ваша резиновая утка соглашается, что ваша логика правильная, просто возьмите то, что вы написали, и прямо перевести его в код. Миссия выполнена. –

+2

Обратите внимание, как ваш код успешно идентифицирует «первый». рядом с вашим пробегом "в обоих направлениях, и что вы знаете, что начальная позиция никогда не является". " – Caleth

ответ

0

Вот что я придумал после того, как по совету Сэма:

vector<char> Board::getHorizontalRun(int row, int column) { 
    int runStart = column; 
    int runEnd = column; 
    vector<char> horizontalRun; 

    // find starting position of run 
    while (true) { 
     if (isInBounds(row, runStart - 1)) { 
      if (array[row][runStart - 1] == '.') { 
       break; 
      } else { 
       runStart--; 
      } 
     } else { 
      break; 
     } 
    } 

    // find ending position of array 
    while (true) { 
     if (isInBounds(row, runEnd + 1)) { 
      if (array[row][runEnd + 1] == '.') { 
       break; 
      } else { 
       runEnd++; 
      } 
     } else { 
      break; 
     } 
    } 

    // Use start and end positions to populate vector 
    for (int i = runStart; i <= runEnd; i++) { 
     horizontalRun.push_back(array[row][i]); 
    } 

    return horizontalRun; 
} 
Смежные вопросы