2015-06-18 3 views
1

Я смотрел на это некоторое время и переписал код три раза до сих пор, это то, что у меня есть и чего я не понимаю.Игра жизни, C проверка жизненных условий

У меня есть метод, который проверяет окрестности, через различные линии печати и мой пробег через нее, это работает.

int getLiveCellCount(Generation *currentGeneration, int i, int j) 
{ 
int liveCellCount = 0; 
// check top row 
if(i > 0) 
{ 
    if(j > 0 && currentGeneration->generation[i-1][j-1] == 'X') 
    { 
     liveCellCount++; 
    } 
    if(currentGeneration->generation[i-1][j] == 'X') 
    { 
     liveCellCount++; 
    } 
    if(j < currentCols && currentGeneration->generation[i-1][j+1] == 'X') 
    { 
     liveCellCount++; 
    } 

} 

// check mid row 
if(j > 0 && currentGeneration->generation[i][j-1] == 'X') 
{ 
    liveCellCount++; 
} 
if(j < currentCols && currentGeneration->generation[i][j+1] == 'X') 
{ 
    liveCellCount++; 
} 

// check bottom row 
if(i < currentRows) 
{ 
    if(j > 0 && universe[i+1][j-1] == 'X') 
    { 
     liveCellCount++; 
    } 
    if(currentGeneration->generation[i+1][j] == 'X') 
    { 
     liveCellCount++; 
    } 
    if(j < currentCols && currentGeneration->generation[i+1][j+1] == 'X') 
    { 
     liveCellCount++; 
    } 
} 

return liveCellCount; 
} 

У меня есть конкретные условия, в которых клетка живет или умирает, живые клетки содержат X и мертвые клетки являются пробелом.

If the cell is alive: 
    it dies if it has 0, 1, 4 or more living neighbours (starvation), or 
    it lives if it has 2 or 3 living neighbours (balance). 
If the cell is dead: 
    it springs to life if it has exactly 3 neighbours (procreation). 

я реализую код следующим образом:

for(i=0; i<currentRows; i++) 
     { 
      for(j=0; j<currentCols; j++) 
      { 
       int livingCells = 0; 
       livingCells = getLiveCellCount(currentGeneration, i,j); 
       if(universe[i][j] == 'X') 
       { 
        if(livingCells == 2 || livingCells == 3) 
        { 
         universe[i][j] = 'X'; 
        } 
        else 
        { 
         universe[i][j] = ' '; 
        } 
       } 
       else 
       { 
        if(livingCells == 3) 
        { 
         universe[i][j] = 'X'; 
        } 
       } 
      } 
     } 

Знайте, что universe[][] переменная сферу файла, моя идея с этим кодом считывается в исходном состоянии в universe, это работает. Я копирую этот массив в массив структур (хранилище для последующего и в настоящее время закомментировано). Я сканирую universe и проверяю каждую ячейку для живых клеток в ее окрестности, основываясь на этом, следуя приведенным выше правилам и редактируя universe на основе элементов по элементам. Что мне не хватает в этом? Где-то состояние не читается правильно, и я не вижу его.

Я хочу поблагодарить всех вас за помощь, которую вы мне дали! Как многие из вас упоминали, я уже рассмотрел небольшую деталь, что каждая ячейка во Вселенной должна обновляться одновременно! Как я уже упоминал, я копирую текущее состояние вселенной в массив 2d в структуре и сохраняю его в массиве для последующего использования, используя текущий снимок юниверса для подсчета количества клеток, а затем редактирование юниверса отлично работает! Спасибо огромное!

+1

Вы должны включить небольшой пример, демонстрирующий проблему, которую вы видите. Вы должны учитывать, что способ сканирования таблицы влияет на состояние вашей игры. Вы одновременно убиваете и оживляете ячейки, поэтому клетка может умереть в позиции x, y, и это повлияет на то, будет ли или нет x + 1, j + 1 жить или умирать, потому что к тому времени, как вы попадете в эту вторую ячейку, вы уже обновил x, y. Это своего рода эффект каскада с одним поворотом. Возможно, это то, чего вы хотите. –

+1

В 'getLiveCellCount' вы не защищаетесь от перехвата верхней границы. – ooga

+0

'getLiveCellCount' только когда-либо вызывается изнутри моих циклов, они должны покрывать верхние границы справа? –

ответ

4

Я думаю, что у вас есть две проблемы с кодом:

  1. Как @ogga сказал в комментариях вы не проверяла верхних границ в getlivecellcounts. Вы проверили нижние границы, когда вы проверяете i и j больше, чем 0, но вам также нужно сделать это для верхней границы (просто убедитесь, что она не больше, чем размер массива, чтобы проверить, не мертв или жив ли ячмень).

  2. В вашей петле цикла я думаю, что вы рассчитываете подсчет живых клеток на лету. Проблема с этим подходом заключается в том, что вы находитесь на какой-либо ячейке [x] [y], и она живая, и у нее есть некоторое число соседей z, и вы меняете ее на мертвую ячейку, а затем переходите к следующей ячейке. Это даст вам неправильное количество соседей в ячейке [x] [y + 1], потому что вы изменили статус ячейки x y уже на новое поколение, которое сейчас уже мертво и было живым раньше.

* Смена ячейки должна производиться в том же поколении.

Другим способом может быть создание другого 2-мерного массива и сохранение новой версии или нового поколения, а затем копирование в предыдущее после его завершения. Таким образом, вы будете изменять все поколения сразу.

+0

Если я правильно понимаю, я могу сделать второй 2d-массив для хранения текущего состояния юниверса, сканирования этого массива и на основе соседей сотовых, обновить ячейки во Вселенной. Затем повторите. –

+0

да, что имеет смысл. – shunya

+0

Спасибо, прочитав сообщение, я вернулся к странице правил игры и увидел это: «Первое поколение создается путем применения вышеуказанных правил одновременно к каждой ячейке в семени», эта новая идея с двумя массивами должна работать так как он удовлетворяет этому условию. –

0

в общем,

1) проверка состояния соседних ячеек всегда должны проверить, что клетка проверяется находится в пределах 2D-массива.

2) тот же массив не может использоваться для обновления содержимого ячейки-мишени, поскольку это может изменить подсчет соседей, если некоторая соседняя ячейка становится целевой ячейкой.Путь вокруг этого состоит в том, чтобы сохранить два 2D-массива и использовать указатель для перехода на последнюю версию после того, как все обновления были применены.

+0

Итак, это означает, что я могу скопировать юниверс в массив temp 2d, отсканировать массив temp и на основе обновления ячеек обновить первоначальную вселенную? –

Смежные вопросы