2011-09-18 70 views
2

我正在進行一維生命遊戲(基於此處在Mathworld處列出的規則)。實質上,每一代都被表示爲一行0或1(死或活),並且下一代是基於「規則」命令行參數的二進制表示形式創建的。從二維C數組中獲取前一行「值」的值

例如,規則30變爲00011110(二進制爲30),這用於確定哪些位模式會在隨後的代中產生新的單元或死掉。

爲了對此進行編程,我需要能夠從上一行訪問三個組中的位(用於應用規則)。下面是樣本圖像(注意,開始行總是爲0的與中央1):

00000100000 #seed row 
11001011001 #generated from seed row 
........... 
11110010101 #n-th row, generated from n-1 row 

爲了產生一排,我必須着眼於從該行中,比特以上三個,然後組將規則應用爲1/0,生/死決定。

基本上我打算匹配3位模式和規則,並使用它打印後代的0或1。這是一般算法:

if three_bit_pattern == 'xxx' && rule[x] == 0/1 {print 0/1} else {print 1/0} 

我遇到困難的程序部分是訪問前一行的內容。我所有的嘗試都會產生垃圾或錯誤的數據

總之,我將如何訪問三位組的前一行的值?

該行創建這樣的:

int i, j, k; 
int row = atoi(argv[1]) + 1; 
int col = 2 * atoi(argv[1]) + 1; 

int arr[col]; 
int output[col]; 

char rule[9]; //binary representation of rule (2^8 stores up to 255 + null term) 
int2binary(atoi(argv[2]), &rule, 10); 

for(i = 0; i < row; i++){ 
    for(j = 0; j < col; j++){ 
    if(i == 0){ 
     if(j == col/2) //print 1 in center of first row 
     arr[i] = 1;  
     else 
     arr[i] = 0; 
     printf("%d", arr[i]); 
    } 
    else{ 
     //output[i] = arr[i-1]; 
     output[i+1] = arr[i]; 
     output[i+2] = arr[i+1]; 
     output[i+3] = arr[i+2]; 
     printf("%s", output); 
    } 
    }//end inner for_loop 
    printf("\n"); 
}//end outer for_loop 

}

好了,所以我做了這個一大堆簡單,我只是將不得不兩個數組(一個保持前柱和一個與當前)。我不明白的是爲什麼打印輸出數組產生垃圾?是輸出[我] = arr [我]不是一個有效的表達式?

+0

您不顯示不起作用的代碼。完全不可能明白爲什麼一段看不見的代碼不起作用。顯示所有的代碼。 –

+0

那麼,它的行索引叫做「行」還是「我」?對於第一行,我可能會使用0;等待引入一個變量,直到值需要變化。 –

+0

的確如此。現在我沒有任何代碼(我一直在進行非工作嘗試),但我會編輯帖子以反映一些嘗試。 –

回答

2

您尚未指定可能影響要使用的數據結構的輸入或輸出。例如,如果在計算它們時將其打印出來,則可能只需保留兩行或甚至只保留一行。它看起來像你打算保留一個數組中的所有行。

它看起來像你的初始行中的邏輯錯誤:

if(firstTime == 1){ 
     if(j == row-1) //print 1 in center of first row 
      arr[i][j] = 1;  
     else 
      arr[i][j] = 0; 
    } 

大概應該是

if(i == 0){ 
     if(j == col/2) //print 1 in center of first row 
      arr[i][j] = 1;  
     else 
      arr[i][j] = 0; 
    } 

什麼的更簡單。

生成其他行的算法並不複雜。

1)使用上述行的元素從0到7建立一個數字。

2)按位 <(1)以規則號的獲得結果

parent = 0; 
if(j>0 && arr[i-1][j-1]) parent = 4; 
if(arr[i-1][j]) parent += 2; 
if(j<col-1 && arr[i-1][j+1]) parent += 1; 

position = 1 << parent; 
arr[i][j] = (rule & position)?1:0; 

有一些明顯的方式,使這個速度更快。例如。,根據上一列的父級和右上角的單元格爲此列構建父級:& with 3,shift left,|與細胞內容。唯一難看的部分是分別處理第一列和最後一列。

編輯迴應評論:

該算法與位操作整數一些自然實現,這哪裏是「規則XX」的想法從何而來。

在它的核心,當前空間的選擇取決於它上面的三個空間。這些有8種可能性。我們可以將它們視爲對應於一個字節的8位。

每個規則是從8個可能性集合到集合{0,1}的一個對應關係。有2^8 = 256個可能的對應關係或規則,它們恰好與一個字節的可能值的數量相同。

標籤規則的最方便的方法是用一個數字來顯示當前單元格是如何由父單元格確定填充的。例如,

規則30:

30 = 16 + 8 + 4 + 2 = 2^4 + 2^3 + 2^2 + 2^1

所以規則是填充當父單元格是:

4 = 100 
3 = 011 
2 = 010 
1 = 001 

又例如,什麼是隻複製前一行的規則?

在這種情況下,我們在單元格的填充,如果上面的電池充滿,但臨近單元可以是任何東西:

010 = 2 
011 = 3 
110 = 6 
111 = 7 

因此,這是規則2^2 + 2^3 + 2^6 + 2^7 =規則4 + 8 + 64 + 128 =規則204.

我希望現在確定單元格的算法更有意義。

1)確定家長模式的數量。

2)確定2 ^圖案是否是規則的一部分。如果是這樣,請填寫單元格。

我的其他評論是你需要存儲多少。如果按照輸出方式輸出,則只需要數組的一行(即只有一個維度)。在遍歷行時,可以用下一行的值替換條目。唯一的困難是你需要保持你正在替換的當前值來確定下一個單元格。

但是你可以保留這個值,並用相同的技巧減少計算量:保留最後的父代號; &用3去除左邊的父親;將它左移1; |它與父母的權利。這給你當前的父母號碼。小心處理數組的最終條目,然後就完成了。

ANOTHER編輯:

首先實現以前的版本,但如果你真的想瘋了的節省空間,更扭曲你的頭腦,儘量保存該行作爲一個整數位值,而不是一個數組1s和0s。如果你想要一行甚至比長整數的位數還要長,那麼你需要一個整數數組來保存這些位,以及一些瘋狂的位操作來處理兩個整數的邊界上的單元格。玩的開心!

+0

你對這兩個小修正是正確的。兩者都和我的代碼一樣,但更正確。 你能解釋一下父變量持有什麼嗎?它跟蹤什麼? –

+0

看來你算法的第一部分就是我卡住的地方。我無法從上面的行中獲取值。我會認爲像next_gen [x] = prev_gen [x]這樣簡單的東西,但這似乎並不正確。 –

+0

@理查德我做了一個編輯來回答你的問題。 – UncleO