-1

我想在處理3中編寫自己的「生命遊戲」版本,但是我遇到了一個我似乎並不明白的錯誤。每當代碼運行時,屏幕會隨着幾個像素的變化而持續黑白,但它看起來不像生活的遊戲。處理中的生命遊戲

任何幫助?

int windowW, windowH, percentAlive, gen; 
//windowW is the width of the window, windowH is the height 
//percentVlive is the initial percent of alive pixel 
//gen is the counter for the generation 
color alive, dead;//alive is white and dead is black to represent their respective colors 
boolean[][] cells0, cells1;//two arrays for the state of the cells, either alive or dead 
boolean zeroOrOne = true;//this is to check which array should be iterated over 

void setup() { 
    size(700, 700); 

    int width = 700; 
    int height = 700; 

    windowW = width; 
    windowH = height; 

    percentAlive = 15; 

    alive = color(255, 255, 255); 
    dead = color(0, 0, 0); 

    cells0 = new boolean[width][height]; 
    cells1 = new boolean[width][height]; 

    frameRate(2); 

    background(alive); 

    for (int x=0; x<width; x++) {//set the percent of live pixels according to the precentAlive varriable 
    for (int y=0; y<height; y++) { 
     int state = (int)random (100); 
     if (state > percentAlive) 
     cells0[x][y] = true; 
     else 
     cells0[x][y] = false; 
    } 
    } 
} 



void draw() { 
    gen += 1;//increases the generation every time it draws 
    drawLoop(zeroOrOne); 
    WriteGeneration(gen); 

    if(zeroOrOne){//changes the zeroOrOne value to change the array being iterated over 
    zeroOrOne = false; 
    } 
    else { 
    zeroOrOne = true; 
    } 
} 

void WriteGeneration(int number) {//changes the label on top 
    fill(0); 
    rect(0, 0, windowW, 100); 
    fill(255); 
    textFont(loadFont("BerlinSansFB-Reg-100.vlw")); 
    text("Generation " + number, 10, 90); 
} 

void drawLoop(boolean check) { 
    loadPixels(); 
    if (check) {//checks which array to iterate thrgough 

    for (int x = 0; x < windowW; x++) {//iterates through the array 
     for (int y = 0; y < windowH; y++) { 
     if (cells0[x][y]) {//checks wether the pixel is alive or dead 
      pixels[x * 700 + y] = alive;//gets the current pixel 
      int lives = lives(x, y, check);//checks how many cells are alive around the current cell 

      if (lives<2) {//these are supposed to put in place the game of life rules 
      cells1[x][y] = false; 
      } else if (lives>4) { 
      cells1[x][y] = false; 
      } else { 
      cells1[x][y] = true; 
      } 
     } else { 
      pixels[x * 700 + y] = dead;//gets the current pixel 
      int lives = lives(x, y, check);//checks how many cells are alive around the current cell 
      if (lives == 3) {//turns the pixel alive if the condition is met 
      cells1[x][y] = true; 
      } 
     } 
     } 
    } 
    } else {//the same as the top but instead the arrays being updated and read are switched 

    for (int x = 0; x < windowW; x++) { 
     for (int y = 0; y < windowH; y++) { 
     if (cells1[x][y]) { 
      pixels[x * 700 + y] = alive; 
      int lives = lives(x, y, check); 
      if (lives<2) { 
      cells0[x][y] = false; 
      } else if (lives>4) { 
      cells0[x][y] = false; 
      } else { 
      cells0[x][y] = true; 
      } 
     } else { 
      pixels[x * 700 + y] = dead; 
      int lives = lives(x, y, check); 
      if (lives == 3) { 
      cells0[x][y] = true; 
      } 
     } 
     } 
    } 
    } 
    updatePixels(); 
} 

int lives(int x, int y, boolean check) {//this just checks how many live pixels are around a given pixel 
    int lives = 0; 
    if (x > 1 && y >1 && x < 699 && y < 699) { 
    if (check) { 
     if (cells0[x-1][y-1]) 
     lives++; 
     if (cells0[x][y-1]) 
     lives++; 
     if (cells0[x+1][y-1]) 
     lives++; 
     if (cells0[x-1][y]) 
     lives++; 
     if (cells0[x+1][y]) 
     lives++; 
     if (cells0[x-1][y+1]) 
     lives++; 
     if (cells0[x][y+1]) 
     lives++; 
     if (cells0[x+1][y+1]) 
     lives++; 
    } else { 
     if (cells1[x-1][y-1]) 
     lives++; 
     if (cells1[x][y-1]) 
     lives++; 
     if (cells1[x+1][y-1]) 
     lives++; 
     if (cells1[x-1][y]) 
     lives++; 
     if (cells1[x+1][y]) 
     lives++; 
     if (cells1[x-1][y+1]) 
     lives++; 
     if (cells1[x][y+1]) 
     lives++; 
     if (cells1[x+1][y+1]) 
     lives++; 
    } 
    } 
    return lives; 
} 
+0

「它看起來不像生活的遊戲」幾乎不是一個問題的描述。你嘗試過調試嗎?或讓它運行速度更慢? – f1sh

+0

'zeroOrOne'和'cells0' /'cell1'東西是我看的地方。你有兩個不同的遊戲在同一時間運行嗎?那肯定會解釋屏幕似乎在兩種不同的事情之間交替......在你一次嘗試兩次之前讓它跑步。 –

+0

我試圖慢運行它,我可以給出的最好的描述是,屏幕在一次迭代中變黑,然後用另一個看起來像人生遊戲的版本返回到白色。它每次都這樣做 –

回答

2

請發表您的代碼作爲MCVE。當我嘗試運行你的代碼時,我得到一個錯誤,因爲我沒有你想要在第59行加載的字體文件。該字體與你的問題沒有關係,所以你應該真正擺脫它張貼問題。

你在這段代碼中有很多事情要做。我明白爲什麼你有兩個數組,但是在草圖層次上讓它們只是讓你的代碼過於複雜。你不應該不斷地在這樣的數組之間切換。相反,我會像這樣組織代碼:

  • 您應該只在草圖級別有一個數組。您也可以擺脫zeroOrOne變量。
  • 然而,你想要初始化該數組。
  • 創建一個基於當前數組返回新數組的nextGeneration()。這可能會調用其他函數來計算鄰居和什麼。但重點是你可以每次創建一個新的數組,而不是在兩個全局數組之間切換。
  • 這將刪除所有重複的邏輯。

一般注意事項:

  • 有8個if語句來檢查鄰居是有點矯枉過正。爲什麼不使用嵌套for循環?
  • 你應該養成遵循適當命名約定的習慣。函數應該以小寫字母開頭,變量應該是描述性的 - 命名check並不真正告訴讀者什麼。

如果你仍然無法正常工作,那麼你將不得不做一些調試。添加print()語句,或者使用Processing編輯器的調試器遍歷代碼。哪條線的行爲與您期望的不同?然後你可以發佈一條MCVE(僅僅是那行代碼),然後我們將從那裏開始。祝你好運。

+0

感謝您的建議。 –

0

您遇到的問題是雙重的:

  1. 兩個單元陣列,你已經干擾,使兩個獨立的遊戲,當你只想要一個。

  2. 在檢查哪些需要修改之前,您正在更新數組中的單元格。

同時解決這兩個問題的方法是重新調整cells1數組的用途。而不是每隔一次檢查一次,將其設置爲完全錯誤的數組。然後,無論何時要修改單元格0中的正方形,將單元格1中的該位置設置爲true,並在爲要更改的每個單元格創建標記後,在drawLoop()的末尾使用單獨的for循環一次全部更改它們方法。這一舉解決了這兩個問題。

完成此操作後,您可以刪除checkzeroAndOne變量,因爲您不再需要它們。這是我得到的drawLoop()方法之後我所做的修改,我建議:

void drawLoop() { 
    loadPixels(); 
    for (int x = 0; x < windowW; x++) { 
    for (int y = 0; y < windowH; y++) { 
     if (cells0[x][y]) { 
     pixels[x * 700 + y] = alive; 
     int lives = lives(x, y); 
     if (lives<2) { 
      cells1[x][y] = true; 
     } else if (lives>4) { 
      cells1[x][y] = true; 
     } 
     } else { 
     pixels[x * 700 + y] = dead; 
     int lives = lives(x, y); 
     if (lives == 3) { 
      cells1[x][y] = true; 
     } 
     } 
    } 
    } 
    for (int x = 0; x < windowW; x++) { 
    for (int y = 0; y < windowH; y++) { 
     if (cells1[x][y]) { 
     cells0[x][y] = !cells0[x][y]; 
     cells1[x][y] = false; 
     } 
    } 
    } 
    updatePixels(); 
} 

我敢肯定,你可以計算出其餘部分。祝你好運!