【问题标题】:Game of Life in D Programming LanguageD 编程语言中的生命游戏
【发布时间】:2016-04-03 05:16:58
【问题描述】:

我正在尝试在 D 中实现生命游戏(这对我来说是新的)。它适用于大小为 100x100、200x200、300x300 的数组,但是当我达到 400x400 或更高时,可执行文件停止工作。我该如何解决?这是我的代码:

import std.stdio;
import std.random;
import std.conv:to;
import std.file;
import std.conv:to;
import core.simd;

alias  to!(string) toString;

immutable side = 400;
immutable generations = 1000;

alias  to!(string) toString;

void main ()
{

//Initialize Game of Life

float[side+2][side+2] big_grid;
float[side][side] cell_grid;

//Input random numbers in the big grid

for ( int i = 1; i < side+1; i++ )
    for ( int k = 1; k < side+1; k++ )
    {
    big_grid[i][k] = uniform(0,2);
    }

//Wrap the cells to sides (toroidal) in the big grid

for (int k = 1; k < side+1; k++ )
    {
    big_grid[side+1][k] = big_grid[1][k];
    big_grid[0][k] = big_grid[side][k];
    big_grid[k][side + 1] = big_grid[k][1];
    big_grid[k][0] = big_grid[k][side];
    }

big_grid[side+1][side+1] = big_grid[1][1];
big_grid[0][0] = big_grid[side][side];
big_grid[0][side+1] = big_grid[side][1];
big_grid[side+1][0] = big_grid[1][side];

//Transfer cell information from big grid to cell grid

for ( int i = 1; i < side+1; i++ )
    for ( int k = 1; k < side+1; k++ )
    {
    cell_grid[i-1][k-1] = big_grid[i][k];
    }

File file = File("gen0.txt", "w");
for ( int i = 0; i < side; i++ )
    {
        for ( int k = 0; k < side; k++ )
        {
        file.write(cell_grid[i][k],",");
        }
        file.write("\n");
    }
file.close();

//Update the state of the cells

for (int d = 1; d < generations; d++ )
    {

    //Rules of Life

    for ( int i = 0; i < side; i++ )
        for ( int k = 0; k < side; k++ )
        {
        if (big_grid[i+1][k+1] == 0 && (big_grid[i][k]+big_grid[i][k+1]+big_grid[i][k+2]+big_grid[i+1][k]+big_grid[i+1][k+1]+big_grid[i+1][k+2]+big_grid[i+2][k]+big_grid[i+2][k+1]+big_grid[i+2][k+2] == 3))
            {
            cell_grid[i][k] = 1;
            }
        else if (big_grid[i+1][k+1] == 1 && ((big_grid[i][k]+big_grid[i][k+1]+big_grid[i][k+2]+big_grid[i+1][k]+big_grid[i+1][k+1]+big_grid[i+1][k+2]+big_grid[i+2][k]+big_grid[i+2][k+1]+big_grid[i+2][k+2] == 3) || (big_grid[i][k]+big_grid[i][k+1]+big_grid[i][k+2]+big_grid[i+1][k]+big_grid[i+1][k+1]+big_grid[i+1][k+2]+big_grid[i+2][k]+big_grid[i+2][k+1]+big_grid[i+2][k+2] == 4)))
            {
            cell_grid[i][k] = 1;
            }
        else
            {
            cell_grid[i][k] = 0;
            }
        }

    //Update big grid for next iteration

    for ( int i = 1; i < side+1; i++ )
        for ( int k = 1; k < side+1; k++ )
        {
        big_grid[i][k] = cell_grid[i-1][k-1];
        }

    for (int k = 1; k < side+1; k++ )
        {
        big_grid[side+1][k] = big_grid[1][k];
        big_grid[0][k] = big_grid[side][k];
        big_grid[k][side + 1] = big_grid[k][1];
        big_grid[k][0] = big_grid[k][side];
        }

    big_grid[side+1][side+1] = big_grid[1][1];
    big_grid[0][0] = big_grid[side][side];
    big_grid[0][side+1] = big_grid[side][1];
    big_grid[side+1][0] = big_grid[1][side];

    file = File("gen"~toString(d)~".txt", "w");
    for ( int i = 0; i < side; i++ )
    {
        for ( int k = 0; k < side; k++ )
        {
        file.write(cell_grid[i][k],",");
        }
        file.write("\n");
    }
    file.close();
    }

}

【问题讨论】:

    标签: arrays d


    【解决方案1】:

    最可能的原因是使用 Windows 时的默认堆栈限制,并且至少有两种解决方法。

    1。增加堆栈限制。

    如果您在 Windows 上编译和运行程序,可执行文件通常有自己编译的最大堆栈大小,因此它更多的是特定于操作系统而不是特定于语言。

    现在,对于编译型编程语言,它们的链接器通常提供增加最大堆栈大小的选项。例如,如果您使用 dmd(官方 D 编译器)并编译为 32 位目标,则命令行将为 dmd -L/STACK:16777216 program.d 以将限制设置为 16 MB。 dmd 链接器的选项列表是here

    2。避免大量使用堆栈。

    另一种方法是注意您只需要堆栈用于本地普通旧数据变量。数组float[side+2][side+2] big_grid; 是一个静态 数组,这意味着它被分配在它被声明为(side+2) * (side+2) 连续4 字节floats 的地方。

    如果您改为使用 动态 数组 auto big_grid = new float [] [] (side + 2, side + 2);,这将仅在堆栈上分配 size_t * 2 个字节(8 或 16 个,取决于位数),其余的分配(一个一维动态浮点数组和size+2 一维浮点数组)将发生在垃圾收集堆上。你可以阅读更多关于不同类型的arrays in D,甚至更多关于使用dynamic arrays

    您也可以将数组声明为线程本地:只需将声明从函数范围移动到模块范围即可。如果您想要一个真正的全局变量,请将__gshared 添加到模块级声明:__gshared float[side+2][side+2] big_grid;。这样,您仍然可以使用静态数组而不在堆栈上进行分配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多