2014-11-01 17 views
8

Tôi có một số mã Game of Life đang hoạt động. Nó tiết kiệm mỗi dân số như là một bitmap. Đây là những gì đầu ra trông giống như (cắt):Lỗi khó hiểu trong chương trình Game Of Life

desired output

Khi làm sạch mã, tôi thấy rằng nếu tôi nhận xét ra hoặc loại bỏ dòng 60:

cout << "Survivor: " << x << ", " << y << "\n"; 

Nó hoàn toàn messes lên các chương trình , và thay vì sản xuất một chiếc tàu lượn như nó nên, nó tạo ra này:

faulty output

Tôi đã poked xung quanh, cố gắng tìm hiểu những gì có thể gây ra điều này, nhưng tôi đã được như vậy, đến nay không thành công. Đây là mã hiện tại của tôi:

//Bitmap Library from http://partow.net/programming/bitmap/ 
#include "bitmap_image.hpp" 
#include <iostream> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

using namespace std; 

#define WIDTH 160 
#define HEIGHT 128 

bool population[WIDTH][HEIGHT]; 
bool survivors[WIDTH][HEIGHT]; 

int check_survivors(); 
int check_neighbors(int x, int y); 
int write_population(char* file); 

int main() { 
    int i, populations; 

    cout << "Enter number of populations: "; 
    cin >> populations; 

    //Glider 
    survivors[28][100] = true; 
    survivors[29][100] = true; 
    survivors[29][101] = true; 
    survivors[30][101] = true; 
    survivors[28][102] = true; 

    //Initial image generation 
    write_population("population0.bmp"); 

    //populations 
    for (i = 0; i < populations; i++) { 
     char filename[17] = "population"; 
     char ii[3]; 
     sprintf(ii, "%d", i+1); 

     strcat(filename, ii); 
     strcat(filename, ".bmp"); 

     check_survivors(); 
     write_population(filename); 
    } 

    return 0; 
} 

int check_survivors() { 
    //set x and y variables 
    int x, y; 

    for (x = 0; x < WIDTH; x++) { 
     for (y = 0; y < HEIGHT; y++) { 
      if (check_neighbors(x, y)) { 
       survivors[x][y] = true; 
       cout << "Survivor: " << x << ", " << y << "\n"; 
      } else { 
       survivors[x][y] = false; 
      } 
     } 
    } 
    return 0; 
} 

int check_neighbors(int x, int y) { 
    int neighbors = 0, survives; 

    //I really need to rewrite this mess 

    //Neighbors above 
    if (population[x-1][y-1] == true && x != 0 && y != 0) { 
     neighbors++; 
    } 
    if (population[x][y-1] == true && y != 0) { 
     neighbors++; 
    } 
    if (population[x+1][y-1] == true && x != WIDTH-1 && y != 0) { 
     neighbors++; 
    } 

    //Neighbors next to 
    if (population[x-1][y] == true && x != 0) { 
     neighbors++; 
    } 
    if (population[x+1][y] == true && x != WIDTH-1) { 
     neighbors++; 
    } 

    //Neighbors below 
    if (population[x-1][y+1] == true && x != 0 && y != HEIGHT-1) { 
     neighbors++; 
    } 
    if (population[x][y+1] == true && y != HEIGHT-1) { 
     neighbors++; 
    } 
    if (population[x+1][y+1] == true && x != WIDTH-1 && y != HEIGHT-1) { 
     neighbors++; 
    } 

    //Determining life or death 
    if (neighbors < 2 || neighbors > 3) { 
     //Neighbors less than 2 or more than 3 is dead cell 
     survives = 0; 
    } else if (neighbors == 3 && population[x][y] == false) { 
     //Exactly 3 neighbors re-animates a cell 
     survives = 1; 
    } else if (population[x][y] == true) { 
     //2 or 3 neighbors is survivor 
     survives = 1; 
    } 

    return survives; 
} 

int write_population(char* file) { 
    //Create Image 
    bitmap_image image(WIDTH, HEIGHT); 

    //Set background to white 
    image_drawer draw(image); 
    image.set_all_channels(255,255,255); 

    //set x and y variables 
    int x, y; 

    //For every array point, check to see if it survives, 
    //and transfer survivors to population 
    for (x = 0; x < WIDTH; x++) { 
     for (y = 0; y < HEIGHT; y++) { 
      if (survivors[x][y] == true) { 
       draw.pen_width(1); 
       draw.pen_color(0,0,0); 
       draw.plot_pixel(x, y); 
      } 
      population[x][y] = survivors[x][y]; 
     } 
    } 

    //Save image 
    image.save_image(file); 

    //return 
    return 1; 
} 
+0

'sprintf (ii,"% d ", i + 1);' có thể gây tràn bộ đệm, cũng như các lệnh gọi 'strcat' sau đây. Viết lại mã này. –

Trả lời

6

Những điều như thế này:

if (population[x-1][y-1] == true && x != 0 && y != 0) 

cần phải được viết lại như sau:

if (x > 0 && y > 0 && population[x-1][y-1] == true) 

nếu không bạn sẽ thẳng vào không xác định lãnh thổ hành vi khi một trong hai x hoặc y0 (vì chúng sẽ nhiều lần khi bạn gọi check_neighbors() từ check_survivors()) và bạn có thể kỳ vọng, lỗi không thể giải thích như thế này. Bạn cần kiểm tra chỉ mục mảng không hợp lệ trước bạn cố truy cập các yếu tố đó.

Ngoài ra, ở đây:

if (neighbors < 2 || neighbors > 3) { 
    //Neighbors less than 2 or more than 3 is dead cell 
    survives = 0; 
} else if (neighbors == 3 && population[x][y] == false) { 
    //Exactly 3 neighbors re-animates a cell 
    survives = 1; 
} else if (population[x][y] == true) { 
    //2 or 3 neighbors is survivor 
    survives = 1; 
} 

nó trông như thể survives có thể bị bỏ lại với một giá trị không xác định nếu neighbors == 2population[x][y] == false, mà cũng có thể gây ra hành vi undefined nếu bạn đã truy cập giá trị đó. Nó không phải là ngay lập tức rõ ràng từ mã của bạn cho dù sự kết hợp của hoàn cảnh có thể là đúng, nhưng nếu bạn vẫn ở giai đoạn gỡ lỗi sau đó ở mức tối thiểu nó có giá trị thêm một điều kiện kiểm tra để xác minh có hay không.

Nếu chương trình của bạn đang trưng bày hành vi không xác định vì hành vi này là, thì có nhiều lý do không thể giải thích cho đến khi các vấn đề đó được khắc phục.

+0

@Quicksilver hãy nhớ đọc những gì [hành vi không xác định] (http://stackoverflow.com/a/4105123/211160) thực sự có nghĩa là, nếu bạn chưa biết. Đó là một thuật ngữ kỹ thuật và không nhất thiết phải quen thuộc với những người đến từ các ngôn ngữ khác. – HostileFork

+0

Nó cũng đáng giá thêm rằng IDE hiện đại, như VisualStudio làm cho nó dễ dàng hơn nhiều để tránh loại lỗi này. –

3

Bạn không luôn gán giá trị vào biến survives ví dụ: nếu population[x][y]falseneighbors là 2. Phần này để lại survives với giá trị của bất kỳ thứ gì trong bộ nhớ vào thời điểm đó. Khi bạn thêm cuộc gọi cout, có thể xảy ra để đặt bit bộ nhớ ngăn xếp đó thành 0, che giấu lỗi chương trình của bạn.

Thêm giá trị intial vào survives khi bạn khai báo.

Các vấn đề liên quan